Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Aug 2012 15:16:43 +0000 (UTC)
From:      Alexander Kabaev <kan@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r239436 - stable/9/sys/kern
Message-ID:  <201208201516.q7KFGhmQ052298@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kan
Date: Mon Aug 20 15:16:43 2012
New Revision: 239436
URL: http://svn.freebsd.org/changeset/base/239436

Log:
  MFC r239095: Do not add handler to event handlers list until ithread
  is created.
  
  In rare event when fast and ithread interrupts share the same vector
  and the fast handler was registered first, we can end up trying to
  schedule the ithread that is not created yet. The kernel built with
  INVARIANTS then triggers an assertion.
  
  Change the order to create the ithread first and only then add the
  handler that needs it to the interrupt event handlers list.
  
  Reviewed by: jhb

Modified:
  stable/9/sys/kern/kern_intr.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/kern_intr.c
==============================================================================
--- stable/9/sys/kern/kern_intr.c	Mon Aug 20 15:08:22 2012	(r239435)
+++ stable/9/sys/kern/kern_intr.c	Mon Aug 20 15:16:43 2012	(r239436)
@@ -545,17 +545,6 @@ intr_event_add_handler(struct intr_event
 		}
 	}
 
-	/* Add the new handler to the event in priority order. */
-	TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
-		if (temp_ih->ih_pri > ih->ih_pri)
-			break;
-	}
-	if (temp_ih == NULL)
-		TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
-	else
-		TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
-	intr_event_update(ie);
-
 	/* Create a thread if we need one. */
 	while (ie->ie_thread == NULL && handler != NULL) {
 		if (ie->ie_flags & IE_ADDING_THREAD)
@@ -572,6 +561,18 @@ intr_event_add_handler(struct intr_event
 			wakeup(ie);
 		}
 	}
+
+	/* Add the new handler to the event in priority order. */
+	TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
+		if (temp_ih->ih_pri > ih->ih_pri)
+			break;
+	}
+	if (temp_ih == NULL)
+		TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
+	else
+		TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
+	intr_event_update(ie);
+
 	CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
 	    ie->ie_name);
 	mtx_unlock(&ie->ie_lock);
@@ -618,23 +619,12 @@ intr_event_add_handler(struct intr_event
 		}
 	}
 
-	/* Add the new handler to the event in priority order. */
-	TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
-		if (temp_ih->ih_pri > ih->ih_pri)
-			break;
-	}
-	if (temp_ih == NULL)
-		TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
-	else
-		TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
-	intr_event_update(ie);
-
 	/* For filtered handlers, create a private ithread to run on. */
-	if (filter != NULL && handler != NULL) { 
+	if (filter != NULL && handler != NULL) {
 		mtx_unlock(&ie->ie_lock);
-		it = ithread_create("intr: newborn", ih);		
+		it = ithread_create("intr: newborn", ih);
 		mtx_lock(&ie->ie_lock);
-		it->it_event = ie; 
+		it->it_event = ie;
 		ih->ih_thread = it;
 		ithread_update(it); // XXX - do we really need this?!?!?
 	} else { /* Create the global per-event thread if we need one. */
@@ -654,6 +644,18 @@ intr_event_add_handler(struct intr_event
 			}
 		}
 	}
+
+	/* Add the new handler to the event in priority order. */
+	TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
+		if (temp_ih->ih_pri > ih->ih_pri)
+			break;
+	}
+	if (temp_ih == NULL)
+		TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
+	else
+		TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
+	intr_event_update(ie);
+
 	CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
 	    ie->ie_name);
 	mtx_unlock(&ie->ie_lock);



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