Skip to contentSkip to conversation

Posix Alarm Timers patchqueue

PATCH New John Stultz 1 participant 4 messages Apr 1, 2011 Timekeeping, clocksource core, NTP, alarmtimer

lore
Share & tools
lore
#0 lore raw

cover Posix Alarm Timers patchqueue

Now that most of the prerequisite code has been merged, I wanted to send out the Posix Alarm Timers patchset for some review in hopes that the details can be worked out so that it can be merged in 2.6.40 or shortly there after.

Issues I'd like to get feedback on:

1) Does the in-kernel alarm timer interface seem sufficient for the Android Alarm Timers to adapt to using?

2) For the Posix Alarm Timers, what capabilities should be required in order to allow an application to set an alarm?

3) For in-kernel alarm timers, should there be some override or explicit switch in sysfs that allows alarm timers to be enabled or disabled to allow a user to make sure their system is not woken up by an alarm timer, if they desire. What should that switch look like?

Remaining issues/Future work:
1) Currently CLOCK_BOOTTIME is updated from read_persistant_clock(), however some systems do not support that call, instead using the RTC to set the time on resume. I'm working on a hook on resume that allows the RTC hook to increment the timekeeping sleep time as well.

2) I'd like to try to hook up _ALARM clockids to the timerfd infrastructure to see if that interface might more closely map to the Android Alarm Timers interface.

thanks
-john

CC Arve Hjønnevåg <[email protected]>
CC Thomas Gleixner <[email protected]>
CC Alessandro Zummo <[email protected]>

John Stultz (3):
timers: Add rb_init_node() to allow for stack allocated rb nodes
timers: Introduce in-kernel alarm-timer interface
timers: posix interface for alarm-timers

 include/linux/alarmtimer.h   |   30 ++
 include/linux/posix-timers.h |    2 +
 include/linux/rbtree.h       |    8 +
 include/linux/time.h         |    2 +
 include/linux/timerqueue.h   |    2 +-
 kernel/time/Makefile         |    2 +-
 kernel/time/alarmtimer.c     |  701 ++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 745 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/alarmtimer.h
 create mode 100644 kernel/time/alarmtimer.c
Signature · 1 line
1.7.3.2.146.gca209
#1 lore raw

PATCH 1/3 timers: Add rb_init_node() to allow for stack allocated rb nodes

In cases where a timerqueue_node or some structure that utilizes a timerqueue_node is allocated on the stack, gcc would give warnings caused by the timerqueue_init()'s calling RB_CLEAR_NODE, which self-references the nodes uninitialized data.

The solution is to create an rb_init_node() function that zeros the rb_node structure out and then calls RB_CLEAR_NODE(), and then call the new init function from timerqueue_init().

---
 include/linux/rbtree.h     |    8 ++++++++
 include/linux/timerqueue.h |    2 +-
 2 files changed, 9 insertions(+), 1 deletions(-)
include/linux/rbtree.h +8 -0
index 7066acb..033b507 100644
@@ -136,6 +136,14 @@ static inline void rb_set_color(struct rb_node *rb, int color)
 #define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
 #define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
 
+static inline void rb_init_node(struct rb_node *rb)
+{
+	rb->rb_parent_color = 0;
+	rb->rb_right = NULL;
+	rb->rb_left = NULL;
+	RB_CLEAR_NODE(rb);
+}
+
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
include/linux/timerqueue.h +1 -1
index d24aaba..98b0a6c 100644
@@ -39,7 +39,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
 
 static inline void timerqueue_init(struct timerqueue_node *node)
 {
-	RB_CLEAR_NODE(&node->node);
+	rb_init_node(&node->node);
 }
 
 static inline void timerqueue_init_head(struct timerqueue_head *head)
Signature · 1 line
1.7.3.2.146.gca209
#2 lore raw

PATCH 2/3 timers: Introduce in-kernel alarm-timer interface

In reply to John Stultz

This provides the in kernel interface and infrastructure for alarm-timers.

Alarm-timers are a hybrid style timer, similar to hrtimers, but when the system is suspended, the RTC device is set to fire and wake the system for when the soonest alarm-timer expires.

The concept for Alarm-timers was inspired by the Android Alarm driver (by Arve Hjønnevåg) found in the Android kernel tree.

See: http://android.git.kernel.org/?p=kernel/common.git;a=blob;f=drivers/rtc/alarm.c;h=1250edfbdf3302f5e4ea6194847c6ef4bb7beb1c;hb=android-2.6.36

This in-kernel interface should be compatible with the Android alarm driver in-kernel interface, but has the advantage of utilizing the new RTC timerqueue code instead of doing direct RTC manipulation.

CC Arve Hjønnevåg <[email protected]>
CC Thomas Gleixner <[email protected]>
CC Alessandro Zummo <[email protected]>
---
 include/linux/alarmtimer.h |   30 ++++
 kernel/time/Makefile       |    2 +-
 kernel/time/alarmtimer.c   |  375 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 406 insertions(+), 1 deletions(-)
 create mode 100644 include/linux/alarmtimer.h
 create mode 100644 kernel/time/alarmtimer.c
