Unified · Split
| @@ -81,6 +81,7 @@ struct tvec_base { · 80 unmodified lines | ||
| 81 | 81 | unsigned long timer_jiffies; |
| 82 | 82 | unsigned long next_timer; |
| 83 | 83 | unsigned long active_timers; |
| 84 | + unsigned long all_timers; | |
| 84 | 85 | struct tvec_root tv1; |
| 85 | 86 | struct tvec tv2; |
| 86 | 87 | struct tvec tv3; |
| @@ -337,6 +338,20 @@ void set_timer_slack(struct timer_list *timer, int slack_hz) · 250 unmodified lines | ||
| 337 | 338 | } |
| 338 | 339 | EXPORT_SYMBOL_GPL(set_timer_slack); |
| 339 | 340 | |
| 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 | + | |
| 340 | 355 | static void |
| 341 | 356 | __internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
| 342 | 357 | { |
| @@ -383,15 +398,17 @@ __internal_add_timer(struct tvec_base *base, struct timer_list *timer) · 40 unmodified lines | ||
| 383 | 398 | |
| 384 | 399 | static void internal_add_timer(struct tvec_base *base, struct timer_list *timer) |
| 385 | 400 | { |
| 401 | + (void)catchup_timer_jiffies(base); | |
| 386 | 402 | __internal_add_timer(base, timer); |
| 387 | 403 | /* |
| 388 | 404 | * Update base->active_timers and base->next_timer |
| 389 | 405 | */ |
| 390 | 406 | 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)) | |
| 392 | 409 | base->next_timer = timer->expires; |
| 393 | − base->active_timers++; | |
| 394 | 410 | } |
| 411 | + base->all_timers++; | |
| 395 | 412 | } |
| 396 | 413 | |
| 397 | 414 | #ifdef CONFIG_TIMER_STATS |
| @@ -671,6 +688,8 @@ detach_expired_timer(struct timer_list *timer, struct tvec_base *base) · 273 unmodified lines | ||
| 671 | 688 | detach_timer(timer, true); |
| 672 | 689 | if (!tbase_get_deferrable(timer->base)) |
| 673 | 690 | base->active_timers--; |
| 691 | + base->all_timers--; | |
| 692 | + (void)catchup_timer_jiffies(base); | |
| 674 | 693 | } |
| 675 | 694 | |
| 676 | 695 | 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 | ||
| 685 | 704 | if (timer->expires == base->next_timer) |
| 686 | 705 | base->next_timer = base->timer_jiffies; |
| 687 | 706 | } |
| 707 | + base->all_timers--; | |
| 708 | + (void)catchup_timer_jiffies(base); | |
| 688 | 709 | return 1; |
| 689 | 710 | } |
| 690 | 711 | |
| @@ -1153,6 +1174,10 @@ static inline void __run_timers(struct tvec_base *base) · 462 unmodified lines | ||
| 1153 | 1174 | struct timer_list *timer; |
| 1154 | 1175 | |
| 1155 | 1176 | spin_lock_irq(&base->lock); |
| 1177 | + if (catchup_timer_jiffies(base)) { | |
| 1178 | + spin_unlock_irq(&base->lock); | |
| 1179 | + return; | |
| 1180 | + } | |
| 1156 | 1181 | while (time_after_eq(jiffies, base->timer_jiffies)) { |
| 1157 | 1182 | struct list_head work_list; |
| 1158 | 1183 | struct list_head *head = &work_list; |
| @@ -1566,6 +1591,7 @@ static int init_timers_cpu(int cpu) · 407 unmodified lines | ||
| 1566 | 1591 | base->timer_jiffies = jiffies; |
| 1567 | 1592 | base->next_timer = base->timer_jiffies; |
| 1568 | 1593 | base->active_timers = 0; |
| 1594 | + base->all_timers = 0; | |
| 1569 | 1595 | return 0; |
| 1570 | 1596 | } |
| 1571 | 1597 | |