OSDN Git Service

xtensa: add fairness to IRQ handling
authorMax Filippov <jcmvbkbc@gmail.com>
Fri, 9 Jul 2021 11:13:23 +0000 (04:13 -0700)
committerMax Filippov <jcmvbkbc@gmail.com>
Wed, 11 Aug 2021 18:36:10 +0000 (11:36 -0700)
Track which IRQs have been served at each level to make sure that no IRQ
is served more than once while other IRQs at the same level are pending.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
arch/xtensa/kernel/traps.c

index efc3a29..874b6ef 100644 (file)
@@ -268,6 +268,7 @@ void do_interrupt(struct pt_regs *regs)
                XCHAL_INTLEVEL7_MASK,
        };
        struct pt_regs *old_regs;
+       unsigned unhandled = ~0u;
 
        trace_hardirqs_off();
 
@@ -283,6 +284,10 @@ void do_interrupt(struct pt_regs *regs)
                for (level = LOCKLEVEL; level > 0; --level) {
                        if (int_at_level & int_level_mask[level]) {
                                int_at_level &= int_level_mask[level];
+                               if (int_at_level & unhandled)
+                                       int_at_level &= unhandled;
+                               else
+                                       unhandled |= int_level_mask[level];
                                break;
                        }
                }
@@ -290,6 +295,8 @@ void do_interrupt(struct pt_regs *regs)
                if (level == 0)
                        break;
 
+               /* clear lowest pending irq in the unhandled mask */
+               unhandled ^= (int_at_level & -int_at_level);
                do_IRQ(__ffs(int_at_level), regs);
        }