[RFC patch 4/5] posix-timers: Expose deferrable mode to user space

From: Thomas Gleixner
Date: Fri Feb 21 2014 - 12:57:23 EST


Expose the deferrable timer mode to user space by adding a new
TIMER_IS_DEFERRABLE flag.

The deferrable mode is available for the syscalls clock_nanosleep()
and timer_settime(). For both syscalls TIMER_IS_DEFERRABLE is handed
in via the 'flags' argument. TIMER_ABSTIME and TIMER_IS_DEFERRABLE can
be ored together.

If a timer is started with this flag, the expiry of the timer is
relaxed. The timer is guaranteed to not expire before the given expiry
time, but the expiry can be delayed to the point where a non
deferrable timer expires. Deferred timers are not waking up a cpu from
a deep idle period.

Applications using the TIMER_IS_DEFERRABLE flag work on older kernels
as well, but the timers won't have the deferrable functionality.

Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Michael Kerrisk <mtk.manpages@xxxxxxxxx>
---
include/uapi/linux/time.h | 4 ++++
kernel/posix-timers.c | 10 +++++++---
2 files changed, 11 insertions(+), 3 deletions(-)

Index: tip/include/uapi/linux/time.h
===================================================================
--- tip.orig/include/uapi/linux/time.h
+++ tip/include/uapi/linux/time.h
@@ -63,7 +63,11 @@ struct itimerval {

/*
* The various flags for setting POSIX.1b interval timers:
+ *
+ * We keep that in sync with the TFD_TIMER_ flags
*/
#define TIMER_ABSTIME 0x01
+/* Reserved for TFD_ONLY flag 0x02 */
+#define TIMER_IS_DEFERRABLE 0x04

#endif /* _UAPI_LINUX_TIME_H */
Index: tip/kernel/posix-timers.c
===================================================================
--- tip.orig/kernel/posix-timers.c
+++ tip/kernel/posix-timers.c
@@ -846,6 +846,7 @@ common_timer_set(struct k_itimer *timr,
return 0;

mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
+ mode |= flags & TIMER_DEFERRABLE ? HRTIMER_MODE_DEFERRABLE : 0;
hrtimer_init(&timr->it.real.timer, timr->it_clock, mode);
timr->it.real.timer.function = posix_timer_fn;

@@ -1079,9 +1080,12 @@ SYSCALL_DEFINE2(clock_getres, const cloc
static int common_nsleep(const clockid_t which_clock, int flags,
struct timespec *tsave, struct timespec __user *rmtp)
{
- return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
- HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
- which_clock);
+ enum hrtimer_mode mode;
+
+ mode = flags & TIMER_ABSTIME ? HRTIMER_MODE_ABS : HRTIMER_MODE_REL;
+ mode |= flags & TIMER_DEFERRABLE ? HRTIMER_MODE_DEFERRABLE : 0;
+
+ return hrtimer_nanosleep(tsave, rmtp, mode, which_clock);
}

SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/