Place interrupt handling in a critical section and remove double
counting in incrementing the interrupt nesting level. This fixes a number of bugs in which the interrupt thread could be preempted by an IPI, indefinitely delaying acknowledgement of the interrupt to the PIC, causing interrupt starvation and hangs. Reported by: linimon Reviewed by: marcel, jhb MFC after: 1 week
This commit is contained in:
parent
93013817b0
commit
3f119cd4f7
@ -80,15 +80,17 @@ powerpc_interrupt(struct trapframe *framep)
|
||||
|
||||
switch (framep->exc) {
|
||||
case EXC_EXI:
|
||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||
critical_enter();
|
||||
PIC_DISPATCH(pic, framep);
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
critical_exit();
|
||||
break;
|
||||
|
||||
case EXC_DECR:
|
||||
critical_enter();
|
||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||
decr_intr(framep);
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
critical_exit();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -118,9 +118,11 @@ powerpc_decr_interrupt(struct trapframe *framep)
|
||||
struct thread *td;
|
||||
|
||||
td = PCPU_GET(curthread);
|
||||
critical_enter();
|
||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||
decr_intr(framep);
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
critical_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,10 +131,8 @@ powerpc_decr_interrupt(struct trapframe *framep)
|
||||
void
|
||||
powerpc_extr_interrupt(struct trapframe *framep)
|
||||
{
|
||||
struct thread *td;
|
||||
|
||||
td = PCPU_GET(curthread);
|
||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||
critical_enter();
|
||||
PIC_DISPATCH(pic, framep);
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
critical_exit();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user