Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Jan 2011 14:42:43 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r217353 - head/sys/dev/jme
Message-ID:  <201101131442.p0DEghL6053778@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Jan 13 14:42:43 2011
New Revision: 217353
URL: http://svn.freebsd.org/changeset/base/217353

Log:
  - Add a locked variant of jme_start() and invoke it directly while holding
    the lock instead of queueing it to a task.
  - Do not invoke jme_rxintr() to reclaim any unprocessed but received
    packets when shutting down the interface.  Instead, just drop these
    packets to match the behavior of other drivers.
  - Hold the driver lock in the interrupt handler to avoid races with
    ioctl requests to down the interface.
  
  Reviewed by:	yongari

Modified:
  head/sys/dev/jme/if_jme.c
  head/sys/dev/jme/if_jmevar.h

Modified: head/sys/dev/jme/if_jme.c
==============================================================================
--- head/sys/dev/jme/if_jme.c	Thu Jan 13 14:41:58 2011	(r217352)
+++ head/sys/dev/jme/if_jme.c	Thu Jan 13 14:42:43 2011	(r217353)
@@ -126,8 +126,8 @@ static void jme_setwol(struct jme_softc 
 static int jme_suspend(device_t);
 static int jme_resume(device_t);
 static int jme_encap(struct jme_softc *, struct mbuf **);
-static void jme_tx_task(void *, int);
 static void jme_start(struct ifnet *);
+static void jme_start_locked(struct ifnet *);
 static void jme_watchdog(struct jme_softc *);
 static int jme_ioctl(struct ifnet *, u_long, caddr_t);
 static void jme_mac_config(struct jme_softc *);
@@ -882,7 +882,6 @@ jme_attach(device_t dev)
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
 
 	/* Create local taskq. */
-	TASK_INIT(&sc->jme_tx_task, 1, jme_tx_task, ifp);
 	sc->jme_tq = taskqueue_create_fast("jme_taskq", M_WAITOK,
 	    taskqueue_thread_enqueue, &sc->jme_tq);
 	if (sc->jme_tq == NULL) {
@@ -934,7 +933,6 @@ jme_detach(device_t dev)
 		JME_UNLOCK(sc);
 		callout_drain(&sc->jme_tick_ch);
 		taskqueue_drain(sc->jme_tq, &sc->jme_int_task);
-		taskqueue_drain(sc->jme_tq, &sc->jme_tx_task);
 		taskqueue_drain(taskqueue_swi, &sc->jme_link_task);
 		/* Restore possibly modified station address. */
 		if ((sc->jme_flags & JME_FLAG_EFUSE) != 0)
@@ -1872,16 +1870,18 @@ jme_encap(struct jme_softc *sc, struct m
 }
 
 static void
-jme_tx_task(void *arg, int pending)
+jme_start(struct ifnet *ifp)
 {
-	struct ifnet *ifp;
+        struct jme_softc *sc;
 
-	ifp = (struct ifnet *)arg;
-	jme_start(ifp);
+	sc = ifp->if_softc;
+	JME_LOCK(sc);
+	jme_start_locked(ifp);
+	JME_UNLOCK(sc);
 }
 
 static void
-jme_start(struct ifnet *ifp)
+jme_start_locked(struct ifnet *ifp)
 {
         struct jme_softc *sc;
         struct mbuf *m_head;
@@ -1889,16 +1889,14 @@ jme_start(struct ifnet *ifp)
 
 	sc = ifp->if_softc;
 
-	JME_LOCK(sc);
+	JME_LOCK_ASSERT(sc);
 
 	if (sc->jme_cdata.jme_tx_cnt >= JME_TX_DESC_HIWAT)
 		jme_txeof(sc);
 
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
-	    IFF_DRV_RUNNING || (sc->jme_flags & JME_FLAG_LINK) == 0) {
-		JME_UNLOCK(sc);
+	    IFF_DRV_RUNNING || (sc->jme_flags & JME_FLAG_LINK) == 0)
 		return;
-	}
 
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -1937,8 +1935,6 @@ jme_start(struct ifnet *ifp)
 		/* Set a timeout in case the chip goes out to lunch. */
 		sc->jme_watchdog_timer = JME_TX_TIMEOUT;
 	}
-
-	JME_UNLOCK(sc);
 }
 
 static void
