]> xenbits.xensource.com Git - people/liuw/freebsd.git/commitdiff
XXX use multiqueue api, not working atm for-preview
authorWei Liu <wei.liu2@citrix.com>
Sun, 11 Oct 2015 18:33:24 +0000 (19:33 +0100)
committerWei Liu <wei.liu2@citrix.com>
Tue, 27 Oct 2015 12:55:22 +0000 (12:55 +0000)
sys/dev/xen/netfront/netfront.c

index 0b4e8af56c088bd63fe4e0963f86979f0f8b0d41..67ae4f5230247a4b26352b3cb6c6e7dfca5750f7 100644 (file)
@@ -98,7 +98,7 @@ __FBSDID("$FreeBSD$");
  *  interface must be reset (down/up) for it
  *  to take effect.
  */
-static int xn_enable_lro = 1;
+static int xn_enable_lro = 0;
 TUNABLE_INT("hw.xn.enable_lro", &xn_enable_lro);
 
 /*
@@ -1073,6 +1073,12 @@ xn_rxeof(struct netfront_queue_info *queue)
                while ((m = mbufq_dequeue(&rxq)) != NULL) {
                        if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
 
+                       /* XXX Setting flowid breaks the stream, need
+                        * to investigate more.
+                        */
+                       /* m->m_pkthdr.flowid = queue->num; */
+                       /* M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); */
+
                        /*
                         * Do we really need to drop the rx lock?
                         */
@@ -1090,6 +1096,7 @@ xn_rxeof(struct netfront_queue_info *queue)
 #else
                        (*ifp->if_input)(ifp, m);
 #endif
+
                        XN_RX_LOCK(queue);
                }
 
@@ -2033,6 +2040,58 @@ xn_configure_features(struct netfront_info *np)
        return (err);
 }
 
+#ifndef XN_LEGACY_TX
+static int
+xn_txq_mq_start(struct ifnet *ifp, struct mbuf *m)
+{
+       struct netfront_info *np;
+       struct netfront_queue_info *queue;
+       int i, npairs, error;
+       int notify;
+
+       np = ifp->if_softc;
+       npairs = np->num_queues;
+
+       /* check if flowid is set */
+       if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
+               i = m->m_pkthdr.flowid % npairs;
+       else
+               i = curcpu % npairs;
+
+       queue = &np->queue[i];
+
+       XN_TX_LOCK(queue);
+
+       /*
+        * XXX should just drop or push to deferred queue if not slots
+        * are available.
+        */
+       if (xn_tx_slot_available(queue)) {
+               error = xn_assemble_tx_request(queue, m);
+
+               RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify);
+               if (notify)
+                       xen_intr_signal(queue->xen_intr_handle);
+       } else {
+               error = ENOMEM; /* XXX not the right errno */
+               m_freem(m);
+       }
+
+       if (RING_FULL(&queue->tx))
+               queue->tx_full = 1;
+
+       XN_TX_UNLOCK(queue);
+
+       return (error);
+}
+
+static void
+xn_qflush(struct ifnet *ifp)
+{
+       if_qflush(ifp);
+}
+#endif
+
 /**
  * Create a network device.
  * @param dev  Newbus device representing this virtual NIC.
@@ -2067,12 +2126,21 @@ create_netdev(device_t dev)
        if_initname(ifp, "xn",  device_get_unit(dev));
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = xn_ioctl;
+
+#ifndef XN_LEGACY_TX
+       ifp->if_transmit = xn_txq_mq_start;
+       ifp->if_qflush = xn_qflush;
+#else
        ifp->if_start = xn_start;
+       ifp->if_snd.ifq_drv_maxlen = NET_TX_RING_SIZE - 1;
+       IFQ_SET_MAXLEN(&ifp->if_snd, NET_TX_RING_SIZE - 1);
+       IFQ_SET_READY(&ifp->if_snd);
+#endif
+
 #ifdef notyet
        ifp->if_watchdog = xn_watchdog;
 #endif
        ifp->if_init = xn_ifinit;
-       ifp->if_snd.ifq_maxlen = NET_TX_RING_SIZE - 1;
 
        ifp->if_hwassist = XN_CSUM_FEATURES;
        ifp->if_capabilities = IFCAP_HWCSUM;