Blame SOURCES/0005-ethtool-Support-for-configurable-RSS-hash-function.patch

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