svn commit: r209068 - head/sys/dev/e1000

Jack F Vogel jfv at FreeBSD.org
Fri Jun 11 20:54:28 UTC 2010


Author: jfv
Date: Fri Jun 11 20:54:27 2010
New Revision: 209068
URL: http://svn.freebsd.org/changeset/base/209068

Log:
  Add a couple fixes from Michael Tuexen.
  Remove unneeded rxtx handler, make que handler generic.
  Do not allocate header mbufs in rx ring if not doing hdr split.
  Release the lock in rxeof call to stack.
  
  MFC for 8.1 asap

Modified:
  head/sys/dev/e1000/if_igb.c

Modified: head/sys/dev/e1000/if_igb.c
==============================================================================
--- head/sys/dev/e1000/if_igb.c	Fri Jun 11 20:38:20 2010	(r209067)
+++ head/sys/dev/e1000/if_igb.c	Fri Jun 11 20:54:27 2010	(r209068)
@@ -99,7 +99,7 @@ int	igb_display_debug_stats = 0;
 /*********************************************************************
  *  Driver version:
  *********************************************************************/
-char igb_driver_version[] = "version - 1.9.5";
+char igb_driver_version[] = "version - 1.9.6";
 
 
 /*********************************************************************
@@ -240,7 +240,6 @@ static void     igb_led_func(void *, int
 static int	igb_irq_fast(void *);
 static void	igb_add_rx_process_limit(struct adapter *, const char *,
 		    const char *, int *, int);
-static void	igb_handle_rxtx(void *context, int pending);
 static void	igb_handle_que(void *context, int pending);
 static void	igb_handle_link(void *context, int pending);
 
@@ -818,21 +817,25 @@ igb_start(struct ifnet *ifp)
 static int
 igb_mq_start(struct ifnet *ifp, struct mbuf *m)
 {
-	struct adapter	*adapter = ifp->if_softc;
-	struct tx_ring	*txr;
-	int 		i = 0, err = 0;
+	struct adapter		*adapter = ifp->if_softc;
+	struct igb_queue	*que;
+	struct tx_ring		*txr;
+	int 			i = 0, err = 0;
 
 	/* Which queue to use */
 	if ((m->m_flags & M_FLOWID) != 0)
 		i = m->m_pkthdr.flowid % adapter->num_queues;
 
 	txr = &adapter->tx_rings[i];
+	que = &adapter->queues[i];
 
 	if (IGB_TX_TRYLOCK(txr)) {
 		err = igb_mq_start_locked(ifp, txr, m);
 		IGB_TX_UNLOCK(txr);
-	} else
+	} else {
 		err = drbr_enqueue(ifp, txr->br, m);
+		taskqueue_enqueue(que->tq, &que->que_task);
+	}
 
 	return (err);
 }
@@ -1225,35 +1228,6 @@ igb_init(void *arg)
 
 
 static void
-igb_handle_rxtx(void *context, int pending)
-{
-	struct igb_queue	*que = context;
-	struct adapter		*adapter = que->adapter;
-	struct tx_ring		*txr = adapter->tx_rings;
-	struct ifnet		*ifp;
-
-	ifp = adapter->ifp;
-
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		if (igb_rxeof(que, adapter->rx_process_limit))
-			taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
-		IGB_TX_LOCK(txr);
-		igb_txeof(txr);
-
-#if __FreeBSD_version >= 800000
-		if (!drbr_empty(ifp, txr->br))
-			igb_mq_start_locked(ifp, txr, NULL);
-#else
-		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-			igb_start_locked(txr, ifp);
-#endif
-		IGB_TX_UNLOCK(txr);
-	}
-
-	igb_enable_intr(adapter);
-}
-
-static void
 igb_handle_que(void *context, int pending)
 {
 	struct igb_queue *que = context;
@@ -1268,7 +1242,8 @@ igb_handle_que(void *context, int pendin
 		IGB_TX_LOCK(txr);
 		igb_txeof(txr);
 #if __FreeBSD_version >= 800000
-		igb_mq_start_locked(ifp, txr, NULL);
+		if (!drbr_empty(ifp, txr->br))
+			igb_mq_start_locked(ifp, txr, NULL);
 #else
 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 			igb_start_locked(txr, ifp);
@@ -1280,11 +1255,15 @@ igb_handle_que(void *context, int pendin
 		}
 	}
 
-	/* Reenable this interrupt */
 #ifdef DEVICE_POLLING
-	if (!(ifp->if_capenable & IFCAP_POLLING))
+	if (ifp->if_capenable & IFCAP_POLLING)
+		return;
 #endif
-	E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims);
+	/* Reenable this interrupt */
+	if (que->eims)
+		E1000_WRITE_REG(&adapter->hw, E1000_EIMS, que->eims);
+	else
+		igb_enable_intr(adapter);
 }
 
 /* Deal with link in a sleepable context */
