From: Stephen Hemminger Date: Thu, 30 Aug 2018 22:35:09 +0000 (-0700) Subject: net/netvsc: allow tuning latency with devargs X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=a25d39a3eb69;p=dpdk.git net/netvsc: allow tuning latency with devargs Allow overriding default guest to host latency on per device basis with devargs. Signed-off-by: Stephen Hemminger --- diff --git a/doc/guides/nics/netvsc.rst b/doc/guides/nics/netvsc.rst index 345f393c24..cc07ce46f8 100644 --- a/doc/guides/nics/netvsc.rst +++ b/doc/guides/nics/netvsc.rst @@ -103,3 +103,19 @@ The following prerequisites apply: * Linux kernel support for UIO on vmbus is done with the uio_hv_generic driver. Full support of multiple queues requires the 4.17 kernel. It is possible to use the netvsc PMD with 4.16 kernel but it is limited to a single queue. + + +Netvsc PMD arguments +-------------------- + +The user can specify below argument in devargs. + +#. ``latency``: + + A netvsc device uses a mailbox page to indicate to the host that there + is something in the transmit queue. The host scans this page at a + periodic interval. This parameter allows adjusting the value that + is used by the host. Smaller values improve transmit latency, and larger + values save CPU cycles. This parameter is in microseconds. + If the value is too large or too small it will be + ignored by the host. (Default: 50) diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c index 7f7ac155e2..e61ff432d4 100644 --- a/drivers/net/netvsc/hn_ethdev.c +++ b/drivers/net/netvsc/hn_ethdev.c @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -130,6 +132,55 @@ eth_dev_vmbus_release(struct rte_eth_dev *eth_dev) eth_dev->intr_handle = NULL; } +/* handle "latency=X" from devargs */ +static int hn_set_latency(const char *key, const char *value, void *opaque) +{ + struct hn_data *hv = opaque; + char *endp = NULL; + unsigned long lat; + + errno = 0; + lat = strtoul(value, &endp, 0); + + if (*value == '\0' || *endp != '\0') { + PMD_DRV_LOG(ERR, "invalid parameter %s=%s", key, value); + return -EINVAL; + } + + PMD_DRV_LOG(DEBUG, "set latency %lu usec", lat); + + hv->latency = lat * 1000; /* usec to nsec */ + return 0; +} + +/* Parse device arguments */ +static int hn_parse_args(const struct rte_eth_dev *dev) +{ + struct hn_data *hv = dev->data->dev_private; + struct rte_devargs *devargs = dev->device->devargs; + static const char * const valid_keys[] = { + "latency", + NULL + }; + struct rte_kvargs *kvlist; + + if (!devargs) + return 0; + + PMD_INIT_LOG(DEBUG, "device args %s %s", + devargs->name, devargs->args); + + kvlist = rte_kvargs_parse(devargs->args, valid_keys); + if (!kvlist) { + PMD_DRV_LOG(NOTICE, "invalid parameters"); + return -EINVAL; + } + + rte_kvargs_process(kvlist, "latency", hn_set_latency, hv); + rte_kvargs_free(kvlist); + return 0; +} + /* Update link status. * Note: the DPDK definition of "wait_to_complete" * means block this call until link is up. @@ -263,8 +314,7 @@ static int hn_subchan_configure(struct hn_data *hv, return err; } - rte_vmbus_set_latency(hv->vmbus, new_sc, - HN_CHAN_LATENCY_NS); + rte_vmbus_set_latency(hv->vmbus, new_sc, hv->latency); retry = 0; chn_index = rte_vmbus_sub_channel_index(new_sc); @@ -626,14 +676,18 @@ eth_hn_dev_init(struct rte_eth_dev *eth_dev) hv->rxbuf_res = &vmbus->resource[HV_RECV_BUF_MAP]; hv->chim_res = &vmbus->resource[HV_SEND_BUF_MAP]; hv->port_id = eth_dev->data->port_id; + hv->latency = HN_CHAN_LATENCY_NS; + + err = hn_parse_args(eth_dev); + if (err) + return err; /* Initialize primary channel input for control operations */ err = rte_vmbus_chan_open(vmbus, &hv->channels[0]); if (err) return err; - rte_vmbus_set_latency(hv->vmbus, hv->channels[0], - HN_CHAN_LATENCY_NS); + rte_vmbus_set_latency(hv->vmbus, hv->channels[0], hv->latency); hv->primary = hn_rx_queue_alloc(hv, 0, eth_dev->device->numa_node); diff --git a/drivers/net/netvsc/hn_var.h b/drivers/net/netvsc/hn_var.h index b42bd97b9a..f188f6360f 100644 --- a/drivers/net/netvsc/hn_var.h +++ b/drivers/net/netvsc/hn_var.h @@ -113,6 +113,7 @@ struct hn_data { uint32_t chim_szmax; /* Max size per buffer */ uint32_t chim_cnt; /* Max packets per buffer */ + uint32_t latency; uint32_t nvs_ver; uint32_t ndis_ver; uint32_t rndis_agg_size;