Date: Wed, 14 Apr 2010 20:55:33 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r206629 - head/sys/dev/e1000 Message-ID: <201004142055.o3EKtXpp084756@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Wed Apr 14 20:55:33 2010 New Revision: 206629 URL: http://svn.freebsd.org/changeset/base/206629 Log: Add a missing fragment in the tx msix handler to invoke another if all work is not done. Sync the igb driver with changes suggested by yongari and made in em, these made sense to be in both drivers. Modified: head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_igb.c Modified: head/sys/dev/e1000/if_em.c ============================================================================== --- head/sys/dev/e1000/if_em.c Wed Apr 14 20:54:23 2010 (r206628) +++ head/sys/dev/e1000/if_em.c Wed Apr 14 20:55:33 2010 (r206629) @@ -93,7 +93,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.0.4"; +char em_driver_version[] = "7.0.5"; /********************************************************************* @@ -1484,12 +1484,17 @@ em_msix_tx(void *arg) { struct tx_ring *txr = arg; struct adapter *adapter = txr->adapter; + bool more; ++txr->tx_irq; EM_TX_LOCK(txr); - em_txeof(txr); + more = em_txeof(txr); EM_TX_UNLOCK(txr); - E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); + if (more) + taskqueue_enqueue(txr->tq, &txr->tx_task); + else + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); return; } Modified: head/sys/dev/e1000/if_igb.c ============================================================================== --- head/sys/dev/e1000/if_igb.c Wed Apr 14 20:54:23 2010 (r206628) +++ head/sys/dev/e1000/if_igb.c Wed Apr 14 20:55:33 2010 (r206629) @@ -99,7 +99,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 1.9.4"; +char igb_driver_version[] = "version - 1.9.5"; /********************************************************************* @@ -758,8 +758,15 @@ igb_start_locked(struct tx_ring *txr, st if (!adapter->link_active) return; - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + /* Call cleanup if number of TX descriptors low */ + if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) + igb_txeof(txr); + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -779,6 +786,7 @@ igb_start_locked(struct tx_ring *txr, st ETHER_BPF_MTAP(ifp, m_head); /* Set watchdog on */ + txr->watchdog_time = ticks; txr->watchdog_check = TRUE; } } @@ -817,8 +825,6 @@ igb_mq_start(struct ifnet *ifp, struct m /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; - else - i = curcpu % adapter->num_queues; txr = &adapter->tx_rings[i]; @@ -847,6 +853,10 @@ igb_mq_start_locked(struct ifnet *ifp, s return (err); } + /* Call cleanup if number of TX descriptors low */ + if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) + igb_txeof(txr); + enq = 0; if (m == NULL) { next = drbr_dequeue(ifp, txr->br); @@ -856,6 +866,7 @@ igb_mq_start_locked(struct ifnet *ifp, s next = drbr_dequeue(ifp, txr->br); } else next = m; + /* Process the queue */ while (next != NULL) { if ((err = igb_xmit(txr, &next)) != 0) { @@ -877,6 +888,7 @@ igb_mq_start_locked(struct ifnet *ifp, s if (enq > 0) { /* Set the watchdog */ txr->watchdog_check = TRUE; + txr->watchdog_time = ticks; } return (err); } @@ -1248,19 +1260,13 @@ igb_handle_que(void *context, int pendin struct adapter *adapter = que->adapter; struct tx_ring *txr = que->txr; struct ifnet *ifp = adapter->ifp; - u32 loop = IGB_MAX_LOOP; bool more; - /* RX first */ - do { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { more = igb_rxeof(que, -1); - } while (loop-- && more); - if (IGB_TX_TRYLOCK(txr)) { - loop = IGB_MAX_LOOP; - do { - more = igb_txeof(txr); - } while (loop-- && more); + IGB_TX_LOCK(txr); + igb_txeof(txr); #if __FreeBSD_version >= 800000 igb_mq_start_locked(ifp, txr, NULL); #else @@ -1268,6 +1274,10 @@ igb_handle_que(void *context, int pendin igb_start_locked(txr, ifp); #endif IGB_TX_UNLOCK(txr); + if (more) { + taskqueue_enqueue(que->tq, &que->que_task); + return; + } } /* Reenable this interrupt */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004142055.o3EKtXpp084756>