History

Merge branch 'timers.2014.02.25a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into timers/core

Thomas Gleixner committed 12 years ago

Commit bce19362 parents f96a34e aea369b1 file · +28 −2Browse files

Showing the changes to kernel/timer.c (1 of 1 file). Show all

Unified · Split

kernel/timer.c+28−2
@@ -81,6 +81,7 @@ struct tvec_base { · 80 unmodified lines
8181 unsigned long timer_jiffies;
8282 unsigned long next_timer;
8383 unsigned long active_timers;
84+ unsigned long all_timers;
8485 struct tvec_root tv1;
8586 struct tvec tv2;
8687 struct tvec tv3;
@@ -337,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) · 250 unmodified lines
337338 }
338339 EXPORT_SYMBOL_GPL(set_timer_slack);
339340
341+/*
342+ * If the list is empty, catch up ->timer_jiffies to the current time.
343+ * The caller must hold the tvec_base lock. Returns true if the list
344+ * was empty and therefore ->timer_jiffies was updated.
345+ */
346+static bool catchup_timer_jiffies(struct tvec_base *base)
347+{
348+ if (!base->all_timers) {
349+ base->timer_jiffies = jiffies;
350+ return true;
351+ }
352+ return false;
353+}
354+
340355 static void
341356 __internal_add_timer(struct tvec_base *base, struct timer_list *timer)
342357 {
@@ -383,15 +398,17 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer) · 40 unmodified lines
383398
384399 static void internal_add_timer(struct tvec_base *base, struct timer_list *timer)
385400 {
401+ (void)catchup_timer_jiffies(base);
386402 __internal_add_timer(base, timer);
387403 /*
388404 * Update base->active_timers and base->next_timer
389405 */
390406 if (!tbase_get_deferrable(timer->base)) {
391− if (time_before(timer->expires, base->next_timer))
407+ if (!base->active_timers++ ||
408+ time_before(timer->expires, base->next_timer))
392409 base->next_timer = timer->expires;
393− base->active_timers++;
394410 }
411+ base->all_timers++;
395412 }
396413
397414 #ifdef CONFIG_TIMER_STATS
@@ -671,6 +688,8 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) · 273 unmodified lines
671688 detach_timer(timer, true);
672689 if (!tbase_get_deferrable(timer->base))
673690 base->active_timers--;
691+ base->all_timers--;
692+ (void)catchup_timer_jiffies(base);
674693 }
675694
676695 static int detach_if_pending(struct timer_list *timer, struct tvec_base *base,
@@ -685,6 +704,8 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, · 8 unmodified lines
685704 if (timer->expires == base->next_timer)
686705 base->next_timer = base->timer_jiffies;
687706 }
707+ base->all_timers--;
708+ (void)catchup_timer_jiffies(base);
688709 return 1;
689710 }
690711
@@ -1153,6 +1174,10 @@ static inline void __run_timers(struct tvec_base *base) · 462 unmodified lines
11531174 struct timer_list *timer;
11541175
11551176 spin_lock_irq(&base->lock);
1177+ if (catchup_timer_jiffies(base)) {
1178+ spin_unlock_irq(&base->lock);
1179+ return;
1180+ }
11561181 while (time_after_eq(jiffies, base->timer_jiffies)) {
11571182 struct list_head work_list;
11581183 struct list_head *head = &work_list;
@@ -1566,6 +1591,7 @@ static int init_timers_cpu(int cpu) · 407 unmodified lines
15661591 base->timer_jiffies = jiffies;
15671592 base->next_timer = base->timer_jiffies;
15681593 base->active_timers = 0;
1594+ base->all_timers = 0;
15691595 return 0;
15701596 }
15711597