netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH ethtool 0/3] RSS ntuple filters
@ 2018-03-09 15:01 Edward Cree
  2018-03-09 15:03 ` [PATCH ethtool 1/3] ethtool-copy.h: sync with net-next Edward Cree
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Edward Cree @ 2018-03-09 15:01 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev

This series adds support for the management of extra RSS contexts and RSS
 spreading of ntuple/NFC filters introduced in kernel commit 84a1d9c48200
 ("net: ethtool: extend RXNFC API to support RSS spreading of filter matches").

Edward Cree (3):
  ethtool-copy.h: sync with net-next
  ethtool: add support for extra RSS contexts and RSS steering filters
  ethtool.8: Document RSS context control and RSS filters

 ethtool-copy.h |  32 ++++++++++---
 ethtool.8.in   |  28 ++++++++++++
 ethtool.c      | 141 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 internal.h     |   4 +-
 rxclass.c      |  58 ++++++++++++++++++++----
 5 files changed, 227 insertions(+), 36 deletions(-)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH ethtool 1/3] ethtool-copy.h: sync with net-next
  2018-03-09 15:01 [PATCH ethtool 0/3] RSS ntuple filters Edward Cree
@ 2018-03-09 15:03 ` Edward Cree
  2018-03-09 15:04 ` [PATCH ethtool 2/3] ethtool: add support for extra RSS contexts and RSS steering filters Edward Cree
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2018-03-09 15:03 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev

This covers kernel changes up to commit 84a1d9c48200,
    net: ethtool: extend RXNFC API to support RSS spreading of filter matches

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 ethtool-copy.h | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index f4e7bb2..8cc61e9 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -912,12 +912,15 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
  * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW
  * @data: Command-dependent value
  * @fs: Flow classification rule
+ * @rss_context: RSS context to be affected
  * @rule_cnt: Number of rules to be affected
  * @rule_locs: Array of used rule locations
  *
  * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating
  * the fields included in the flow hash, e.g. %RXH_IP_SRC.  The following
- * structure fields must not be used.
+ * structure fields must not be used, except that if @flow_type includes
+ * the %FLOW_RSS flag, then @rss_context determines which RSS context to
+ * act on.
  *
  * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues
  * on return.
@@ -929,7 +932,9 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
  * set in @data then special location values should not be used.
  *
  * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the location of an
- * existing rule on entry and @fs contains the rule on return.
+ * existing rule on entry and @fs contains the rule on return; if
+ * @fs.@flow_type includes the %FLOW_RSS flag, then @rss_context is
+ * filled with the RSS context ID associated with the rule.
  *
  * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the
  * user buffer for @rule_locs on entry.  On return, @data is the size
@@ -940,7 +945,11 @@ static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
  * For %ETHTOOL_SRXCLSRLINS, @fs specifies the rule to add or update.
  * @fs.@location either specifies the location to use or is a special
  * location value with %RX_CLS_LOC_SPECIAL flag set.  On return,
- * @fs.@location is the actual rule location.
+ * @fs.@location is the actual rule location.  If @fs.@flow_type
+ * includes the %FLOW_RSS flag, @rss_context is the RSS context ID to
+ * use for flow spreading traffic which matches this rule.  The value
+ * from the rxfh indirection table will be added to @fs.@ring_cookie
+ * to choose which ring to deliver to.
  *
  * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the location of an
  * existing rule on entry.
@@ -961,7 +970,10 @@ struct ethtool_rxnfc {
 	__u32				flow_type;
 	__u64				data;
 	struct ethtool_rx_flow_spec	fs;
-	__u32				rule_cnt;
+	union {
+		__u32			rule_cnt;
+		__u32			rss_context;
+	};
 	__u32				rule_locs[0];
 };
 
@@ -988,7 +1000,11 @@ struct ethtool_rxfh_indir {
 /**
  * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
  * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
- * @rss_context: RSS context identifier.
+ * @rss_context: RSS context identifier.  Context 0 is the default for normal
+ *	traffic; other contexts can be referenced as the destination for RX flow
+ *	classification rules.  %ETH_RXFH_CONTEXT_ALLOC is used with command
+ *	%ETHTOOL_SRSSH to allocate a new RSS context; on return this field will
+ *	contain the ID of the newly allocated context.
  * @indir_size: On entry, the array size of the user buffer for the
  *	indirection table, which may be zero, or (for %ETHTOOL_SRSSH),
  *	%ETH_RXFH_INDIR_NO_CHANGE.  On return from %ETHTOOL_GRSSH,
@@ -1007,7 +1023,8 @@ struct ethtool_rxfh_indir {
  * size should be returned.  For %ETHTOOL_SRSSH, an @indir_size of
  * %ETH_RXFH_INDIR_NO_CHANGE means that indir table setting is not requested
  * and a @indir_size of zero means the indir table should be reset to default
- * values. An hfunc of zero means that hash function setting is not requested.
+ * values (if @rss_context == 0) or that the RSS context should be deleted.
+ * An hfunc of zero means that hash function setting is not requested.
  */
 struct ethtool_rxfh {
 	__u32   cmd;
@@ -1019,6 +1036,7 @@ struct ethtool_rxfh {
 	__u32	rsvd32;
 	__u32   rss_config[0];
 };
+#define ETH_RXFH_CONTEXT_ALLOC		0xffffffff
 #define ETH_RXFH_INDIR_NO_CHANGE	0xffffffff
 
 /**
@@ -1633,6 +1651,8 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex)
 /* Flag to enable additional fields in struct ethtool_rx_flow_spec */
 #define	FLOW_EXT	0x80000000
 #define	FLOW_MAC_EXT	0x40000000
+/* Flag to enable RSS spreading of traffic matching rule (nfc only) */
+#define	FLOW_RSS	0x20000000
 
 /* L3-L4 network traffic flow hash options */
 #define	RXH_L2DA	(1 << 1)

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH ethtool 2/3] ethtool: add support for extra RSS contexts and RSS steering filters
  2018-03-09 15:01 [PATCH ethtool 0/3] RSS ntuple filters Edward Cree
  2018-03-09 15:03 ` [PATCH ethtool 1/3] ethtool-copy.h: sync with net-next Edward Cree
