lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190401184245.1255272-1-jonathan.lemon@gmail.com>
Date:   Mon, 1 Apr 2019 11:42:45 -0700
From:   Jonathan Lemon <jonathan.lemon@...il.com>
To:     "John W. Linville" <linville@...driver.com>
CC:     <netdev@...r.kernel.org>, <kernel-team@...com>
Subject: [PATCH] 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@...il.com>
---
 ethtool.8.in   |  6 ++++++
 ethtool.c      | 46 +++++++++++++++++++++++++++++++++-------------
 test-cmdline.c |  4 ++++
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/ethtool.8.in b/ethtool.8.in
index b878521..e9f2421 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
@@ -953,6 +955,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 59131e8..282e103 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
-- 
2.21.0.196.g041f5ea1cf

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