You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
5.8 KiB
189 lines
5.8 KiB
6 years ago
|
From e89f3c656ff17741aa3ea33c57bc177afedc999b Mon Sep 17 00:00:00 2001
|
||
|
From: Gal Pressman <galp@mellanox.com>
|
||
|
Date: Wed, 8 Mar 2017 16:03:51 +0200
|
||
|
Subject: [PATCH 5/7] ethtool: Support for configurable RSS hash function
|
||
|
|
||
|
This ethtool patch adds support to set and get the current RSS hash
|
||
|
function for the device through the new hfunc mask field in the
|
||
|
ethtool_rxfh struct. Kernel supported hash function names are queried
|
||
|
with ETHTOOL_GSTRINGS - each string is corresponding with a bit in hfunc
|
||
|
mask according to its index in the string-set.
|
||
|
|
||
|
(This corrects the mistaken revert from commit 126464e4da182064. -- JWL)
|
||
|
|
||
|
Signed-off-by: Eyal Perry <eyalpe@mellanox.com>
|
||
|
Signed-off-by: Gal Pressman <galp@mellanox.com>
|
||
|
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
|
||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||
|
(cherry picked from commit b888f358763a20625a381e071ea50524a520c7c1)
|
||
|
---
|
||
|
ethtool.8.in | 6 ++++++
|
||
|
ethtool.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||
|
2 files changed, 69 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/ethtool.8.in b/ethtool.8.in
|
||
|
index 9631847..b69c5c6 100644
|
||
|
--- a/ethtool.8.in
|
||
|
+++ b/ethtool.8.in
|
||
|
@@ -301,6 +301,8 @@ ethtool \- query or control network driver and hardware settings
|
||
|
.BI weight\ W0
|
||
|
.IR W1
|
||
|
.RB ...\ | \ default \ ]
|
||
|
+.RB [ hfunc
|
||
|
+.IR FUNC ]
|
||
|
.HP
|
||
|
.B ethtool \-f|\-\-flash
|
||
|
.I devname file
|
||
|
@@ -853,6 +855,10 @@ Sets RSS hash key of the specified network device. RSS hash key should be of dev
|
||
|
Hash key format must be in xx:yy:zz:aa:bb:cc format meaning both the nibbles of a byte should be mentioned
|
||
|
even if a nibble is zero.
|
||
|
.TP
|
||
|
+.BI hfunc
|
||
|
+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 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 ce48639..8eba6e6 100644
|
||
|
--- a/ethtool.c
|
||
|
+++ b/ethtool.c
|
||
|
@@ -3640,6 +3640,7 @@ static int do_grxfhindir(struct cmd_context *ctx,
|
||
|
|
||
|
static int do_grxfh(struct cmd_context *ctx)
|
||
|
{
|
||
|
+ struct ethtool_gstrings *hfuncs = NULL;
|
||
|
struct ethtool_rxfh rss_head = {0};
|
||
|
struct ethtool_rxnfc ring_count;
|
||
|
struct ethtool_rxfh *rss;
|
||
|
@@ -3697,6 +3698,26 @@ static int do_grxfh(struct cmd_context *ctx)
|
||
|
printf("%02x:", (u8) hkey[i]);
|
||
|
}
|
||
|
|
||
|
+ printf("RSS hash function:\n");
|
||
|
+ if (!rss->hfunc) {
|
||
|
+ printf(" Operation not supported\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ hfuncs = get_stringset(ctx, ETH_SS_RSS_HASH_FUNCS, 0, 1);
|
||
|
+ if (!hfuncs) {
|
||
|
+ perror("Cannot get hash functions names");
|
||
|
+ free(rss);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < hfuncs->len; i++)
|
||
|
+ printf(" %s: %s\n",
|
||
|
+ (const char *)hfuncs->data + i * ETH_GSTRING_LEN,
|
||
|
+ (rss->hfunc & (1 << i)) ? "on" : "off");
|
||
|
+
|
||
|
+out:
|
||
|
+ free(hfuncs);
|
||
|
free(rss);
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -3800,11 +3821,16 @@ static int do_srxfh(struct cmd_context *ctx)
|
||
|
struct ethtool_rxfh *rss;
|
||
|
struct ethtool_rxnfc ring_count;
|
||
|
int rxfhindir_equal = 0, rxfhindir_default = 0;
|
||
|
+ struct ethtool_gstrings *hfuncs = NULL;
|
||
|
char **rxfhindir_weight = NULL;
|
||
|
char *rxfhindir_key = NULL;
|
||
|
+ char *req_hfunc_name = NULL;
|
||
|
+ char *hfunc_name = NULL;
|
||
|
char *hkey = NULL;
|
||
|
int err = 0;
|
||
|
+ int i;
|
||
|
u32 arg_num = 0, indir_bytes = 0;
|
||
|
+ u32 req_hfunc = 0;
|
||
|
u32 entry_size = sizeof(rss_head.rss_config[0]);
|
||
|
u32 num_weights = 0;
|
||
|
|
||
|
@@ -3836,6 +3862,12 @@ static int do_srxfh(struct cmd_context *ctx)
|
||
|
} else if (!strcmp(ctx->argp[arg_num], "default")) {
|
||
|
++arg_num;
|
||
|
rxfhindir_default = 1;
|
||
|
+ } else if (!strcmp(ctx->argp[arg_num], "hfunc")) {
|
||
|
+ ++arg_num;
|
||
|
+ req_hfunc_name = ctx->argp[arg_num];
|
||
|
+ if (!req_hfunc_name)
|
||
|
+ exit_bad_args();
|
||
|
+ ++arg_num;
|
||
|
} else {
|
||
|
exit_bad_args();
|
||
|
}
|
||
|
@@ -3868,7 +3900,8 @@ static int do_srxfh(struct cmd_context *ctx)
|
||
|
|
||
|
rss_head.cmd = ETHTOOL_GRSSH;
|
||
|
err = send_ioctl(ctx, &rss_head);
|
||
|
- if (err < 0 && errno == EOPNOTSUPP && !rxfhindir_key) {
|
||
|
+ if (err < 0 && errno == EOPNOTSUPP && !rxfhindir_key &&
|
||
|
+ !req_hfunc_name) {
|
||
|
return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_equal,
|
||
|
rxfhindir_weight, num_weights);
|
||
|
} else if (err < 0) {
|
||
|
@@ -3886,14 +3919,39 @@ static int do_srxfh(struct cmd_context *ctx)
|
||
|
if (rxfhindir_equal || rxfhindir_weight)
|
||
|
indir_bytes = rss_head.indir_size * entry_size;
|
||
|
|
||
|
+ if (rss_head.hfunc && req_hfunc_name) {
|
||
|
+ hfuncs = get_stringset(ctx, ETH_SS_RSS_HASH_FUNCS, 0, 1);
|
||
|
+ if (!hfuncs) {
|
||
|
+ perror("Cannot get hash functions names");
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < hfuncs->len && !req_hfunc ; i++) {
|
||
|
+ hfunc_name = (char *)(hfuncs->data +
|
||
|
+ i * ETH_GSTRING_LEN);
|
||
|
+ if (!strncmp(hfunc_name, req_hfunc_name,
|
||
|
+ ETH_GSTRING_LEN))
|
||
|
+ req_hfunc = (u32)1 << i;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!req_hfunc) {
|
||
|
+ fprintf(stderr,
|
||
|
+ "Unknown hash function: %s\n", req_hfunc_name);
|
||
|
+ free(hfuncs);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
rss = calloc(1, sizeof(*rss) + indir_bytes + rss_head.key_size);
|
||
|
if (!rss) {
|
||
|
perror("Cannot allocate memory for RX flow hash config");
|
||
|
- return 1;
|
||
|
+ err = 1;
|
||
|
+ goto free;
|
||
|
}
|
||
|
rss->cmd = ETHTOOL_SRSSH;
|
||
|
rss->indir_size = rss_head.indir_size;
|
||
|
rss->key_size = rss_head.key_size;
|
||
|
+ rss->hfunc = req_hfunc;
|
||
|
|
||
|
if (fill_indir_table(&rss->indir_size, rss->rss_config, rxfhindir_default,
|
||
|
rxfhindir_equal, rxfhindir_weight, num_weights)) {
|
||
|
@@ -3918,6 +3976,7 @@ free:
|
||
|
free(hkey);
|
||
|
|
||
|
free(rss);
|
||
|
+ free(hfuncs);
|
||
|
return err;
|
||
|
}
|
||
|
|
||
|
@@ -4650,7 +4709,8 @@ static const struct option {
|
||
|
{ "-X|--set-rxfh-indir|--rxfh", 1, do_srxfh,
|
||
|
"Set Rx flow hash indirection table and/or RSS hash key",
|
||
|
" [ equal N | weight W0 W1 ... | default ]\n"
|
||
|
- " [ hkey %x:%x:%x:%x:%x:.... ]\n" },
|
||
|
+ " [ hkey %x:%x:%x:%x:%x:.... ]\n"
|
||
|
+ " [ hfunc FUNC ]\n" },
|
||
|
{ "-f|--flash", 1, do_flash,
|
||
|
"Flash firmware image from the specified file to a region on the device",
|
||
|
" FILENAME [ REGION-NUMBER-TO-FLASH ]\n" },
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|