svn commit: r204903 - in head/sys/powerpc: aim booke
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Tue Mar 9 02:00:54 UTC 2010
Author: nwhitehorn
Date: Tue Mar 9 02:00:53 2010
New Revision: 204903
URL: http://svn.freebsd.org/changeset/base/204903
Log:
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
Modified:
head/sys/powerpc/aim/interrupt.c
head/sys/powerpc/booke/interrupt.c
Modified: head/sys/powerpc/aim/interrupt.c
==============================================================================
--- head/sys/powerpc/aim/interrupt.c Tue Mar 9 01:11:45 2010 (r204902)
+++ head/sys/powerpc/aim/interrupt.c Tue Mar 9 02:00:53 2010 (r204903)
@@ -80,15 +80,17 @@ powerpc_interrupt(struct trapframe *fram
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:
Modified: head/sys/powerpc/booke/interrupt.c
==============================================================================
--- head/sys/powerpc/booke/interrupt.c Tue Mar 9 01:11:45 2010 (r204902)
+++ head/sys/powerpc/booke/interrupt.c Tue Mar 9 02:00:53 2010 (r204903)
@@ -118,9 +118,11 @@ powerpc_decr_interrupt(struct trapframe
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
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();
}
More information about the svn-src-all
mailing list