Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 3 Jun 2009 21:56:29 +0000 (UTC)
From:      Kip Macy <kmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r193408 - user/kmacy/releng_7_2_fcs/sys/dev/cxgb
Message-ID:  <200906032156.n53LuTMb068245@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kmacy
Date: Wed Jun  3 21:56:29 2009
New Revision: 193408
URL: http://svn.freebsd.org/changeset/base/193408

Log:
  release interrupt resources without lock held - try to avoid races with initialization

Modified:
  user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_adapter.h
  user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_main.c

Modified: user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_adapter.h
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_adapter.h	Wed Jun  3 21:50:26 2009	(r193407)
+++ user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_adapter.h	Wed Jun  3 21:56:29 2009	(r193408)
@@ -129,6 +129,7 @@ enum {				/* adapter flags */
 	TP_PARITY_INIT  = (1 << 8),
 	INIT_IN_PROGRESS = (1 << 9),
 	INTR_INIT_DONE	= (1 << 10),
+	TEARDOWN_IN_PROGRESS = (1 << 11),
 };
 
 #define FL_Q_SIZE	4096

Modified: user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_main.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_main.c	Wed Jun  3 21:50:26 2009	(r193407)
+++ user/kmacy/releng_7_2_fcs/sys/dev/cxgb/cxgb_main.c	Wed Jun  3 21:56:29 2009	(r193408)
@@ -99,6 +99,7 @@ static void cxgb_tick_handler(void *, in
 static void cxgb_down_locked(struct adapter *sc);
 static void cxgb_tick(void *);
 static void setup_rss(adapter_t *sc);
+static void cxgb_release(struct adapter *sc);
 
 /* Attachment glue for the PCI controller end of the device.  Each port of
  * the device is attached separately, as defined later.
@@ -661,6 +662,7 @@ cxgb_free(struct adapter *sc)
  * drops the lock
  */
 	cxgb_down_locked(sc);
+	cxgb_release(sc);
 	
 #ifdef MSI_SUPPORTED
 	if (sc->flags & (USING_MSI | USING_MSIX)) {
@@ -1038,7 +1040,7 @@ cxgb_port_detach(device_t dev)
 	if (p->ifp->if_drv_flags & IFF_DRV_RUNNING) 
 		cxgb_stop_locked(p);
 	PORT_UNLOCK(p);
-	
+
 	ether_ifdetach(p->ifp);
 	printf("waiting for callout to stop ...");
 	DELAY(1000000);
@@ -1697,17 +1699,17 @@ cxgb_up(struct adapter *sc)
 	return (err);
 }
 
-
-/*
- * Release resources when all the ports and offloading have been stopped.
- */
 static void
-cxgb_down_locked(struct adapter *sc)
+cxgb_release(struct adapter *sc)
 {
+	ADAPTER_LOCK(sc);
+	if (sc->flags & TEARDOWN_IN_PROGRESS) {
+		ADAPTER_UNLOCK(sc);
+		return;
+	}
+	sc->flags |= TEARDOWN_IN_PROGRESS;
+	ADAPTER_UNLOCK(sc);
 	
-	t3_sge_stop(sc);
-	t3_intr_disable(sc);
-
 	if (sc->intr_tag != NULL) {
 		bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
 		sc->intr_tag = NULL;
@@ -1722,14 +1724,7 @@ cxgb_down_locked(struct adapter *sc)
 	
 	if (sc->flags & USING_MSIX) 
 		cxgb_teardown_msix(sc);
-	
-	callout_stop(&sc->cxgb_tick_ch);
-	callout_stop(&sc->sge_timer_ch);
-	ADAPTER_UNLOCK(sc);
 
-	callout_drain(&sc->cxgb_tick_ch);
-	callout_drain(&sc->sge_timer_ch);
-	
 	if (sc->tq != NULL) {
 		printf("draining slow intr\n");
 		taskqueue_drain(sc->tq, &sc->slow_intr_task);
@@ -1738,6 +1733,26 @@ cxgb_down_locked(struct adapter *sc)
 		printf("draining tick task\n");
 		taskqueue_drain(sc->tq, &sc->tick_task);
 	}
+	
+	ADAPTER_LOCK(sc);
+	sc->flags &= ~(TEARDOWN_IN_PROGRESS|INTR_INIT_DONE);
+	ADAPTER_UNLOCK(sc);
+}
+
+/*
+ * Release resources when all the ports and offloading have been stopped.
+ */
+static void
+cxgb_down_locked(struct adapter *sc)
+{
+	
+	t3_sge_stop(sc);
+	t3_intr_disable(sc);
+
+	callout_stop(&sc->cxgb_tick_ch);
+	callout_stop(&sc->sge_timer_ch);
+	ADAPTER_UNLOCK(sc);
+
 }
 
 static int
@@ -1855,6 +1870,10 @@ cxgb_intr_init(struct adapter *sc)
 	int err = 0;
 
 	ADAPTER_LOCK(sc);
+	if (sc->flags & (INIT_IN_PROGRESS|TEARDOWN_IN_PROGRESS)) {
+		ADAPTER_UNLOCK(sc);
+		return (EINPROGRESS);
+	}	
 	sc->flags |= INIT_IN_PROGRESS;
 	ADAPTER_UNLOCK(sc);
 
@@ -2100,10 +2119,12 @@ cxgb_ioctl(struct ifnet *ifp, unsigned l
 			} else
 				cxgb_init_locked(p);
 			p->if_flags = ifp->if_flags;
-		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			PORT_UNLOCK(p);
+		} else if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 			cxgb_stop_locked(p);
-				
-		PORT_UNLOCK(p);
+			PORT_UNLOCK(p);
+			cxgb_release(p->adapter);
+		}
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:



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