svn commit: r206629 - head/sys/dev/e1000
Jack F Vogel
jfv at FreeBSD.org
Wed Apr 14 20:55:33 UTC 2010
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 */
More information about the svn-src-all
mailing list