@@ -1923,11 +1902,6 @@ igb_local_timer(void *arg)
 			goto timeout;
 	}
 
-	/* Trigger an RX interrupt on all queues */
-#ifdef DEVICE_POLLING
-	if (!(ifp->if_capenable & IFCAP_POLLING))
-#endif
-	E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->rx_mask);
 	callout_reset(&adapter->timer, hz, igb_local_timer, adapter);
 	return;
 
@@ -2142,7 +2116,7 @@ igb_allocate_legacy(struct adapter *adap
 	 * Try allocating a fast interrupt and the associated deferred
 	 * processing contexts.
 	 */
-	TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, que);
+	TASK_INIT(&adapter->rxtx_task, 0, igb_handle_que, que);
 	/* Make tasklet for deferred link handling */
 	TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
 	adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT,
@@ -2194,7 +2168,6 @@ igb_allocate_msix(struct adapter *adapte
 			device_printf(dev, "Failed to register Queue handler");
 			return (error);
 		}
-		bus_describe_intr(dev, que->res, que->tag, "que %d", i);
 		que->msix = vector;
 		if (adapter->hw.mac.type == e1000_82575)
 			que->eims = E1000_EICR_TX_QUEUE0 << i;
@@ -2230,7 +2203,6 @@ igb_allocate_msix(struct adapter *adapte
 		device_printf(dev, "Failed to register Link handler");
 		return (error);
 	}
-	bus_describe_intr(dev, adapter->res, adapter->tag, "link");
 	adapter->linkvec = vector;
 
 	/* Make tasklet for deferred handling */