include/linux/alarmtimer.h new file +30 -0
new file mode 100644
index 0000000..6861f28
@@ -0,0 +1,30 @@
+#ifndef _LINUX_ALARMTIMER_H
+#define _LINUX_ALARMTIMER_H
+
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/timerqueue.h>
+#include <linux/rtc.h>
+
+enum alarmtimer_type {
+	ALARM_REALTIME,
+	ALARM_BOOTTIME,
+
+	ALARM_NUMTYPE,
+};
+
+struct alarm {
+	struct timerqueue_node node;
+	ktime_t period;
+	void (*function)(struct alarm *);
+	enum alarmtimer_type type;
+	char enabled;
+	void *data;
+};
+
+void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
+		void (*function)(struct alarm *));
+void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);
+void alarm_cancel(struct alarm *alarm);
+
+#endif
kernel/time/Makefile +1 -1
index b042599..e2fd74b 100644
@@ -1,5 +1,5 @@
 obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o
-obj-y += timeconv.o posix-clock.o
+obj-y += timeconv.o posix-clock.o alarmtimer.o
 
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD)		+= clockevents.o
 obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= tick-common.o
kernel/time/alarmtimer.c new file +375 -0

375 lines not on this page · raw message

Signature · 1 line
1.7.3.2.146.gca209
#3 lore raw

PATCH 3/3 timers: posix interface for alarm-timers

In reply to John Stultz

This patch exposes alarm-timers to userland via the posix clock and timers interface, using two new clockids: CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM. Both clockids behave identically to CLOCK_REALTIME and CLOCK_BOOTTIME, respectively, but timers set against the _ALARM suffixed clockids will wake the system if it is suspended.

Some background can be found here:

	https://lwn.net/Articles/429925/

The concept for Alarm-timers was inspired by the Android Alarm driver (by Arve Hjønnevåg) found in the Android kernel tree.

See: http://android.git.kernel.org/?p=kernel/common.git;a=blob;f=drivers/rtc/alarm.c;h=1250edfbdf3302f5e4ea6194847c6ef4bb7beb1c;hb=android-2.6.36

While the in-kernel interface is pretty similar between alarm-timers and Android alarm driver, the user-space interface for the Android alarm driver is via ioctls to a new char device. As mentioned above, I've instead chosen to export this functionality via the posix interface, as it seemed a little simpler and avoids creating duplicate interfaces to things like CLOCK_REALTIME and CLOCK_MONOTONIC under alternate names (ie:ANDROID_ALARM_RTC and ANDROID_ALARM_SYSTEMTIME).

The semantics of the Android alarm driver are different from what this posix interface provides. For instance, threads other then the thread waiting on the Android alarm driver are able to modify the alarm being waited on. Also this interface does not allow the same wakelock semantics that the Android driver provides (ie: kernel takes a wakelock on RTC alarm-interupt, and holds it through process wakeup, and while the process runs, until the process either closes the char device or calls back in to wait on a new alarm).

One potential way to implement similar semantics may be via the timerfd infrastructure.

Open questions that need to be resolved prior to inclusion:
o What capabilities are needed to set _ALARM timers
o Do we need some sort of ability (possibly via sysfs) to enable/disable alarm timers, so that suspended laptops don't wake up at inappropriate times.

CC Arve Hjønnevåg <[email protected]>
CC Thomas Gleixner <[email protected]>
CC Alessandro Zummo <[email protected]>
---
 include/linux/posix-timers.h |    2 +
 include/linux/time.h         |    2 +
 kernel/time/alarmtimer.c     |  326 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 330 insertions(+), 0 deletions(-)
include/linux/posix-timers.h +2 -0
index d51243a..808227d 100644
@@ -5,6 +5,7 @@
 #include <linux/list.h>
 #include <linux/sched.h>
 #include <linux/timex.h>
+#include <linux/alarmtimer.h>
 
 union cpu_time_count {
 	cputime_t cpu;
@@ -80,6 +81,7 @@ struct k_itimer {
 			unsigned long incr;
 			unsigned long expires;
 		} mmtimer;
+		struct alarm alarmtimer;
 	} it;
 };
 
include/linux/time.h +2 -0
index 454a262..56c4998 100644
@@ -294,6 +294,8 @@ struct itimerval {
 #define CLOCK_REALTIME_COARSE		5
 #define CLOCK_MONOTONIC_COARSE		6
 #define CLOCK_BOOTTIME			7
+#define CLOCK_REALTIME_ALARM		8
+#define CLOCK_BOOTTIME_ALARM		9
 
 /*
  * The IDs of various hardware clocks:
kernel/time/alarmtimer.c +326 -0

344 lines not on this page · raw message

Signature · 1 line
1.7.3.2.146.gca209