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 <sthemmin@microsoft.com>
This commit is contained in:
parent
cf2b90756c
commit
a25d39a3eb
@ -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)
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include <rte_memcpy.h>
|
||||
#include <rte_string_fns.h>
|
||||
#include <rte_memzone.h>
|
||||
#include <rte_devargs.h>
|
||||
#include <rte_malloc.h>
|
||||
#include <rte_kvargs.h>
|
||||
#include <rte_atomic.h>
|
||||
#include <rte_branch_prediction.h>
|
||||
#include <rte_ether.h>
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user