Message ID | 20230505113315.3307723-10-liujian56@huawei.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | fix softlockup in run_timer_softirq | expand |
Context | Check | Description |
---|---|---|
netdev/series_format | success | Posting correctly formatted |
netdev/tree_selection | success | Guessed tree name to be net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | fail | Errors and warnings before: 10 this patch: 11 |
netdev/cc_maintainers | success | CCed 3 of 3 maintainers |
netdev/build_clang | fail | Errors and warnings before: 8 this patch: 9 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/deprecated_api | success | None detected |
netdev/check_selftest | success | No net selftest shell script |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | fail | Errors and warnings before: 10 this patch: 11 |
netdev/checkpatch | warning | WARNING: line length of 82 exceeds 80 columns |
netdev/kdoc | fail | Errors and warnings before: 0 this patch: 1 |
netdev/source_inline | warning | Was 1 now: 1 |
diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 63a8ce7177dd..70744a469a39 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1992,7 +1992,7 @@ void timer_clear_idle(void) * __run_timers - run all expired timers (if any) on this CPU. * @base: the timer vector to be processed. */ -static inline void __run_timers(struct timer_base *base) +static inline void __run_timers(struct timer_base *base, struct softirq_action *h) { struct hlist_head heads[LVL_DEPTH]; int levels; @@ -2020,6 +2020,12 @@ static inline void __run_timers(struct timer_base *base) while (levels--) expire_timers(base, heads + levels); + + if (softirq_needs_break(h)) { + if (time_after_eq(jiffies, base->next_expiry)) + __raise_softirq_irqoff(TIMER_SOFTIRQ); + break; + } } raw_spin_unlock_irq(&base->lock); timer_base_unlock_expiry(base); @@ -2032,9 +2038,9 @@ static __latent_entropy void run_timer_softirq(struct softirq_action *h) { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); - __run_timers(base); + __run_timers(base, h); if (IS_ENABLED(CONFIG_NO_HZ_COMMON)) - __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); + __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF]), h); } /*
In the while loop of __run_timers(), because there are too many timers or improper timer handler functions, if the processing time of the expired timers is always greater than the time wheel's next_expiry, the function will loop infinitely. To prevent this, use the timeout/break logic provided by SoftIRQs. If the running time exceeds the limit, break the loop and an additional TIMER_SOFTIRQ is triggered. Signed-off-by: Liu Jian <liujian56@huawei.com> --- kernel/time/timer.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)