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-head mailing list