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