@ 2018-03-09 15:04 ` Edward Cree
  2018-03-09 15:04 ` [PATCH ethtool 3/3] ethtool.8: Document RSS context control and RSS filters Edward Cree
  2018-03-12 18:51 ` [PATCH ethtool 0/3] RSS ntuple filters John W. Linville
  3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2018-03-09 15:04 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev

RSS contexts can be created on a device with -X ... context new, modified
 with -X ... context N, and deleted with -X ... context N delete.
N-tuple filters can be directed at those contexts with -N ... context N.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 ethtool.c  | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 internal.h |   4 +-
 rxclass.c  |  58 +++++++++++++++++++++----
 3 files changed, 173 insertions(+), 30 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index c870a2b..5ea9f05 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1506,7 +1506,7 @@ static void dump_features(const struct feature_defs *defs,
 
 static int dump_rxfhash(int fhash, u64 val)
 {
-	switch (fhash) {
+	switch (fhash & ~FLOW_RSS) {
 	case TCP_V4_FLOW:
 		fprintf(stdout, "TCP over IPV4 flows");
 		break;
@@ -3517,11 +3517,20 @@ static int do_srxclass(struct cmd_context *ctx)
 	if (ctx->argc < 2)
 		exit_bad_args();
 
-	if (ctx->argc == 3 && !strcmp(ctx->argp[0], "rx-flow-hash")) {
+	if (!strcmp(ctx->argp[0], "rx-flow-hash")) {
 		int rx_fhash_set;
 		u32 rx_fhash_val;
 		struct ethtool_rxnfc nfccmd;
+		bool flow_rss = false;
 
+		if (ctx->argc == 5) {
+			if (strcmp(ctx->argp[3], "context"))
+				exit_bad_args();
+			flow_rss = true;
+			nfccmd.rss_context = get_u32(ctx->argp[4], 0);
+		} else if (ctx->argc != 3) {
+			exit_bad_args();
+		}
 		rx_fhash_set = rxflow_str_to_type(ctx->argp[1]);
 		if (!rx_fhash_set)
 			exit_bad_args();
@@ -3531,16 +3540,19 @@ static int do_srxclass(struct cmd_context *ctx)
 		nfccmd.cmd = ETHTOOL_SRXFH;
 		nfccmd.flow_type = rx_fhash_set;
 		nfccmd.data = rx_fhash_val;
+		if (flow_rss)
+			nfccmd.flow_type |= FLOW_RSS;
 
 		err = send_ioctl(ctx, &nfccmd);
 		if (err < 0)
 			perror("Cannot change RX network flow hashing options");
 	} else if (!strcmp(ctx->argp[0], "flow-type")) {
 		struct ethtool_rx_flow_spec rx_rule_fs;
+		__u32 rss_context = 0;
 
 		ctx->argc--;
 		ctx->argp++;
-		if (rxclass_parse_ruleopts(ctx, &rx_rule_fs) < 0)
+		if (rxclass_parse_ruleopts(ctx, &rx_rule_fs, &rss_context) < 0)
 			exit_bad_args();
 
 		/* attempt to add rule via N-tuple specifier */
@@ -3549,7 +3561,7 @@ static int do_srxclass(struct cmd_context *ctx)
 			return 0;
 
 		/* attempt to add rule via network flow classifier */
-		err = rxclass_rule_ins(ctx, &rx_rule_fs);
+		err = rxclass_rule_ins(ctx, &rx_rule_fs, rss_context);
 		if (err < 0) {
 			fprintf(stderr, "Cannot insert"
 				" classification rule\n");
@@ -3578,8 +3590,18 @@ static int do_grxclass(struct cmd_context *ctx)
 	struct ethtool_rxnfc nfccmd;
 	int err;
 
-	if (ctx->argc == 2 && !strcmp(ctx->argp[0], "rx-flow-hash")) {
+	if (ctx->argc > 0 && !strcmp(ctx->argp[0], "rx-flow-hash")) {
 		int rx_fhash_get;
+		bool flow_rss = false;
+
+		if (ctx->argc == 4) {
+			if (strcmp(ctx->argp[2], "context"))
+				exit_bad_args();
+			flow_rss = true;
+			nfccmd.rss_context = get_u32(ctx->argp[3], 0);
+		} else if (ctx->argc != 2) {
+			exit_bad_args();
+		}
 
 		rx_fhash_get = rxflow_str_to_type(ctx->argp[1]);
 		if (!rx_fhash_get)
@@ -3587,11 +3609,17 @@ static int do_grxclass(struct cmd_context *ctx)
 
 		nfccmd.cmd = ETHTOOL_GRXFH;
 		nfccmd.flow_type = rx_fhash_get;
+		if (flow_rss)
+			nfccmd.flow_type |= FLOW_RSS;
 		err = send_ioctl(ctx, &nfccmd);
-		if (err < 0)
+		if (err < 0) {
 			perror("Cannot get RX network flow hashing options");
-		else
+		} else {
+			if (flow_rss)
+				fprintf(stdout, "For RSS context %u:\n",
+					nfccmd.rss_context);
 			dump_rxfhash(rx_fhash_get, nfccmd.data);
+		}
 	} else if (ctx->argc == 2 && !strcmp(ctx->argp[0], "rule")) {
 		int rx_class_rule_get =
 			get_uint_range(ctx->argp[1], 0, INT_MAX);
@@ -3683,10 +3711,23 @@ static int do_grxfh(struct cmd_context *ctx)
 	struct ethtool_rxfh rss_head = {0};
 	struct ethtool_rxnfc ring_count;
 	struct ethtool_rxfh *rss;
+	u32 rss_context = 0;
 	u32 i, indir_bytes;
+	int arg_num = 0;
 	char *hkey;
 	int err;
 
+	while (arg_num < ctx->argc) {
+		if (!strcmp(ctx->argp[arg_num], "context")) {
+			++arg_num;
+			rss_context = get_int_range(ctx->argp[arg_num], 0, 1,
+						    ETH_RXFH_CONTEXT_ALLOC - 1);
+			++arg_num;
+		} else {
+			exit_bad_args();
+		}
+	}
+
 	ring_count.cmd = ETHTOOL_GRXRINGS;
 	err = send_ioctl(ctx, &ring_count);
 	if (err < 0) {
@@ -3695,6 +3736,7 @@ static int do_grxfh(struct cmd_context *ctx)
 	}
 
 	rss_head.cmd = ETHTOOL_GRSSH;
+	rss_head.rss_context = rss_context;
 	err = send_ioctl(ctx, &rss_head);
 	if (err < 0 && errno == EOPNOTSUPP) {
 		return do_grxfhindir(ctx, &ring_count);
@@ -3712,6 +3754,7 @@ static int do_grxfh(struct cmd_context *ctx)
 	}
 
 	rss->cmd = ETHTOOL_GRSSH;
+	rss->rss_context = rss_context;
 	rss->indir_size = rss_head.indir_size;
 	rss->key_size = rss_head.key_size;
 	err = send_ioctl(ctx, rss);
@@ -3872,6 +3915,8 @@ static int do_srxfh(struct cmd_context *ctx)
 	u32 req_hfunc = 0;
 	u32 entry_size = sizeof(rss_head.rss_config[0]);
 	u32 num_weights = 0;
+	u32 rss_context = 0;
+	int delete = 0;
 
 	if (ctx->argc < 1)
 		exit_bad_args();
@@ -3907,6 +3952,18 @@ static int do_srxfh(struct cmd_context *ctx)
 			if (!req_hfunc_name)
 				exit_bad_args();
 			++arg_num;
+		} else if (!strcmp(ctx->argp[arg_num], "context")) {
+			++arg_num;
+			if(!strcmp(ctx->argp[arg_num], "new"))
+				rss_context = ETH_RXFH_CONTEXT_ALLOC;
+			else
+				rss_context = get_int_range(
+						ctx->argp[arg_num], 0, 1,
+						ETH_RXFH_CONTEXT_ALLOC - 1);
+			++arg_num;
+		} else if (!strcmp(ctx->argp[arg_num], "delete")) {
+			++arg_num;
+			delete = 1;
 		} else {
 			exit_bad_args();
 		}
@@ -3930,6 +3987,41 @@ static int do_srxfh(struct cmd_context *ctx)
 		return 1;
 	}
 
+	if (rxfhindir_default && rss_context) {
+		fprintf(stderr,
+			"Default and context options are mutually exclusive\n");
+		return 1;
+	}
+
+	if (delete && !rss_context) {
+		fprintf(stderr, "Delete option requires context option\n");
+		return 1;
+	}
+	
+	if (delete && rxfhindir_weight) {
+		fprintf(stderr,
+			"Delete and weight options are mutually exclusive\n");
+		return 1;
+	}
+	
+	if (delete && rxfhindir_equal) {
+		fprintf(stderr,
+			"Delete and equal options are mutually exclusive\n");
+		return 1;
+	}
+	
+	if (delete && rxfhindir_default) {
+		fprintf(stderr,
+			"Delete and default options are mutually exclusive\n");
+		return 1;
+	}
+	
+	if (delete && rxfhindir_key) {
+		fprintf(stderr,
+			"Delete and hkey options are mutually exclusive\n");
+		return 1;
+	}
+
 	ring_count.cmd = ETHTOOL_GRXRINGS;
 	err = send_ioctl(ctx, &ring_count);
 	if (err < 0) {
@@ -3940,7 +4032,7 @@ 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 &&
-	    !req_hfunc_name) {
+	    !req_hfunc_name && !rss_context) {
 		return do_srxfhindir(ctx, rxfhindir_default, rxfhindir_equal,
 				     rxfhindir_weight, num_weights);
 	} else if (err < 0) {
@@ -3988,14 +4080,19 @@ static int do_srxfh(struct cmd_context *ctx)
 		goto free;
 	}
 	rss->cmd = ETHTOOL_SRSSH;
-	rss->indir_size = rss_head.indir_size;
-	rss->key_size = rss_head.key_size;
+	rss->rss_context = rss_context;
 	rss->hfunc = req_hfunc;
-
-	if (fill_indir_table(&rss->indir_size, rss->rss_config, rxfhindir_default,
-			     rxfhindir_equal, rxfhindir_weight, num_weights)) {
-		err = 1;
-		goto free;
+	if (delete) {
+		rss->indir_size = rss->key_size = 0;
+	} else {
+		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)) {
+			err = 1;
+			goto free;
+		}
 	}
 
 	if (hkey)
@@ -4008,6 +4105,8 @@ static int do_srxfh(struct cmd_context *ctx)
 	if (err < 0) {
 		perror("Cannot set RX flow hash configuration");
 		err = 1;
+	} else if (rss_context == ETH_RXFH_CONTEXT_ALLOC) {
+		printf("New RSS context is %d\n", rss->rss_context);
 	}
 
 free:
@@ -5023,12 +5122,12 @@ static const struct option {
 	{ "-n|-u|--show-nfc|--show-ntuple", 1, do_grxclass,
 	  "Show Rx network flow classification options or rules",
 	  "		[ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
-	  "tcp6|udp6|ah6|esp6|sctp6 |\n"
+	  "tcp6|udp6|ah6|esp6|sctp6 [context %d] |\n"
 	  "		  rule %d ]\n" },
 	{ "-N|-U|--config-nfc|--config-ntuple", 1, do_srxclass,
 	  "Configure Rx network flow classification options or rules",
 	  "		rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|"
-	  "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... |\n"
+	  "tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... [context %d] |\n"
 	  "		flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4|"
 	  "ip6|tcp6|udp6|ah6|esp6|sctp6\n"
 	  "			[ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
@@ -5047,17 +5146,21 @@ static const struct option {
 	  "			[ user-def %x [m %x] ]\n"
 	  "			[ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
 	  "			[ action %d ] | [ vf %d queue %d ]\n"
+	  "			[ context %d ]\n"
 	  "			[ loc %d]] |\n"
 	  "		delete %d\n" },
 	{ "-T|--show-time-stamping", 1, do_tsinfo,
 	  "Show time stamping capabilities" },
 	{ "-x|--show-rxfh-indir|--show-rxfh", 1, do_grxfh,
-	  "Show Rx flow hash indirection table and/or RSS hash key" },
+	  "Show Rx flow hash indirection table and/or RSS hash key",
+	  "		[ context %d ]\n" },
 	{ "-X|--set-rxfh-indir|--rxfh", 1, do_srxfh,
 	  "Set Rx flow hash indirection table and/or RSS hash key",
+	  "		[ context %d|new ]\n"
 	  "		[ equal N | weight W0 W1 ... | default ]\n"
 	  "		[ hkey %x:%x:%x:%x:%x:.... ]\n"
-	  "		[ hfunc FUNC ]\n" },
+	  "		[ hfunc FUNC ]\n"
+	  "		[ delete ]\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" },
diff --git a/internal.h b/internal.h
index 4e658ea..913f4eb 100644
--- a/internal.h
+++ b/internal.h
@@ -332,11 +332,11 @@ int vmxnet3_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
 
 /* Rx flow classification */
 int rxclass_parse_ruleopts(struct cmd_context *ctx,
-			   struct ethtool_rx_flow_spec *fsp);
+			   struct ethtool_rx_flow_spec *fsp, __u32 *rss_context);
 int rxclass_rule_getall(struct cmd_context *ctx);
 int rxclass_rule_get(struct cmd_context *ctx, __u32 loc);
 int rxclass_rule_ins(struct cmd_context *ctx,
-		     struct ethtool_rx_flow_spec *fsp);
+		     struct ethtool_rx_flow_spec *fsp, __u32 rss_context);
 int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
 
 /* Module EEPROM parsing code */
diff --git a/rxclass.c b/rxclass.c
index e05031b..ce4b382 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -94,14 +94,15 @@ static void rxclass_print_nfc_spec_ext(struct ethtool_rx_flow_spec *fsp)
 	}
 }
 
-static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
+static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp,
+				   __u32 rss_context)
 {
 	unsigned char	*smac, *smacm, *dmac, *dmacm;
 	__u32		flow_type;
 
 	fprintf(stdout,	"Filter: %d\n", fsp->location);
 
-	flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT);
+	flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
 
 	invert_flow_mask(fsp);
 
@@ -247,6 +248,9 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
 
 	rxclass_print_nfc_spec_ext(fsp);
 
+	if (fsp->flow_type & FLOW_RSS)
+		fprintf(stdout, "\tRSS Context ID: %u\n", rss_context);
+
 	if (fsp->ring_cookie != RX_CLS_FLOW_DISC) {
 		u64 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
 		u64 queue = ethtool_get_flow_spec_ring(fsp->ring_cookie);
@@ -269,10 +273,11 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
 	fprintf(stdout, "\n");
 }
 
-static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
+static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp,
+			       __u32 rss_context)
 {
 	/* print the rule in this location */
-	switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
+	switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS)) {
 	case TCP_V4_FLOW:
 	case UDP_V4_FLOW:
 	case SCTP_V4_FLOW:
@@ -285,11 +290,11 @@ static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
 	case ESP_V6_FLOW:
 	case IPV6_USER_FLOW:
 	case ETHER_FLOW:
-		rxclass_print_nfc_rule(fsp);
+		rxclass_print_nfc_rule(fsp, rss_context);
 		break;
 	case IPV4_USER_FLOW:
 		if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4)
-			rxclass_print_nfc_rule(fsp);
+			rxclass_print_nfc_rule(fsp, rss_context);
 		else /* IPv6 uses IPV6_USER_FLOW */
 			fprintf(stderr, "IPV4_USER_FLOW with wrong ip_ver\n");
 		break;
@@ -333,7 +338,7 @@ int rxclass_rule_get(struct cmd_context *ctx, __u32 loc)
 	}
 
 	/* display rule */
-	rxclass_print_rule(&nfccmd.fs);
+	rxclass_print_rule(&nfccmd.fs, (__u32)nfccmd.rss_context);
 	return err;
 }
 
@@ -563,7 +568,7 @@ out:
 }
 
 int rxclass_rule_ins(struct cmd_context *ctx,
-		     struct ethtool_rx_flow_spec *fsp)
+		     struct ethtool_rx_flow_spec *fsp, __u32 rss_context)
 {
 	struct ethtool_rxnfc nfccmd;
 	__u32 loc = fsp->location;
@@ -581,6 +586,7 @@ int rxclass_rule_ins(struct cmd_context *ctx,
 
 	/* notify netdev of new rule */
 	nfccmd.cmd = ETHTOOL_SRXCLSRLINS;
+	nfccmd.rss_context = rss_context;
 	nfccmd.fs = *fsp;
 	err = send_ioctl(ctx, &nfccmd);
 	if (err < 0)
@@ -1254,7 +1260,7 @@ static int rxclass_get_mask(char *str, unsigned char *p,
 }
 
 int rxclass_parse_ruleopts(struct cmd_context *ctx,
-			   struct ethtool_rx_flow_spec *fsp)
+			   struct ethtool_rx_flow_spec *fsp, __u32 *rss_context)
 {
 	const struct rule_opts *options;
 	unsigned char *p = (unsigned char *)fsp;
@@ -1343,6 +1349,40 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
 	for (i = 1; i < argc;) {
 		const struct rule_opts *opt;
 		int idx;
+
+		/* special handling for 'context %d' as it doesn't go in
+		 * the struct ethtool_rx_flow_spec
+		 */
+		if (!strcmp(argp[i], "context")) {
+			unsigned long long val;
+
+			i++;
+			if (i >= argc) {
+				fprintf(stderr, "'context' missing value\n");
+				return -1;
+			}
+
+			if (rxclass_get_ulong(argp[i], &val, 32)) {
+				fprintf(stderr, "Invalid context value[%s]\n",
+					argp[i]);
+				return -1;
+			}
+
+			/* Can't use the ALLOC special value as the context ID
+			 * of a filter to insert
+			 */
+			if ((__u32)val == ETH_RXFH_CONTEXT_ALLOC) {
+				fprintf(stderr, "Bad context value %x\n",
+					(__u32)val);
+				return -1;
+			}
+
+			*rss_context = (__u32)val;
+			fsp->flow_type |= FLOW_RSS;
+			i++;
+			continue;
+		}
+
 		for (opt = options, idx = 0; idx < n_opts; idx++, opt++) {
 			char mask_name[16];
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH ethtool 3/3] ethtool.8: Document RSS context control and RSS filters
  2018-03-09 15:01 [PATCH ethtool 0/3] RSS ntuple filters Edward Cree
  2018-03-09 15:03 ` [PATCH ethtool 1/3] ethtool-copy.h: sync with net-next Edward Cree
  2018-03-09 15:04 ` [PATCH ethtool 2/3] ethtool: add support for extra RSS contexts and RSS steering filters Edward Cree
@ 2018-03-09 15:04 ` Edward Cree
  2018-03-12 18:51 ` [PATCH ethtool 0/3] RSS ntuple filters John W. Linville
  3 siblings, 0 replies; 5+ messages in thread
From: Edward Cree @ 2018-03-09 15:04 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 ethtool.8.in | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/ethtool.8.in b/ethtool.8.in
index 690e55e..99ac62f 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -274,6 +274,7 @@ ethtool \- query or control network driver and hardware settings
 .BM user\-def
 .RB [ dst-mac \ \*(MA\ [ m \ \*(MA]]
 .BN action
+.BN context
 .BN loc
 .RB |
 .br
@@ -303,6 +304,10 @@ ethtool \- query or control network driver and hardware settings
 .RB ...\ | \ default \ ]
 .RB [ hfunc
 .IR FUNC ]
+.RB [ context
+.I CTX
+.RB |\  new ]
+.RB [ delete ]
 .HP
 .B ethtool \-f|\-\-flash
 .I devname file
@@ -868,6 +873,13 @@ lB	l.
 0 or higher	Rx queue to route the flow
 .TE
 .TP
+.BI context \ N
+Specifies the RSS context to spread packets over multiple queues; either
+.B 0
+for the default RSS context, or a value returned by
+.BI ethtool\ -X\  ... \ context
+.BR new .
+.TP
 .BI vf \ N
 Specifies the Virtual Function the filter applies to. Not compatible with action.
 .TP
@@ -925,6 +937,22 @@ must be non-zero and must not exceed the size of the indirection table.
 .TP
 .BI default
 Sets the receive flow hash indirection table to its default value.
+.TP
+\fBcontext \fICTX\fR | \fBnew\fR
+Specifies an RSS context to act on; either 
+.B new 
+to allocate a new RSS context, or
+.IR CTX , 
+a value returned by a previous 
+.IB ... \ context 
+.BR new .
+.TP
+.B delete
+Delete the specified RSS context.  May only be used in conjunction with 
+.B context 
+and a non-zero 
+.I CTX 
+value.
 .RE
 .TP
 .B \-f \-\-flash

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH ethtool 0/3] RSS ntuple filters
  2018-03-09 15:01 [PATCH ethtool 0/3] RSS ntuple filters Edward Cree
                   ` (2 preceding siblings ...)
  2018-03-09 15:04 ` [PATCH ethtool 3/3] ethtool.8: Document RSS context control and RSS filters Edward Cree
@ 2018-03-12 18:51 ` John W. Linville
  3 siblings, 0 replies; 5+ messages in thread
