Skip to content

Commit d11d579

Browse files
Maciej W. RozyckiIngo Molnar
authored andcommitted
x86: I/O APIC: AEOI timer acknowledgement clean-ups
The code that used to be in do_slow_gettimeoffset() that relied on the IRR bit of the master 8259A PIC for IRQ0 to check the state of the output timer 0 of the PIT is no longer there. As a result, there is no need to use the POLL command to acknowledge the timer interrupt in the "8259A Virtual Wire", except for the NMI watchdog when the i82489DX APIC is used (this is because this particular APIC treats NMIs as level-triggered and keeping the input asserted would keep motherboard NMI sources held off for too long). Remove the unneeded bits and adjust comments accordingly. Signed-off-by: Maciej W. Rozycki <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
1 parent a0176e2 commit d11d579

File tree

4 files changed

+13
-19
lines changed

4 files changed

+13
-19
lines changed

arch/x86/kernel/io_apic_32.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,19 +2146,17 @@ static inline void __init check_timer(void)
21462146
set_intr_gate(vector, interrupt[0]);
21472147

21482148
/*
2149-
* Subtle, code in do_timer_interrupt() expects an AEOI
2150-
* mode for the 8259A whenever interrupts are routed
2151-
* through I/O APICs. Also IRQ0 has to be enabled in
2152-
* the 8259A which implies the virtual wire has to be
2153-
* disabled in the local APIC. Finally timer interrupts
2154-
* need to be acknowledged manually in the 8259A for
2155-
* timer_interrupt() and for the i82489DX when using
2156-
* the NMI watchdog.
2149+
* As IRQ0 is to be enabled in the 8259A, the virtual
2150+
* wire has to be disabled in the local APIC. Also
2151+
* timer interrupts need to be acknowledged manually in
2152+
* the 8259A for the i82489DX when using the NMI
2153+
* watchdog as that APIC treats NMIs as level-triggered.
2154+
* The AEOI mode will finish them in the 8259A
2155+
* automatically.
21572156
*/
21582157
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
21592158
init_8259A(1);
2160-
timer_ack = !cpu_has_tsc;
2161-
timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
2159+
timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
21622160
if (timer_over_8254 > 0)
21632161
enable_8259A_irq(0);
21642162

@@ -2219,6 +2217,7 @@ static inline void __init check_timer(void)
22192217
printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
22202218
nmi_watchdog = 0;
22212219
}
2220+
timer_ack = 0;
22222221

22232222
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
22242223

@@ -2237,7 +2236,6 @@ static inline void __init check_timer(void)
22372236

22382237
printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
22392238

2240-
timer_ack = 0;
22412239
init_8259A(0);
22422240
make_8259A_irq(0);
22432241
apic_write_around(APIC_LVT0, APIC_DM_EXTINT);

arch/x86/kernel/io_apic_64.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,11 +1669,8 @@ static inline void __init check_timer(void)
16691669
assign_irq_vector(0, TARGET_CPUS);
16701670

16711671
/*
1672-
* Subtle, code in do_timer_interrupt() expects an AEOI
1673-
* mode for the 8259A whenever interrupts are routed
1674-
* through I/O APICs. Also IRQ0 has to be enabled in
1675-
* the 8259A which implies the virtual wire has to be
1676-
* disabled in the local APIC.
1672+
* As IRQ0 is to be enabled in the 8259A, the virtual
1673+
* wire has to be disabled in the local APIC.
16771674
*/
16781675
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
16791676
init_8259A(1);

arch/x86/kernel/nmi_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ int __init check_nmi_watchdog(void)
131131
kfree(prev_nmi_count);
132132
return 0;
133133
error:
134-
timer_ack = !cpu_has_tsc;
134+
timer_ack = 0;
135135

136136
return -1;
137137
}

arch/x86/kernel/time_32.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
8484
if (timer_ack) {
8585
/*
8686
* Subtle, when I/O APICs are used we have to ack timer IRQ
87-
* manually to reset the IRR bit for do_slow_gettimeoffset().
88-
* This will also deassert NMI lines for the watchdog if run
87+
* manually to deassert NMI lines for the watchdog if run
8988
* on an 82489DX-based system.
9089
*/
9190
spin_lock(&i8259A_lock);

0 commit comments

Comments
 (0)