From 7068b7a16270f1e85a8893d74b0f3c58d7826883 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 28 Apr 2011 13:29:18 -0700 Subject: timers: Remove delayed irqwork from alarmtimers implementation Thomas asked about the delayed irq work in the alarmtimers code, and I realized that it was a legacy from when the alarmtimer base lock was a mutex (due to concerns that we'd be interacting with the RTC device, which is protected by mutexes). Since the alarmtimer base is now protected by a spinlock, we can simply execute alarmtimer functions directly from the hrtimer callback. Should any future alarmtimer functions sleep, they can simply manage scheduling any delayed work themselves. CC: Thomas Gleixner Signed-off-by: John Stultz --- kernel/time/alarmtimer.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index bed9800..491e37b 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -33,7 +33,6 @@ * @timer: hrtimer used to schedule events while running * @gettime: Function to read the time correlating to the base * @base_clockid: clockid for the base - * @irqwork Delayed work structure for expiring timers */ static struct alarm_base { spinlock_t lock; @@ -41,7 +40,6 @@ static struct alarm_base { struct hrtimer timer; ktime_t (*gettime)(void); clockid_t base_clockid; - struct work_struct irqwork; } alarm_bases[ALARM_NUMTYPE]; /* rtc timer and device for setting alarm wakeups at suspend */ @@ -97,22 +95,23 @@ static void alarmtimer_remove(struct alarm_base *base, struct alarm *alarm) } } + /** - * alarmtimer_do_work - Handles alarm being fired. - * @work: pointer to workqueue being run + * alarmtimer_fired - Handles alarm hrtimer being fired. + * @timer: pointer to hrtimer being run * * When a alarm timer fires, this runs through the timerqueue to * see which alarms expired, and runs those. If there are more alarm * timers queued for the future, we set the hrtimer to fire when * when the next future alarm timer expires. */ -static void alarmtimer_do_work(struct work_struct *work) +static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) { - struct alarm_base *base = container_of(work, struct alarm_base, - irqwork); + struct alarm_base *base = container_of(timer, struct alarm_base, timer); struct timerqueue_node *next; unsigned long flags; ktime_t now; + int ret = HRTIMER_NORESTART; spin_lock_irqsave(&base->lock, flags); now = base->gettime(); @@ -140,25 +139,13 @@ static void alarmtimer_do_work(struct work_struct *work) } if (next) { - hrtimer_start(&base->timer, next->expires, - HRTIMER_MODE_ABS); + hrtimer_set_expires(&base->timer, next->expires); + ret = HRTIMER_RESTART; } spin_unlock_irqrestore(&base->lock, flags); -} + return ret; -/** - * alarmtimer_fired - Handles alarm hrtimer being fired. - * @timer: pointer to hrtimer being run - * - * When a timer fires, this schedules the do_work function to - * be run. - */ -static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) -{ - struct alarm_base *base = container_of(timer, struct alarm_base, timer); - schedule_work(&base->irqwork); - return HRTIMER_NORESTART; } @@ -636,7 +623,6 @@ static int __init alarmtimer_init(void) alarm_bases[i].base_clockid, HRTIMER_MODE_ABS); alarm_bases[i].timer.function = alarmtimer_fired; - INIT_WORK(&alarm_bases[i].irqwork, alarmtimer_do_work); } error = platform_driver_register(&alarmtimer_driver); platform_device_register_simple("alarmtimer", -1, NULL, 0); -- cgit v1.1