Subject: softirq: Rewrite softirq processing loop From: Peter Zijlstra Date: Fri Sep 11 17:00:03 CEST 2020 From: Peter Zijlstra Simplify the softirq processing loop by using the bitmap APIs [ tglx: Make max_restart unsigned int and reduce the variable declaration maze ] Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Thomas Gleixner --- kernel/softirq.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -254,13 +254,11 @@ static inline void lockdep_softirq_end(b asmlinkage __visible void __softirq_entry __do_softirq(void) { - unsigned long end = jiffies + MAX_SOFTIRQ_TIME; + unsigned int vec_nr, max_restart = MAX_SOFTIRQ_RESTART; unsigned long old_flags = current->flags; - int max_restart = MAX_SOFTIRQ_RESTART; struct softirq_action *h; + unsigned long pending; bool in_hardirq; - __u32 pending; - int softirq_bit; /* * Mask out PF_MEMALLOC as the current task context is borrowed for the @@ -281,20 +279,15 @@ asmlinkage __visible void __softirq_entr local_irq_enable(); - h = softirq_vec; - - while ((softirq_bit = ffs(pending))) { - unsigned int vec_nr; + for_each_set_bit(vec_nr, &pending, NR_SOFTIRQS) { int prev_count; - h += softirq_bit - 1; - - vec_nr = h - softirq_vec; - prev_count = preempt_count(); - + __clear_bit(vec_nr, &pending); kstat_incr_softirqs_this_cpu(vec_nr); + prev_count = preempt_count(); trace_softirq_entry(vec_nr); + h = softirq_vec + vec_nr; h->action(h); trace_softirq_exit(vec_nr); if (unlikely(prev_count != preempt_count())) { @@ -303,8 +296,6 @@ asmlinkage __visible void __softirq_entr prev_count, preempt_count()); preempt_count_set(prev_count); } - h++; - pending >>= softirq_bit; } if (__this_cpu_read(ksoftirqd) == current)