summaryrefslogtreecommitdiff
path: root/fs/timerfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/timerfd.c')
-rw-r--r--fs/timerfd.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c
index 1327a02ec778..0548c572839c 100644
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -50,7 +50,8 @@ static DEFINE_SPINLOCK(cancel_lock);
static inline bool isalarm(struct timerfd_ctx *ctx)
{
return ctx->clockid == CLOCK_REALTIME_ALARM ||
- ctx->clockid == CLOCK_BOOTTIME_ALARM;
+ ctx->clockid == CLOCK_BOOTTIME_ALARM ||
+ ctx->clockid == CLOCK_POWEROFF_ALARM;
}
/*
@@ -142,7 +143,8 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
{
spin_lock(&ctx->cancel_lock);
if ((ctx->clockid == CLOCK_REALTIME ||
- ctx->clockid == CLOCK_REALTIME_ALARM) &&
+ ctx->clockid == CLOCK_REALTIME_ALARM ||
+ ctx->clockid == CLOCK_POWEROFF_ALARM) &&
(flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) {
if (!ctx->might_cancel) {
ctx->might_cancel = true;
@@ -174,6 +176,7 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
enum hrtimer_mode htmode;
ktime_t texp;
int clockid = ctx->clockid;
+ enum alarmtimer_type type;
htmode = (flags & TFD_TIMER_ABSTIME) ?
HRTIMER_MODE_ABS: HRTIMER_MODE_REL;
@@ -184,10 +187,8 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags,
ctx->tintv = timespec_to_ktime(ktmr->it_interval);
if (isalarm(ctx)) {
- alarm_init(&ctx->t.alarm,
- ctx->clockid == CLOCK_REALTIME_ALARM ?
- ALARM_REALTIME : ALARM_BOOTTIME,
- timerfd_alarmproc);
+ type = clock2alarm(ctx->clockid);
+ alarm_init(&ctx->t.alarm, type, timerfd_alarmproc);
} else {
hrtimer_init(&ctx->t.tmr, clockid, htmode);
hrtimer_set_expires(&ctx->t.tmr, texp);
@@ -387,6 +388,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
{
int ufd;
struct timerfd_ctx *ctx;
+ enum alarmtimer_type type;
/* Check the TFD_* constants for consistency. */
BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
@@ -397,7 +399,8 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
clockid != CLOCK_REALTIME &&
clockid != CLOCK_REALTIME_ALARM &&
clockid != CLOCK_BOOTTIME &&
- clockid != CLOCK_BOOTTIME_ALARM))
+ clockid != CLOCK_BOOTTIME_ALARM &&
+ clockid != CLOCK_POWEROFF_ALARM))
return -EINVAL;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -408,13 +411,12 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
spin_lock_init(&ctx->cancel_lock);
ctx->clockid = clockid;
- if (isalarm(ctx))
- alarm_init(&ctx->t.alarm,
- ctx->clockid == CLOCK_REALTIME_ALARM ?
- ALARM_REALTIME : ALARM_BOOTTIME,
- timerfd_alarmproc);
- else
+ if (isalarm(ctx)) {
+ type = clock2alarm(ctx->clockid);
+ alarm_init(&ctx->t.alarm, type, timerfd_alarmproc);
+ } else {
hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS);
+ }
ctx->moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 });
@@ -486,6 +488,10 @@ static int do_timerfd_settime(int ufd, int flags,
ret = timerfd_setup(ctx, flags, new);
spin_unlock_irq(&ctx->wqh.lock);
+
+ if (ctx->clockid == CLOCK_POWEROFF_ALARM)
+ set_power_on_alarm();
+
fdput(f);
return ret;
}