@@ -3572,7 +3544,7 @@ igb_refresh_mbufs(struct rx_ring *rxr, i
 	cleaned = -1; /* Signify no completions */
 	while (i != limit) {
 		rxbuf = &rxr->rx_buffers[i];
-		if (rxbuf->m_head == NULL) {
+		if ((rxbuf->m_head == NULL) && (rxr->hdr_split)) {
 			mh = m_gethdr(M_DONTWAIT, MT_DATA);
 			if (mh == NULL)
 				goto update;
@@ -3778,16 +3750,24 @@ igb_setup_receive_ring(struct rx_ring *r
 	*/
 	igb_free_receive_ring(rxr);
 
+	/* Configure for header split? */
+	if (igb_header_split)
+		rxr->hdr_split = TRUE;
+
         /* Now replenish the ring mbufs */
 	for (int j = 0; j != adapter->num_rx_desc; ++j) {
 		struct mbuf	*mh, *mp;
 
 		rxbuf = &rxr->rx_buffers[j];
+		if (rxr->hdr_split == FALSE)
+			goto skip_head;
 
 		/* First the header */
 		rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA);
-		if (rxbuf->m_head == NULL)
+		if (rxbuf->m_head == NULL) {
+			error = ENOBUFS;
                         goto fail;
+		}
 		m_adj(rxbuf->m_head, ETHER_ALIGN);
 		mh = rxbuf->m_head;
 		mh->m_len = mh->m_pkthdr.len = MHLEN;
@@ -3803,11 +3783,14 @@ igb_setup_receive_ring(struct rx_ring *r
 		/* Update descriptor */
 		rxr->rx_base[j].read.hdr_addr = htole64(hseg[0].ds_addr);
 
+skip_head:
 		/* Now the payload cluster */
 		rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA,
 		    M_PKTHDR, adapter->rx_mbuf_sz);
-		if (rxbuf->m_pack == NULL)
+		if (rxbuf->m_pack == NULL) {
+			error = ENOBUFS;
                         goto fail;
+		}
 		mp = rxbuf->m_pack;
 		mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
 		/* Get the memory mapping */
@@ -3826,11 +3809,8 @@ igb_setup_receive_ring(struct rx_ring *r
 	rxr->next_to_check = 0;
 	rxr->next_to_refresh = 0;
 	rxr->lro_enabled = FALSE;
-
-	if (igb_header_split)
-		rxr->hdr_split = TRUE;
-	else
-		ifp->if_capabilities &= ~IFCAP_LRO;
+	rxr->rx_split_packets = 0;
+	rxr->rx_bytes = 0;
 
 	rxr->fmp = NULL;
 	rxr->lmp = NULL;
@@ -3874,7 +3854,7 @@ static int
 igb_setup_receive_structures(struct adapter *adapter)
 {
 	struct rx_ring *rxr = adapter->rx_rings;
-	int i, j;
+	int i;
 
 	for (i = 0; i < adapter->num_queues; i++, rxr++)
 		if (igb_setup_receive_ring(rxr))
@@ -3885,13 +3865,11 @@ fail:
 	/*
 	 * Free RX buffers allocated so far, we will only handle
 	 * the rings that completed, the failing case will have
-	 * cleaned up for itself. The value of 'i' will be the
-	 * failed ring so we must pre-decrement it.
+	 * cleaned up for itself. 'i' is the endpoint.
 	 */
-	rxr = adapter->rx_rings;
-	for (--i; i > 0; i--, rxr++) {
-		for (j = 0; j < adapter->num_rx_desc; j++)
-			igb_free_receive_ring(rxr);
+	for (int j = 0; j > i; ++j) {
+		rxr = &adapter->rx_rings[i];
+		igb_free_receive_ring(rxr);
 	}
 
 	return (ENOBUFS);
@@ -4197,7 +4175,9 @@ igb_rx_input(struct rx_ring *rxr, struct
 			if (tcp_lro_rx(&rxr->lro, m, 0) == 0)
 				return;
 	}
+	IGB_RX_UNLOCK(rxr);
 	(*ifp->if_input)(ifp, m);
+	IGB_RX_LOCK(rxr);
 }
 
 /*********************************************************************
@@ -4368,8 +4348,11 @@ next_desc:
 		/*
 		** Send to the stack or LRO
 		*/
-		if (sendmp != NULL)
+		if (sendmp != NULL) {
+			rxr->next_to_check = i;
 			igb_rx_input(rxr, ifp, sendmp, ptype);
+			i = rxr->next_to_check;
+		}
 
 		/* Every 8 descriptors we go to refresh mbufs */
 		if (processed == 8) {
@@ -4838,19 +4821,14 @@ igb_print_debug_info(struct adapter *ada
 	    adapter->hw.fc.high_water,
 	    adapter->hw.fc.low_water);
 
-	for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
+	for (int i = 0; i < adapter->num_queues; i++, txr++) {
 		device_printf(dev, "Queue(%d) tdh = %d, tdt = %d  ", i,
 		    E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
 		    E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
-		device_printf(dev, "rdh = %d, rdt = %d\n",
-		    E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
-		    E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
-		device_printf(dev, "TX(%d) no descriptors avail event = %lld\n",
+		device_printf(dev, "TX(%d) no descriptors = %lld\n",
 		    txr->me, (long long)txr->no_desc_avail);
 		device_printf(dev, "TX(%d) Packets sent = %lld\n",
 		    txr->me, (long long)txr->tx_packets);
-		device_printf(dev, "RX(%d) Packets received = %lld  ",
-		    rxr->me, (long long)rxr->rx_packets);
 	}
 
 	for (int i = 0; i < adapter->num_queues; i++, rxr++) {
@@ -4870,7 +4848,7 @@ igb_print_debug_info(struct adapter *ada
 	}
 
 	for (int i = 0; i < adapter->num_queues; i++, que++)
-		device_printf(dev,"QUE(%d) IRQs = %llx\n",
+		device_printf(dev,"QUE(%d) IRQs = %lld\n",
 		    i, (long long)que->irqs);
 
 	device_printf(dev, "LINK MSIX IRQ Handled = %u\n", adapter->link_irq);


More information about the svn-src-all mailing list