--- m/kernel/softirq.c 2022-07-27 19:33:46.550253900 +0800 +++ n/kernel/softirq.c 2022-07-27 19:43:33.835184000 +0800 @@ -516,6 +516,7 @@ static inline void lockdep_softirq_end(b asmlinkage __visible void __softirq_entry __do_softirq(void) { unsigned long end = jiffies + MAX_SOFTIRQ_TIME; + unsigned long ts_sum = jiffies + 2; unsigned long old_flags = current->flags; int max_restart = MAX_SOFTIRQ_RESTART; struct softirq_action *h; @@ -545,6 +546,7 @@ restart: h = softirq_vec; while ((softirq_bit = ffs(pending))) { + unsigned long ts_single = jiffies + 2; unsigned int vec_nr; int prev_count; @@ -558,6 +560,11 @@ restart: trace_softirq_entry(vec_nr); h->action(h); trace_softirq_exit(vec_nr); + + WARN_ONCE(time_after(jiffies, ts_single), + "softirq hog %s\n", softirq_to_name[vec_nr]); + WARN_ON_ONCE(time_after(jiffies, ts_sum)); + if (unlikely(prev_count != preempt_count())) { pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n", vec_nr, softirq_to_name[vec_nr], h->action, --- m/net/core/dev.c 2022-07-27 19:36:47.136101600 +0800 +++ n/net/core/dev.c 2022-07-27 19:45:49.911201000 +0800 @@ -5019,6 +5019,7 @@ static __latent_entropy void net_tx_acti if (sd->output_queue) { struct Qdisc *head; + unsigned long ts; local_irq_disable(); head = sd->output_queue; @@ -5028,12 +5029,15 @@ static __latent_entropy void net_tx_acti rcu_read_lock(); + ts = jiffies + 2; + while (head) { struct Qdisc *q = head; spinlock_t *root_lock = NULL; head = head->next_sched; + WARN_ON_ONCE(time_after(jiffies, ts)); /* We need to make sure head->next_sched is read * before clearing __QDISC_STATE_SCHED */