aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Lemon <jonathan.lemon@gmail.com>2019-04-01 11:42:45 -0700
committerJohn W. Linville <linville@tuxdriver.com>2019-04-09 14:39:04 -0400
commit8c8bfaa74fef6dfb8134ce10c338fe50fe9901a2 (patch)
treecc9610bf956453363ba2354c3ca0059864a00d2b
parentb8b93adef91ac6943d475e5226a8fdf5ea622461 (diff)
downloadethtool-8c8bfaa74fef6dfb8134ce10c338fe50fe9901a2.tar.gz
Add a 'start N' option when specifying the Rx flow hash indirection table.
When using more than one RSS table, specifying a starting queue for flow distibution makes it easier to specify the set of queues attached to the table. An example: ethtool -X eth0 context 0 equal 14 # queues 0 .. 13 ethtool -X eth0 context 1 start 14 equal 42 # queues 14 .. 56 ethtool -N eth0 flow-type udp6 dst-port 4242 context 1 Here, context 0 might be handling normal kernel traffic, while context 1 handles AF_XDP traffic. Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com> Acked-by: Edward Cree <ecree@solarflare.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--ethtool.8.in6
-rw-r--r--ethtool.c46
-rw-r--r--test-cmdline.c4
3 files changed, 43 insertions, 13 deletions
diff --git a/ethtool.8.in b/ethtool.8.in
index 868af35..0e1eca4 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -297,6 +297,8 @@ ethtool \- query or control network driver and hardware settings
.B ethtool \-X|\-\-set\-rxfh\-indir|\-\-rxfh
.I devname
.RB [ hkey \ \*(MA:\...]
+.RB [ start
+.IR N ]
.RB [\ equal
.IR N \ |
.BI weight\ W0
@@ -959,6 +961,10 @@ even if a nibble is zero.
Sets RSS hash function of the specified network device.
List of RSS hash functions which kernel supports is shown as a part of the --show-rxfh command output.
.TP
+.BI start\ N
+For the \fBequal\fR and \fBweight\fR options, sets the starting receive queue
+for spreading flows to \fIN\fR.
+.TP
.BI equal\ N
Sets the receive flow hash indirection table to spread flows evenly
between the first \fIN\fR receive queues.
diff --git a/ethtool.c b/ethtool.c
index f56a604..66a907e 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -3902,13 +3902,14 @@ out:
}
static int fill_indir_table(u32 *indir_size, u32 *indir, int rxfhindir_default,
- int rxfhindir_equal, char **rxfhindir_weight,
- u32 num_weights)
+ int rxfhindir_start, int rxfhindir_equal,
+ char **rxfhindir_weight, u32 num_weights)
{
u32 i;
+
if (rxfhindir_equal) {
for (i = 0; i < *indir_size; i++)
- indir[i] = i % rxfhindir_equal;
+ indir[i] = rxfhindir_start + (i % rxfhindir_equal);
} else if (rxfhindir_weight) {
u32 j, weight, sum = 0, partial = 0;
@@ -3937,7 +3938,7 @@ static int fill_indir_table(u32 *indir_size, u32 *indir, int rxfhindir_default,
weight = get_u32(rxfhindir_weight[j], 0);
partial += weight;
}
- indir[i] = j;
+ indir[i] = rxfhindir_start + j;
}
} else if (rxfhindir_default) {
/* "*indir_size == 0" ==> reset indir to default */
@@ -3950,8 +3951,8 @@ static int fill_indir_table(u32 *indir_size, u32 *indir, int rxfhindir_default,
}
static int do_srxfhindir(struct cmd_context *ctx, int rxfhindir_default,
- int rxfhindir_equal, char **rxfhindir_weight,
- u32 num_weights)
+ int rxfhindir_start, int rxfhindir_equal,
+ char **rxfhindir_weight, u32 num_weights)
{
struct ethtool_rxfh_indir indir_head;
struct ethtool_rxfh_indir *indir;
@@ -3977,8 +3978,8 @@ static int do_srxfhindir(struct cmd_context *ctx, int rxfhindir_default,
indir->size = indir_head.size;
if (fill_indir_table(&indir->size, indir->ring_index,
- rxfhindir_default, rxfhindir_equal,
- rxfhindir_weight, num_weights)) {
+ rxfhindir_default, rxfhindir_start,
+ rxfhindir_equal, rxfhindir_weight, num_weights)) {
free(indir);
return 1;
}
@@ -3999,7 +4000,7 @@ static int do_srxfh(struct cmd_context *ctx)
struct ethtool_rxfh rss_head = {0};
struct ethtool_rxfh *rss = NULL;
struct ethtool_rxnfc ring_count;
- int rxfhindir_equal = 0, rxfhindir_default = 0;
+ int rxfhindir_equal = 0, rxfhindir_default = 0, rxfhindir_start = 0;
struct ethtool_gstrings *hfuncs = NULL;
char **rxfhindir_weight = NULL;
char *rxfhindir_key = NULL;
@@ -4024,6 +4025,11 @@ static int do_srxfh(struct cmd_context *ctx)
rxfhindir_equal = get_int_range(ctx->argp[arg_num],
0, 1, INT_MAX);
++arg_num;
+ } else if (!strcmp(ctx->argp[arg_num], "start")) {
+ ++arg_num;
+ rxfhindir_start = get_int_range(ctx->argp[arg_num],
+ 0, 0, INT_MAX);
+ ++arg_num;
} else if (!strcmp(ctx->argp[arg_num], "weight")) {
++arg_num;
rxfhindir_weight = ctx->argp + arg_num;
@@ -4084,6 +4090,18 @@ static int do_srxfh(struct cmd_context *ctx)
return 1;
}
+ if (rxfhindir_start && rxfhindir_default) {
+ fprintf(stderr,
+ "Start and default options are mutually exclusive\n");
+ return 1;
+ }
+
+ if (rxfhindir_start && !(rxfhindir_equal || rxfhindir_weight)) {
+ fprintf(stderr,
+ "Start must be used with equal or weight options\n");
+ return 1;
+ }
+
if (rxfhindir_default && rss_context) {
fprintf(stderr,
"Default and context options are mutually exclusive\n");
@@ -4130,8 +4148,9 @@ static int do_srxfh(struct cmd_context *ctx)
err = send_ioctl(ctx, &rss_head);
if (err < 0 && errno == EOPNOTSUPP && !rxfhindir_key &&
!req_hfunc_name && !rss_context) {
- return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_equal,
- rxfhindir_weight, num_weights);
+ return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_start,
+ rxfhindir_equal, rxfhindir_weight,
+ num_weights);
} else if (err < 0) {
perror("Cannot get RX flow hash indir size and key size");
return 1;
@@ -4186,8 +4205,9 @@ static int do_srxfh(struct cmd_context *ctx)
rss->indir_size = rss_head.indir_size;
rss->key_size = rss_head.key_size;
if (fill_indir_table(&rss->indir_size, rss->rss_config,
- rxfhindir_default, rxfhindir_equal,
- rxfhindir_weight, num_weights)) {
+ rxfhindir_default, rxfhindir_start,
+ rxfhindir_equal, rxfhindir_weight,
+ num_weights)) {
err = 1;
goto free;
}
diff --git a/test-cmdline.c b/test-cmdline.c
index 84630a5..b76e2c3 100644
--- a/test-cmdline.c
+++ b/test-cmdline.c
@@ -194,7 +194,11 @@ static struct test_case {
{ 1, "-X devname equal 0" },
{ 1, "--set-rxfh-indir devname equal foo" },
{ 1, "-X devname equal" },
+ { 1, "-X devname start" },
+ { 1, "-X devname start 3" },
+ { 0, "-X devname start 4 equal 2" },
{ 0, "--set-rxfh-indir devname weight 1 2 3 4" },
+ { 0, "--set-rxfh-indir devname start 4 weight 1 2 3 4" },
{ 0, "--rxfh devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" },
{ 0, "-X devname hkey 48:15:6e:bb:d8:bd:6f:b1:a4:c6:7a:c4:76:1c:29:98:da:e1:ae:6c:2e:12:2f:c0:b9:be:61:3d:00:54:35:9e:09:05:c7:d7:93:72:4a:ee" },
#if 0