Author: sephe
Date: Sun Sep 18 08:19:33 2016
New Revision: 305926
URL: https://svnweb.freebsd.org/changeset/base/305926

Log:
  hyperv/hn: Add sysctls to dynamic adjust RSS key and indirect table
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D7890

Modified:
  head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
  head/sys/dev/hyperv/netvsc/if_hnvar.h
  head/sys/dev/hyperv/netvsc/ndis.h

Modified: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c  Sun Sep 18 08:10:40 
2016        (r305925)
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c  Sun Sep 18 08:19:33 
2016        (r305926)
@@ -325,6 +325,8 @@ static int hn_rx_stat_ulong_sysctl(SYSCT
 static int hn_tx_stat_ulong_sysctl(SYSCTL_HANDLER_ARGS);
 static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
 static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
+static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS);
+static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS);
 static int hn_check_iplen(const struct mbuf *, int);
 static int hn_create_tx_ring(struct hn_softc *, int);
 static void hn_destroy_tx_ring(struct hn_tx_ring *);
@@ -391,6 +393,42 @@ hn_get_txswq_depth(const struct hn_tx_ri
 }
 
 static int
+hn_rss_reconfig(struct hn_softc *sc)
+{
+       int error;
+
+       HN_LOCK_ASSERT(sc);
+
+       /*
+        * Disable RSS first.
+        *
+        * NOTE:
+        * Direct reconfiguration by setting the UNCHG flags does
+        * _not_ work properly.
+        */
+       if (bootverbose)
+               if_printf(sc->hn_ifp, "disable RSS\n");
+       error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_DISABLE);
+       if (error) {
+               if_printf(sc->hn_ifp, "RSS disable failed\n");
+               return (error);
+       }
+
+       /*
+        * Reenable the RSS w/ the updated RSS key or indirect
+        * table.
+        */
+       if (bootverbose)
+               if_printf(sc->hn_ifp, "reconfig RSS\n");
+       error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
+       if (error) {
+               if_printf(sc->hn_ifp, "RSS reconfig failed\n");
+               return (error);
+       }
+       return (0);
+}
+
+static int
 hn_ifmedia_upd(struct ifnet *ifp __unused)
 {
 
@@ -583,6 +621,12 @@ netvsc_attach(device_t dev)
        SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "ndis_version",
            CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
            hn_ndis_version_sysctl, "A", "NDIS version");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key",
+           CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+           hn_rss_key_sysctl, "IU", "RSS key");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_ind",
+           CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
+           hn_rss_ind_sysctl, "IU", "RSS indirect table");
 
        /*
         * Setup the ifmedia, which has been initialized earlier.
@@ -2031,6 +2075,50 @@ hn_ndis_version_sysctl(SYSCTL_HANDLER_AR
 }
 
 static int
+hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS)
+{
+       struct hn_softc *sc = arg1;
+       int error;
+
+       HN_LOCK(sc);
+
+       error = SYSCTL_OUT(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key));
+       if (error || req->newptr == NULL)
+               goto back;
+
+       error = SYSCTL_IN(req, sc->hn_rss.rss_key, sizeof(sc->hn_rss.rss_key));
+       if (error)
+               goto back;
+
+       error = hn_rss_reconfig(sc);
+back:
+       HN_UNLOCK(sc);
+       return (error);
+}
+
+static int
+hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS)
+{
+       struct hn_softc *sc = arg1;
+       int error;
+
+       HN_LOCK(sc);
+
+       error = SYSCTL_OUT(req, sc->hn_rss.rss_ind, sizeof(sc->hn_rss.rss_ind));
+       if (error || req->newptr == NULL)
+               goto back;
+
+       error = SYSCTL_IN(req, sc->hn_rss.rss_ind, sizeof(sc->hn_rss.rss_ind));
+       if (error)
+               goto back;
+
+       error = hn_rss_reconfig(sc);
+back:
+       HN_UNLOCK(sc);
+       return (error);
+}
+
+static int
 hn_check_iplen(const struct mbuf *m, int hoff)
 {
        const struct ip *ip;
@@ -3179,7 +3267,7 @@ hn_synth_attach(struct hn_softc *sc, int
                        rss->rss_ind[i] = i % nchan;
        }
 
-       error = hn_rndis_conf_rss(sc);
+       error = hn_rndis_conf_rss(sc, NDIS_RSS_FLAG_NONE);
        if (error) {
                /*
                 * Failed to configure RSS key or indirect table; only

Modified: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c        Sun Sep 18 08:10:40 
2016        (r305925)
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c        Sun Sep 18 08:19:33 
2016        (r305926)
@@ -837,7 +837,7 @@ hn_rndis_conf_offload(struct hn_softc *s
 }
 
 int
-hn_rndis_conf_rss(struct hn_softc *sc)
+hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags)
 {
        struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
        struct ndis_rss_params *prm = &rss->rss_params;
@@ -858,6 +858,7 @@ hn_rndis_conf_rss(struct hn_softc *sc)
        prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS;
        prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2;
        prm->ndis_hdr.ndis_size = sizeof(*rss);
+       prm->ndis_flags = flags;
        prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ |
            NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 |
            NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6;

Modified: head/sys/dev/hyperv/netvsc/if_hnvar.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h       Sun Sep 18 08:10:40 2016        
(r305925)
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h       Sun Sep 18 08:19:33 2016        
(r305926)
@@ -118,7 +118,7 @@ uint32_t    hn_chim_alloc(struct hn_softc *
 void           hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
 
 int            hn_rndis_attach(struct hn_softc *sc);
-int            hn_rndis_conf_rss(struct hn_softc *sc);
+int            hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags);
 void           *hn_rndis_pktinfo_append(struct rndis_packet_msg *,
                    size_t pktsize, size_t pi_dlen, uint32_t pi_type);
 int            hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt);

Modified: head/sys/dev/hyperv/netvsc/ndis.h
==============================================================================
--- head/sys/dev/hyperv/netvsc/ndis.h   Sun Sep 18 08:10:40 2016        
(r305925)
+++ head/sys/dev/hyperv/netvsc/ndis.h   Sun Sep 18 08:19:33 2016        
(r305926)
@@ -188,6 +188,7 @@ struct ndis_rss_params {
 #define        NDIS_RSS_PARAMS_REV_1           1       /* NDIS 6.0 */
 #define        NDIS_RSS_PARAMS_REV_2           2       /* NDIS 6.20 */
 
+#define        NDIS_RSS_FLAG_NONE              0x0000
 #define        NDIS_RSS_FLAG_BCPU_UNCHG        0x0001
 #define        NDIS_RSS_FLAG_HASH_UNCHG        0x0002
 #define        NDIS_RSS_FLAG_IND_UNCHG         0x0004
_______________________________________________
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