Author: sephe
Date: Wed Nov 30 05:28:39 2016
New Revision: 309311
URL: https://svnweb.freebsd.org/changeset/base/309311

Log:
  hyperv/hn: Allow multiple TX taskqueues.
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D8655

Modified:
  head/sys/dev/hyperv/netvsc/if_hn.c
  head/sys/dev/hyperv/netvsc/if_hnvar.h

Modified: head/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hn.c  Wed Nov 30 05:11:59 2016        
(r309310)
+++ head/sys/dev/hyperv/netvsc/if_hn.c  Wed Nov 30 05:28:39 2016        
(r309311)
@@ -416,6 +416,10 @@ static int                 hn_share_tx_taskq = 0;
 SYSCTL_INT(_hw_hn, OID_AUTO, share_tx_taskq, CTLFLAG_RDTUN,
     &hn_share_tx_taskq, 0, "Enable shared TX taskqueue");
 
+static int                     hn_tx_taskq_cnt = 1;
+SYSCTL_INT(_hw_hn, OID_AUTO, tx_taskq_cnt, CTLFLAG_RDTUN,
+    &hn_tx_taskq_cnt, 0, "# of TX taskqueues");
+
 #ifndef HN_USE_TXDESC_BUFRING
 static int                     hn_use_txdesc_bufring = 0;
 #else
@@ -465,7 +469,7 @@ SYSCTL_INT(_hw_hn, OID_AUTO, tx_agg_pkts
     &hn_tx_agg_pkts, 0, "Packet transmission aggregation packet limit");
 
 static u_int                   hn_cpu_index;   /* next CPU for channel */
-static struct taskqueue                *hn_tx_taskq;   /* shared TX taskqueue 
*/
+static struct taskqueue                **hn_tx_taskque;/* shared TX taskqueues 
*/
 
 static const uint8_t
 hn_rss_key_default[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
@@ -898,13 +902,21 @@ hn_attach(device_t dev)
        /*
         * Setup taskqueue for transmission.
         */
-       if (hn_tx_taskq == NULL) {
-               sc->hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
-                   taskqueue_thread_enqueue, &sc->hn_tx_taskq);
-               taskqueue_start_threads(&sc->hn_tx_taskq, 1, PI_NET, "%s tx",
-                   device_get_nameunit(dev));
+       if (hn_tx_taskque == NULL) {
+               int i;
+
+               sc->hn_tx_taskqs =
+                   malloc(hn_tx_taskq_cnt * sizeof(struct taskqueue *),
+                   M_DEVBUF, M_WAITOK);
+               for (i = 0; i < hn_tx_taskq_cnt; ++i) {
+                       sc->hn_tx_taskqs[i] = taskqueue_create("hn_tx",
+                           M_WAITOK, taskqueue_thread_enqueue,
+                           &sc->hn_tx_taskqs[i]);
+                       taskqueue_start_threads(&sc->hn_tx_taskqs[i], 1, PI_NET,
+                           "%s tx%d", device_get_nameunit(dev), i);
+               }
        } else {
-               sc->hn_tx_taskq = hn_tx_taskq;
+               sc->hn_tx_taskqs = hn_tx_taskque;
        }
 
        /*
@@ -1204,8 +1216,13 @@ hn_detach(device_t dev)
        hn_destroy_rx_data(sc);
        hn_destroy_tx_data(sc);
 
-       if (sc->hn_tx_taskq != hn_tx_taskq)
-               taskqueue_free(sc->hn_tx_taskq);
+       if (sc->hn_tx_taskqs != hn_tx_taskque) {
+               int i;
+
+               for (i = 0; i < hn_tx_taskq_cnt; ++i)
+                       taskqueue_free(sc->hn_tx_taskqs[i]);
+               free(sc->hn_tx_taskqs, M_DEVBUF);
+       }
        taskqueue_free(sc->hn_mgmt_taskq0);
 
        if (sc->hn_xact != NULL) {
@@ -3295,7 +3312,7 @@ hn_tx_ring_create(struct hn_softc *sc, i
            M_WAITOK, &txr->hn_tx_lock);
 #endif
 
-       txr->hn_tx_taskq = sc->hn_tx_taskq;
+       txr->hn_tx_taskq = sc->hn_tx_taskqs[id % hn_tx_taskq_cnt];
 
 #ifdef HN_IFSTART_SUPPORT
        if (hn_use_if_start) {
@@ -5334,6 +5351,15 @@ hn_chan_callback(struct vmbus_channel *c
 static void
 hn_tx_taskq_create(void *arg __unused)
 {
+       int i;
+
+       /*
+        * Fix the # of TX taskqueues.
+        */
+       if (hn_tx_taskq_cnt <= 0)
+               hn_tx_taskq_cnt = 1;
+       else if (hn_tx_taskq_cnt > mp_ncpus)
+               hn_tx_taskq_cnt = mp_ncpus;
 
        if (vm_guest != VM_GUEST_HV)
                return;
@@ -5341,9 +5367,14 @@ hn_tx_taskq_create(void *arg __unused)
        if (!hn_share_tx_taskq)
                return;
 
-       hn_tx_taskq = taskqueue_create("hn_tx", M_WAITOK,
-           taskqueue_thread_enqueue, &hn_tx_taskq);
-       taskqueue_start_threads(&hn_tx_taskq, 1, PI_NET, "hn tx");
+       hn_tx_taskque = malloc(hn_tx_taskq_cnt * sizeof(struct taskqueue *),
+           M_DEVBUF, M_WAITOK);
+       for (i = 0; i < hn_tx_taskq_cnt; ++i) {
+               hn_tx_taskque[i] = taskqueue_create("hn_tx", M_WAITOK,
+                   taskqueue_thread_enqueue, &hn_tx_taskque[i]);
+               taskqueue_start_threads(&hn_tx_taskque[i], 1, PI_NET,
+                   "hn tx%d", i);
+       }
 }
 SYSINIT(hn_txtq_create, SI_SUB_DRIVERS, SI_ORDER_SECOND,
     hn_tx_taskq_create, NULL);
@@ -5352,8 +5383,13 @@ static void
 hn_tx_taskq_destroy(void *arg __unused)
 {
 
-       if (hn_tx_taskq != NULL)
-               taskqueue_free(hn_tx_taskq);
+       if (hn_tx_taskque != NULL) {
+               int i;
+
+               for (i = 0; i < hn_tx_taskq_cnt; ++i)
+                       taskqueue_free(hn_tx_taskque[i]);
+               free(hn_tx_taskque, M_DEVBUF);
+       }
 }
 SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_SECOND,
     hn_tx_taskq_destroy, NULL);

Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h       Wed Nov 30 05:11:59 2016        
(r309310)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h       Wed Nov 30 05:28:39 2016        
(r309311)
@@ -192,7 +192,7 @@ struct hn_softc {
        int             hn_chim_szmax;
 
        int             hn_cpu;
-       struct taskqueue *hn_tx_taskq;
+       struct taskqueue **hn_tx_taskqs;
        struct sysctl_oid *hn_tx_sysctl_tree;
        struct sysctl_oid *hn_rx_sysctl_tree;
        struct vmbus_xact_ctx *hn_xact;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to