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

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