From: John W. Linville @ 2018-03-12 18:51 UTC (permalink / raw)
  To: Edward Cree; +Cc: netdev

On Fri, Mar 09, 2018 at 03:01:58PM +0000, Edward Cree wrote:
> This series adds support for the management of extra RSS contexts and RSS
>  spreading of ntuple/NFC filters introduced in kernel commit 84a1d9c48200
>  ("net: ethtool: extend RXNFC API to support RSS spreading of filter matches").
> 
> Edward Cree (3):
>   ethtool-copy.h: sync with net-next
>   ethtool: add support for extra RSS contexts and RSS steering filters
>   ethtool.8: Document RSS context control and RSS filters
> 
>  ethtool-copy.h |  32 ++++++++++---
>  ethtool.8.in   |  28 ++++++++++++
>  ethtool.c      | 141 +++++++++++++++++++++++++++++++++++++++++++++++++--------
>  internal.h     |   4 +-
>  rxclass.c      |  58 ++++++++++++++++++++----
>  5 files changed, 227 insertions(+), 36 deletions(-)
> 

LGTM -- queued for the next release...thanks!

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-03-12 19:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-09 15:01 [PATCH ethtool 0/3] RSS ntuple filters Edward Cree
2018-03-09 15:03 ` [PATCH ethtool 1/3] ethtool-copy.h: sync with net-next Edward Cree
2018-03-09 15:04 ` [PATCH ethtool 2/3] ethtool: add support for extra RSS contexts and RSS steering filters Edward Cree
2018-03-09 15:04 ` [PATCH ethtool 3/3] ethtool.8: Document RSS context control and RSS filters Edward Cree
2018-03-12 18:51 ` [PATCH ethtool 0/3] RSS ntuple filters John W. Linville

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).