From owner-svn-src-all@FreeBSD.ORG Mon Aug 20 15:19:35 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6919E106566B; Mon, 20 Aug 2012 15:19:35 +0000 (UTC) (envelope-from kan@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 53B658FC0C; Mon, 20 Aug 2012 15:19:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q7KFJZbl052653; Mon, 20 Aug 2012 15:19:35 GMT (envelope-from kan@svn.freebsd.org) Received: (from kan@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7KFJZp3052651; Mon, 20 Aug 2012 15:19:35 GMT (envelope-from kan@svn.freebsd.org) Message-Id: <201208201519.q7KFJZp3052651@svn.freebsd.org> From: Alexander Kabaev Date: Mon, 20 Aug 2012 15:19:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239437 - releng/9.1/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Aug 2012 15:19:35 -0000 Author: kan Date: Mon Aug 20 15:19:34 2012 New Revision: 239437 URL: http://svn.freebsd.org/changeset/base/239437 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. Approved by: re (kib) Reviewed by: jhb Modified: releng/9.1/sys/kern/kern_intr.c Directory Properties: releng/9.1/sys/ (props changed) Modified: releng/9.1/sys/kern/kern_intr.c ============================================================================== --- releng/9.1/sys/kern/kern_intr.c Mon Aug 20 15:16:43 2012 (r239436) +++ releng/9.1/sys/kern/kern_intr.c Mon Aug 20 15:19:34 2012 (r239437) @@ -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);