All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.