Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Mar 2010 02:00:54 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r204903 - in head/sys/powerpc: aim booke
Message-ID:  <201003090200.o2920soQ073256@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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();
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003090200.o2920soQ073256>