@@ -1964,7 +1960,7 @@ jme_watchdog(struct jme_softc *sc)
 		if_printf(sc->jme_ifp,
 		    "watchdog timeout (missed Tx interrupts) -- recovering\n");
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->jme_tq, &sc->jme_tx_task);
+			jme_start_locked(ifp);
 		return;
 	}
 
@@ -1973,7 +1969,7 @@ jme_watchdog(struct jme_softc *sc)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	jme_init_locked(sc);
 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		taskqueue_enqueue(sc->jme_tq, &sc->jme_tx_task);
+		jme_start_locked(ifp);
 }
 
 static int
@@ -2267,10 +2263,8 @@ jme_link_task(void *arg, int pending)
 	/* XXX Drain all queued tasks. */
 	JME_UNLOCK(sc);
 	taskqueue_drain(sc->jme_tq, &sc->jme_int_task);
-	taskqueue_drain(sc->jme_tq, &sc->jme_tx_task);
 	JME_LOCK(sc);
 
-	jme_rxintr(sc, JME_RX_RING_CNT);
 	if (sc->jme_cdata.jme_rxhead != NULL)
 		m_freem(sc->jme_cdata.jme_rxhead);
 	JME_RXCHAIN_RESET(sc);
@@ -2297,7 +2291,7 @@ jme_link_task(void *arg, int pending)
 
 	/*
 	 * Reuse configured Rx descriptors and reset
-	 * procuder/consumer index.
+	 * producer/consumer index.
 	 */
 	sc->jme_cdata.jme_rx_cons = 0;
 	sc->jme_morework = 0;
@@ -2376,6 +2370,7 @@ jme_int_task(void *arg, int pending)
 	sc = (struct jme_softc *)arg;
 	ifp = sc->jme_ifp;
 
+	JME_LOCK(sc);
 	status = CSR_READ_4(sc, JME_INTR_STATUS);
 	if (sc->jme_morework != 0) {
 		sc->jme_morework = 0;
@@ -2410,19 +2405,18 @@ jme_int_task(void *arg, int pending)
 			CSR_WRITE_4(sc, JME_RXCSR, sc->jme_rxcsr |
 			    RXCSR_RX_ENB | RXCSR_RXQ_START);
 		}
-		/*
-		 * Reclaiming Tx buffers are deferred to make jme(4) run
-		 * without locks held.
-		 */
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			taskqueue_enqueue(sc->jme_tq, &sc->jme_tx_task);
+			jme_start_locked(ifp);
 	}
 
 	if (more != 0 || (CSR_READ_4(sc, JME_INTR_STATUS) & JME_INTRS) != 0) {
 		taskqueue_enqueue(sc->jme_tq, &sc->jme_int_task);
+		JME_UNLOCK(sc);
 		return;
 	}
 done:
+	JME_UNLOCK(sc);
+
 	/* Reenable interrupts. */
 	CSR_WRITE_4(sc, JME_INTR_MASK_SET, JME_INTRS);
 }
@@ -2524,6 +2518,8 @@ jme_rxeof(struct jme_softc *sc)
 	uint32_t flags, status;
 	int cons, count, nsegs;
 
+	JME_LOCK_ASSERT(sc);
+
 	ifp = sc->jme_ifp;
 
 	cons = sc->jme_cdata.jme_rx_cons;
@@ -2635,7 +2631,9 @@ jme_rxeof(struct jme_softc *sc)
 
 			ifp->if_ipackets++;
 			/* Pass it on. */
+			JME_UNLOCK(sc);
 			(*ifp->if_input)(ifp, m);
+			JME_LOCK(sc);
 
 			/* Reset mbuf chains. */
 			JME_RXCHAIN_RESET(sc);

Modified: head/sys/dev/jme/if_jmevar.h
==============================================================================
--- head/sys/dev/jme/if_jmevar.h	Thu Jan 13 14:41:58 2011	(r217352)
+++ head/sys/dev/jme/if_jmevar.h	Thu Jan 13 14:42:43 2011	(r217353)
@@ -221,7 +221,6 @@ struct jme_softc {
 	volatile int		jme_morework;
 
 	struct task		jme_int_task;
-	struct task		jme_tx_task;
 	struct task		jme_link_task;
 	struct taskqueue	*jme_tq;
 	struct mtx		jme_mtx;



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