On Tuesday, September 25, 2012 4:19:01 pm Vijay Singh wrote:
> > Vijay, can you test this to see if it helps with your test case?
> >
> >> Jack
> 
> John, apologies for the delay. I have some data to share now.
> 
> With your patch, the transmit side lock contention is all gone.
> However I still see receive side contention. I have MSI/X enabled,
> with one hw queue per-port.

Well, that's progress at least.  Jack, can you ok this patch?  It is just the 
changes to adjust the deferred tx handling and doesn't include any watchdog 
changes.  The igb fix is just a comestic nit:

Index: dev/e1000/if_igb.h
===================================================================
--- dev/e1000/if_igb.h  (revision 240960)
+++ dev/e1000/if_igb.h  (working copy)
@@ -299,9 +299,9 @@
        struct igb_tx_buffer    *tx_buffers;
 #if __FreeBSD_version >= 800000
        struct buf_ring         *br;
+       struct task             txq_task;
 #endif
        bus_dma_tag_t           txtag;
-       struct task             txq_task;
 
        u32                     bytes;
        u32                     packets;
Index: dev/ixgbe/ixgbe.c
===================================================================
--- dev/ixgbe/ixgbe.c   (revision 240960)
+++ dev/ixgbe/ixgbe.c   (working copy)
@@ -104,13 +104,15 @@
 static int      ixgbe_attach(device_t);
 static int      ixgbe_detach(device_t);
 static int      ixgbe_shutdown(device_t);
-static void     ixgbe_start(struct ifnet *);
-static void     ixgbe_start_locked(struct tx_ring *, struct ifnet *);
 #if __FreeBSD_version >= 800000
 static int     ixgbe_mq_start(struct ifnet *, struct mbuf *);
 static int     ixgbe_mq_start_locked(struct ifnet *,
                     struct tx_ring *, struct mbuf *);
 static void    ixgbe_qflush(struct ifnet *);
+static void    ixgbe_deferred_mq_start(void *, int);
+#else
+static void     ixgbe_start(struct ifnet *);
+static void     ixgbe_start_locked(struct tx_ring *, struct ifnet *);
 #endif
 static int      ixgbe_ioctl(struct ifnet *, u_long, caddr_t);
 static void    ixgbe_init(void *);
@@ -631,6 +633,7 @@
 {
        struct adapter *adapter = device_get_softc(dev);
        struct ix_queue *que = adapter->queues;
+       struct tx_ring *txr = adapter->tx_rings;
        u32     ctrl_ext;
 
        INIT_DEBUGOUT("ixgbe_detach: begin");
@@ -645,8 +648,11 @@
        ixgbe_stop(adapter);
        IXGBE_CORE_UNLOCK(adapter);
 
-       for (int i = 0; i < adapter->num_queues; i++, que++) {
+       for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
                if (que->tq) {
+#if __FreeBSD_version >= 800000
+                       taskqueue_drain(que->tq, &txr->txq_task);
+#endif
                        taskqueue_drain(que->tq, &que->que_task);
                        taskqueue_free(que->tq);
                }
@@ -708,6 +714,7 @@
 }
 
 
+#if __FreeBSD_version < 800000
 /*********************************************************************
  *  Transmit entry point
  *
@@ -779,7 +786,7 @@
        return;
 }
 
-#if __FreeBSD_version >= 800000
+#else
 /*
 ** Multiqueue Transmit driver
 **
@@ -807,7 +814,7 @@
                IXGBE_TX_UNLOCK(txr);
        } else {
                err = drbr_enqueue(ifp, txr->br, m);
-               taskqueue_enqueue(que->tq, &que->que_task);
+               taskqueue_enqueue(que->tq, &txr->txq_task);
        }
 
        return (err);
@@ -873,6 +880,22 @@
 }
 
 /*
+ * Called from a taskqueue to drain queued transmit packets.
+ */
+static void
+ixgbe_deferred_mq_start(void *arg, int pending)
+{
+       struct tx_ring *txr = arg;
+       struct adapter *adapter = txr->adapter;
+       struct ifnet *ifp = adapter->ifp;
+
+       IXGBE_TX_LOCK(txr);
+       if (!drbr_empty(ifp, txr->br))
+               ixgbe_mq_start_locked(ifp, txr, NULL);
+       IXGBE_TX_UNLOCK(txr);
+}
+
+/*
 ** Flush all ring buffers
 */
 static void
@@ -2230,6 +2258,9 @@
 {
        device_t dev = adapter->dev;
        struct          ix_queue *que = adapter->queues;
+#if __FreeBSD_version >= 800000
+       struct tx_ring          *txr = adapter->tx_rings;
+#endif
        int error, rid = 0;
 
        /* MSI RID at 1 */
@@ -2249,6 +2280,9 @@
         * Try allocating a fast interrupt and the associated deferred
         * processing contexts.
         */
+#if __FreeBSD_version >= 800000
+       TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
+#endif
        TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que);
        que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT,
             taskqueue_thread_enqueue, &que->tq);
@@ -2295,9 +2329,10 @@
 {
        device_t        dev = adapter->dev;
        struct          ix_queue *que = adapter->queues;
+       struct          tx_ring *txr = adapter->tx_rings;
        int             error, rid, vector = 0;
 
-       for (int i = 0; i < adapter->num_queues; i++, vector++, que++) {
+       for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
                rid = vector + 1;
                que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                    RF_SHAREABLE | RF_ACTIVE);
@@ -2327,6 +2362,9 @@
                if (adapter->num_queues > 1)
                        bus_bind_intr(dev, que->res, i);
 
+#if __FreeBSD_version >= 800000
+               TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
+#endif
                TASK_INIT(&que->que_task, 0, ixgbe_handle_que, que);
                que->tq = taskqueue_create_fast("ixgbe_que", M_NOWAIT,
                    taskqueue_thread_enqueue, &que->tq);
@@ -2570,12 +2608,13 @@
        ifp->if_softc = adapter;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = ixgbe_ioctl;
-       ifp->if_start = ixgbe_start;
 #if __FreeBSD_version >= 800000
        ifp->if_transmit = ixgbe_mq_start;
        ifp->if_qflush = ixgbe_qflush;
+#else
+       ifp->if_start = ixgbe_start;
+       IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
 #endif
-       ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2;
 
        ether_ifattach(ifp, adapter->hw.mac.addr);
 
Index: dev/ixgbe/ixgbe.h
===================================================================
--- dev/ixgbe/ixgbe.h   (revision 240960)
+++ dev/ixgbe/ixgbe.h   (working copy)
@@ -314,6 +314,7 @@
        char                    mtx_name[16];
 #if __FreeBSD_version >= 800000
        struct buf_ring         *br;
+       struct task             txq_task;
 #endif
 #ifdef IXGBE_FDIR
        u16                     atr_sample;

-- 
John Baldwin
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to