timer: add on-stack deferrable timer interfaces
Jesse Barnes [Mon, 10 May 2010 21:26:20 +0000 (14:26 -0700)]
In some cases (for instance with kernel threads) it may be desireable to
use on-stack deferrable timers to get their power saving benefits.  Add
interfaces to support this for the IPS driver.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Matthew Garrett <mjg@redhat.com>

include/linux/timer.h
kernel/timer.c

index ea965b8..38cf093 100644 (file)
@@ -100,6 +100,13 @@ void init_timer_deferrable_key(struct timer_list *timer,
                setup_timer_on_stack_key((timer), #timer, &__key,       \
                                         (fn), (data));                 \
        } while (0)
+#define setup_deferrable_timer_on_stack(timer, fn, data)               \
+       do {                                                            \
+               static struct lock_class_key __key;                     \
+               setup_deferrable_timer_on_stack_key((timer), #timer,    \
+                                                   &__key, (fn),       \
+                                                   (data));            \
+       } while (0)
 #else
 #define init_timer(timer)\
        init_timer_key((timer), NULL, NULL)
@@ -111,6 +118,8 @@ void init_timer_deferrable_key(struct timer_list *timer,
        setup_timer_key((timer), NULL, NULL, (fn), (data))
 #define setup_timer_on_stack(timer, fn, data)\
        setup_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
+#define setup_deferrable_timer_on_stack(timer, fn, data)\
+       setup_deferrable_timer_on_stack_key((timer), NULL, NULL, (fn), (data))
 #endif
 
 #ifdef CONFIG_DEBUG_OBJECTS_TIMERS
@@ -150,6 +159,12 @@ static inline void setup_timer_on_stack_key(struct timer_list *timer,
        init_timer_on_stack_key(timer, name, key);
 }
 
+extern void setup_deferrable_timer_on_stack_key(struct timer_list *timer,
+                                               const char *name,
+                                               struct lock_class_key *key,
+                                               void (*function)(unsigned long),
+                                               unsigned long data);
+
 /**
  * timer_pending - is a timer pending?
  * @timer: the timer in question
index ee305c8..efde11e 100644 (file)
@@ -577,6 +577,19 @@ static void __init_timer(struct timer_list *timer,
        lockdep_init_map(&timer->lockdep_map, name, key, 0);
 }
 
+void setup_deferrable_timer_on_stack_key(struct timer_list *timer,
+                                        const char *name,
+                                        struct lock_class_key *key,
+                                        void (*function)(unsigned long),
+                                        unsigned long data)
+{
+       timer->function = function;
+       timer->data = data;
+       init_timer_on_stack_key(timer, name, key);
+       timer_set_deferrable(timer);
+}
+EXPORT_SYMBOL_GPL(setup_deferrable_timer_on_stack_key);
+
 /**
  * init_timer_key - initialize a timer
  * @timer: the timer to be initialized