Loading kernel/timer.c +28 −2 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ struct tvec_base { unsigned long timer_jiffies; unsigned long next_timer; unsigned long active_timers; unsigned long all_timers; struct tvec_root tv1; struct tvec tv2; struct tvec tv3; Loading Loading @@ -337,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) } EXPORT_SYMBOL_GPL(set_timer_slack); /* * If the list is empty, catch up ->timer_jiffies to the current time. * The caller must hold the tvec_base lock. Returns true if the list * was empty and therefore ->timer_jiffies was updated. */ static bool catchup_timer_jiffies(struct tvec_base *base) { if (!base->all_timers) { base->timer_jiffies = jiffies; return true; } return false; } static void __internal_add_timer(struct tvec_base *base, struct timer_list *timer) { Loading Loading @@ -383,15 +398,17 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer) static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) { (void)catchup_timer_jiffies(base); __internal_add_timer(base, timer); /* * Update base->active_timers and base->next_timer */ if (!tbase_get_deferrable(timer->base)) { if (time_before(timer->expires, base->next_timer)) if (!base->active_timers++ || time_before(timer->expires, base->next_timer)) base->next_timer = timer->expires; base->active_timers++; } base->all_timers++; } #ifdef CONFIG_TIMER_STATS Loading Loading @@ -671,6 +688,8 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) detach_timer(timer, true); if (!tbase_get_deferrable(timer->base)) base->active_timers--; base->all_timers--; (void)catchup_timer_jiffies(base); } static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, Loading @@ -685,6 +704,8 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, if (timer->expires == base->next_timer) base->next_timer = base->timer_jiffies; } base->all_timers--; (void)catchup_timer_jiffies(base); return 1; } Loading Loading @@ -1153,6 +1174,10 @@ static inline void __run_timers(struct tvec_base *base) struct timer_list *timer; spin_lock_irq(&base->lock); if (catchup_timer_jiffies(base)) { spin_unlock_irq(&base->lock); return; } while (time_after_eq(jiffies, base->timer_jiffies)) { struct list_head work_list; struct list_head *head = &work_list; Loading Loading @@ -1566,6 +1591,7 @@ static int init_timers_cpu(int cpu) base->timer_jiffies = jiffies; base->next_timer = base->timer_jiffies; base->active_timers = 0; base->all_timers = 0; return 0; } Loading Loading
kernel/timer.c +28 −2 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ struct tvec_base { unsigned long timer_jiffies; unsigned long next_timer; unsigned long active_timers; unsigned long all_timers; struct tvec_root tv1; struct tvec tv2; struct tvec tv3; Loading Loading @@ -337,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) } EXPORT_SYMBOL_GPL(set_timer_slack); /* * If the list is empty, catch up ->timer_jiffies to the current time. * The caller must hold the tvec_base lock. Returns true if the list * was empty and therefore ->timer_jiffies was updated. */ static bool catchup_timer_jiffies(struct tvec_base *base) { if (!base->all_timers) { base->timer_jiffies = jiffies; return true; } return false; } static void __internal_add_timer(struct tvec_base *base, struct timer_list *timer) { Loading Loading @@ -383,15 +398,17 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer) static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) { (void)catchup_timer_jiffies(base); __internal_add_timer(base, timer); /* * Update base->active_timers and base->next_timer */ if (!tbase_get_deferrable(timer->base)) { if (time_before(timer->expires, base->next_timer)) if (!base->active_timers++ || time_before(timer->expires, base->next_timer)) base->next_timer = timer->expires; base->active_timers++; } base->all_timers++; } #ifdef CONFIG_TIMER_STATS Loading Loading @@ -671,6 +688,8 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) detach_timer(timer, true); if (!tbase_get_deferrable(timer->base)) base->active_timers--; base->all_timers--; (void)catchup_timer_jiffies(base); } static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, Loading @@ -685,6 +704,8 @@ static int detach_if_pending(struct timer_list *timer, struct tvec_base *base, if (timer->expires == base->next_timer) base->next_timer = base->timer_jiffies; } base->all_timers--; (void)catchup_timer_jiffies(base); return 1; } Loading Loading @@ -1153,6 +1174,10 @@ static inline void __run_timers(struct tvec_base *base) struct timer_list *timer; spin_lock_irq(&base->lock); if (catchup_timer_jiffies(base)) { spin_unlock_irq(&base->lock); return; } while (time_after_eq(jiffies, base->timer_jiffies)) { struct list_head work_list; struct list_head *head = &work_list; Loading Loading @@ -1566,6 +1591,7 @@ static int init_timers_cpu(int cpu) base->timer_jiffies = jiffies; base->next_timer = base->timer_jiffies; base->active_timers = 0; base->all_timers = 0; return 0; } Loading