From e2409a0e5269fb6ba5268d820b7ad50a0392ade1 Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Tue, 1 Oct 2019 21:53:28 +0900 Subject: [PATCH] Issue the EOI at the beginning of the interrupt handler in order to avoid deadlocks --- kernel/arch/interrupt.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/kernel/arch/interrupt.c b/kernel/arch/interrupt.c index 8649a4a..b0db93c 100644 --- a/kernel/arch/interrupt.c +++ b/kernel/arch/interrupt.c @@ -50,6 +50,27 @@ int _int_handle(stack_frame_t ctx) default: break; } + + /* + * Issue the EOI before invoking the scheduler since it might reschedule + * tasks, and the remainder of the function would not be executed until + * this task gets scheduled again. Since the interrupt controller (whether + * it be the i8259 or the APIC) will not issue further interrupts until + * an EOI is issued, the next task would effectively not get preempted + * until it makes a syscall or causes an exception (or an NMI or IPI + * occurs). + * + * TLDR: Issue the EOI first to avoid deadlocks. + */ + +#if CONFIG_APIC == 1 + /* FIXME: Make sure this is NOT done for NMI, SMI, INIT, ExtInt, + * SIPI or INIT-deassert mode interrupts */ + _apic_eoi(ctx.intn); +#else + _i8259_eoi(ctx.intn); +#endif /* CONFIG_APIC */ + /* if(ctx.intn == 32) { unsigned *apic_esr; @@ -95,14 +116,6 @@ int _int_handle(stack_frame_t ctx) break; } - #if CONFIG_APIC == 1 - /* FIXME: Make sure this is NOT done for NMI, SMI, INIT, ExtInt, - * SIPI or INIT-deassert mode interrupts */ - _apic_eoi(ctx.intn); - #else - _i8259_eoi(ctx.intn); - #endif /* CONFIG_APIC */ - return(0); } -- 2.47.3