From owner-svn-src-all@freebsd.org  Wed Nov 18 18:09:50 2015
Return-Path: <owner-svn-src-all@freebsd.org>
Delivered-To: svn-src-all@mailman.ysv.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org
 [IPv6:2001:1900:2254:206a::19:1])
 by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7C02EA317D9;
 Wed, 18 Nov 2015 18:09:50 +0000 (UTC)
 (envelope-from royger@FreeBSD.org)
Received: from repo.freebsd.org (repo.freebsd.org
 [IPv6:2610:1c1:1:6068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id 4706F10C4;
 Wed, 18 Nov 2015 18:09:50 +0000 (UTC)
 (envelope-from royger@FreeBSD.org)
Received: from repo.freebsd.org ([127.0.1.37])
 by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tAII9ndA009906;
 Wed, 18 Nov 2015 18:09:49 GMT (envelope-from royger@FreeBSD.org)
Received: (from royger@localhost)
 by repo.freebsd.org (8.15.2/8.15.2/Submit) id tAII9nHD009905;
 Wed, 18 Nov 2015 18:09:49 GMT (envelope-from royger@FreeBSD.org)
Message-Id: <201511181809.tAII9nHD009905@repo.freebsd.org>
X-Authentication-Warning: repo.freebsd.org: royger set sender to
 royger@FreeBSD.org using -f
From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= <royger@FreeBSD.org>
Date: Wed, 18 Nov 2015 18:09:49 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-all@freebsd.org,
 svn-src-head@freebsd.org
Subject: svn commit: r291022 - head/sys/x86/x86
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-all@freebsd.org
X-Mailman-Version: 2.1.20
Precedence: list
List-Id: "SVN commit messages for the entire src tree \(except for &quot;
 user&quot; and &quot; projects&quot; \)" <svn-src-all.freebsd.org>
List-Unsubscribe: <https://lists.freebsd.org/mailman/options/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-all/>
List-Post: <mailto:svn-src-all@freebsd.org>
List-Help: <mailto:svn-src-all-request@freebsd.org?subject=help>
List-Subscribe: <https://lists.freebsd.org/mailman/listinfo/svn-src-all>,
 <mailto:svn-src-all-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Wed, 18 Nov 2015 18:09:50 -0000

Author: royger
Date: Wed Nov 18 18:09:49 2015
New Revision: 291022
URL: https://svnweb.freebsd.org/changeset/base/291022

Log:
  x86/intr: allow mutex recursion in intr_remove_handler
  
  This is needed so interrupt handlers can be removed while the PIC is
  resuming, it was previously not possible due to intr_resume holding the
  intr_table_lock and intr_remove_handler recursing on it.
  
  Sponsored by:		Citrix Systems R&D
  Reviewed by:		kib (previous version)
  MFC after:		2 weeks
  Differential Revision:	https://reviews.freebsd.org/D4114

Modified:
  head/sys/x86/x86/intr_machdep.c

Modified: head/sys/x86/x86/intr_machdep.c
==============================================================================
--- head/sys/x86/x86/intr_machdep.c	Wed Nov 18 17:52:38 2015	(r291021)
+++ head/sys/x86/x86/intr_machdep.c	Wed Nov 18 18:09:49 2015	(r291022)
@@ -197,19 +197,28 @@ int
 intr_remove_handler(void *cookie)
 {
 	struct intsrc *isrc;
-	int error;
+	int error, mtx_owned;
 
 	isrc = intr_handler_source(cookie);
 	error = intr_event_remove_handler(cookie);
 	if (error == 0) {
-		mtx_lock(&intr_table_lock);
+		/*
+		 * Recursion is needed here so PICs can remove interrupts
+		 * while resuming. It was previously not possible due to
+		 * intr_resume holding the intr_table_lock and
+		 * intr_remove_handler recursing on it.
+		 */
+		mtx_owned = mtx_owned(&intr_table_lock);
+		if (mtx_owned == 0)
+			mtx_lock(&intr_table_lock);
 		isrc->is_handlers--;
 		if (isrc->is_handlers == 0) {
 			isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI);
 			isrc->is_pic->pic_disable_intr(isrc);
 		}
 		intrcnt_updatename(isrc);
-		mtx_unlock(&intr_table_lock);
+		if (mtx_owned == 0)
+			mtx_unlock(&intr_table_lock);
 	}
 	return (error);
 }