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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to