The following commit has been merged into the x86/apic branch of tip:

Commit-ID:     058df195c23403f91acc028e39ca2ad599d0af52
Gitweb:        
https://git.kernel.org/tip/058df195c23403f91acc028e39ca2ad599d0af52
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Thu, 10 Dec 2020 21:15:04 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Thu, 10 Dec 2020 23:02:31 +01:00

x86/ioapic: Cleanup the timer_works() irqflags mess

Mark tripped over the creative irqflags handling in the IO-APIC timer
delivery check which ends up doing:

        local_irq_save(flags);
        local_irq_enable();
        local_irq_restore(flags);

which triggered a new consistency check he's working on required for
replacing the POPF based restore with a conditional STI.

That code is a historical mess and none of this is needed. Make it
straightforward use local_irq_disable()/enable() as that's all what is
required. It is invoked from interrupt enabled code nowadays.

Reported-by: Mark Rutland <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Tested-by: Mark Rutland <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

---
 arch/x86/kernel/apic/io_apic.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 089e755..e4ab480 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1620,21 +1620,16 @@ static void __init delay_without_tsc(void)
 static int __init timer_irq_works(void)
 {
        unsigned long t1 = jiffies;
-       unsigned long flags;
 
        if (no_timer_check)
                return 1;
 
-       local_save_flags(flags);
        local_irq_enable();
-
        if (boot_cpu_has(X86_FEATURE_TSC))
                delay_with_tsc();
        else
                delay_without_tsc();
 
-       local_irq_restore(flags);
-
        /*
         * Expect a few ticks at least, to be sure some possible
         * glue logic does not lock up after one or two first
@@ -1643,10 +1638,10 @@ static int __init timer_irq_works(void)
         * least one tick may be lost due to delays.
         */
 
-       /* jiffies wrap? */
-       if (time_after(jiffies, t1 + 4))
-               return 1;
-       return 0;
+       local_irq_disable();
+
+       /* Did jiffies advance? */
+       return time_after(jiffies, t1 + 4);
 }
 
 /*
@@ -2163,13 +2158,12 @@ static inline void __init check_timer(void)
        struct irq_cfg *cfg = irqd_cfg(irq_data);
        int node = cpu_to_node(0);
        int apic1, pin1, apic2, pin2;
-       unsigned long flags;
        int no_pin1 = 0;
 
        if (!global_clock_event)
                return;
 
-       local_irq_save(flags);
+       local_irq_disable();
 
        /*
         * get/set the timer IRQ vector:
@@ -2237,7 +2231,6 @@ static inline void __init check_timer(void)
                        goto out;
                }
                panic_if_irq_remap("timer doesn't work through 
Interrupt-remapped IO-APIC");
-               local_irq_disable();
                clear_IO_APIC_pin(apic1, pin1);
                if (!no_pin1)
                        apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
@@ -2261,7 +2254,6 @@ static inline void __init check_timer(void)
                /*
                 * Cleanup, just in case ...
                 */
-               local_irq_disable();
                legacy_pic->mask(0);
                clear_IO_APIC_pin(apic2, pin2);
                apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
@@ -2278,7 +2270,6 @@ static inline void __init check_timer(void)
                apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
-       local_irq_disable();
        legacy_pic->mask(0);
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
        apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
@@ -2297,7 +2288,6 @@ static inline void __init check_timer(void)
                apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
                goto out;
        }
-       local_irq_disable();
        apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
        if (apic_is_x2apic_enabled())
                apic_printk(APIC_QUIET, KERN_INFO
@@ -2306,7 +2296,7 @@ static inline void __init check_timer(void)
        panic("IO-APIC + timer doesn't work!  Boot with apic=debug and send a "
                "report.  Then try booting with the 'noapic' option.\n");
 out:
-       local_irq_restore(flags);
+       local_irq_enable();
 }
 
 /*

Reply via email to