Skip to contentSkip to conversation

ethdev: AGE action preparation

PATCH Superseded Michael Baum 3 participants 32 messages Sep 21, 2022 – Oct 28, 2022

lore
Share & tools
lore
#0 lore raw

cover ethdev: AGE action preparation

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

Michael Baum (3):
ethdev: add strict queue to pre-configuration flow hints
ethdev: add queue-based API to report aged flow rules
ethdev: add structure for indirect AGE update

 app/test-pmd/cmdline_flow.c                 |  93 +++++++++-
 app/test-pmd/config.c                       | 177 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  90 +++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  89 +++++++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   3 +
 9 files changed, 491 insertions(+), 16 deletions(-)
Signature · 1 line
2.25.1
#1 lore raw

PATCH 1/3 ethdev: add strict queue to pre-configuration flow hints

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

This patch add flag about above situation and could be extended to cover more situations.

---
 app/test-pmd/cmdline_flow.c                 | 10 ++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++--
 lib/ethdev/rte_flow.h                       | 14 ++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)
app/test-pmd/cmdline_flow.c +10 -0
index 7f50028eb7..a982083d27 100644
@@ -219,6 +219,7 @@ enum index {
 	CONFIG_COUNTERS_NUMBER,
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
+	CONFIG_FLAGS,
 
 	/* Indirect action arguments */
 	INDIRECT_ACTION_CREATE,
@@ -1081,6 +1082,7 @@ static const enum index next_config_attr[] = {
 	CONFIG_COUNTERS_NUMBER,
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
+	CONFIG_FLAGS,
 	END,
 	ZERO,
 };
@@ -2667,6 +2669,14 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.configure.port_attr.nb_meters)),
 	},
+	[CONFIG_FLAGS] = {
+		.name = "flags",
+		.help = "configuration flags",
+		.next = NEXT(next_config_attr,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.configure.port_attr.flags)),
+	},
 	/* Top-level command. */
 	[PATTERN_TEMPLATE] = {
 		.name = "pattern_template",
doc/guides/testpmd_app_ug/testpmd_funcs.rst +2 -2
index 330e34427d..6c12e0286c 100644
@@ -3082,7 +3082,7 @@ following sections.
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 - Create a pattern template::
    flow pattern_template {port_id} create [pattern_template_id {id}]
@@ -3233,7 +3233,7 @@ for asynchronous flow creation/destruction operations. It is bound to
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 If successful, it will show::
 
lib/ethdev/rte_flow.h +14 -0
index a79f1e7ef0..c552771472 100644
@@ -4874,6 +4874,12 @@ rte_flow_flex_item_release(uint16_t port_id,
 			   const struct rte_flow_item_flex_handle *handle,
 			   struct rte_flow_error *error);
 
+/**
+ * Indicate all operations for a given flow rule will _strictly_
+ * happen on the same queue (create/destroy/query/update).
+ */
+#define RTE_FLOW_PORT_FLAG_STRICT_QUEUE RTE_BIT32(0)
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4902,6 +4908,10 @@ struct rte_flow_port_info {
 	 * @see RTE_FLOW_ACTION_TYPE_METER
 	 */
 	uint32_t max_nb_meters;
+	/**
+	 * Port supported flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t supported_flags;
 };
 
 /**
@@ -4971,6 +4981,10 @@ struct rte_flow_port_attr {
 	 * @see RTE_FLOW_ACTION_TYPE_METER
 	 */
 	uint32_t nb_meters;
+	/**
+	 * Port flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t flags;
 };
 
 /**
Signature · 1 line
2.25.1
Acked-by on v1 1/3
#2 lore raw

RE: [PATCH 1/3] ethdev: add strict queue to pre-configuration flow hints

Hi Michael,

Quoted 18 lines

-----Original Message-----
From: Michael Baum <[email protected]>
Sent: Wednesday, 21 September 2022 17:54

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

Quoted 5 lines

This patch add flag about above situation and could be extended to cover more situations.

---

Thanks,
Ori

#3 lore raw

PATCH 2/3 ethdev: add queue-based API to report aged flow rules

In reply to Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

---
 app/test-pmd/cmdline_flow.c                 |  17 ++-
 app/test-pmd/config.c                       | 159 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  86 ++++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  48 +++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   3 +
 8 files changed, 333 insertions(+), 10 deletions(-)
app/test-pmd/cmdline_flow.c +15 -2
index a982083d27..4fb90a92cb 100644
@@ -127,6 +127,7 @@ enum index {
 	/* Queue arguments. */
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
@@ -1159,6 +1160,7 @@ static const enum index next_table_destroy_attr[] = {
 static const enum index next_queue_subcmd[] = {
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 	ZERO,
 };
@@ -2942,6 +2944,13 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
 		.call = parse_qo_destroy,
 	},
+	[QUEUE_AGED] = {
+		.name = "aged",
+		.help = "list and destroy aged flows",
+		.next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)),
+		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+		.call = parse_aged,
+	},
 	[QUEUE_INDIRECT_ACTION] = {
 		.name = "indirect_action",
 		.help = "queue indirect actions",
@@ -8640,8 +8649,8 @@ parse_aged(struct context *ctx, const struct token *token,
 	/* Nothing else to do if there is no buffer. */
 	if (!out)
 		return len;
-	if (!out->command) {
-		if (ctx->curr != AGED)
+	if (!out->command || out->command == QUEUE) {
+		if (ctx->curr != AGED && ctx->curr != QUEUE_AGED)
 			return -1;
 		if (sizeof(*out) > size)
 			return -1;
@@ -10496,6 +10505,10 @@ cmd_flow_parsed(const struct buffer *in)
 	case PULL:
 		port_queue_flow_pull(in->port, in->queue);
 		break;
+	case QUEUE_AGED:
+		port_queue_flow_aged(in->port, in->queue,
+				     in->args.aged.destroy);
+		break;
 	case QUEUE_INDIRECT_ACTION_CREATE:
 		port_queue_action_handle_create(
 				in->port, in->queue, in->postpone,
app/test-pmd/config.c +158 -1

177 lines not on this page · raw message

app/test-pmd/testpmd.h +1 -0
index fb2f5195d3..4e24dd9ee0 100644
@@ -982,6 +982,7 @@ int port_queue_action_handle_update(portid_t port_id, uint32_t queue_id,
 				    const struct rte_flow_action *action);
 int port_queue_flow_push(portid_t port_id, queueid_t queue_id);
 int port_queue_flow_pull(portid_t port_id, queueid_t queue_id);
+void port_queue_flow_aged(portid_t port_id, uint32_t queue_id, uint8_t destroy);
 int port_flow_validate(portid_t port_id,
 		       const struct rte_flow_attr *attr,
 		       const struct rte_flow_item *pattern,
doc/guides/testpmd_app_ug/testpmd_funcs.rst +81 -5

126 lines not on this page · raw message

lib/ethdev/rte_flow.c +22 -0
index 501be9d602..5c95ac7f8b 100644
@@ -1133,6 +1133,28 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
 				  NULL, rte_strerror(ENOTSUP));
 }
 
+int
+rte_flow_get_q_aged_flows(uint16_t port_id, uint32_t queue_id, void **contexts,
+			  uint32_t nb_contexts, struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	int ret;
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->get_q_aged_flows)) {
+		fts_enter(dev);
+		ret = ops->get_q_aged_flows(dev, queue_id, contexts,
+					    nb_contexts, error);
+		fts_exit(dev);
+		return flow_err(port_id, ret, error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
 struct rte_flow_action_handle *
 rte_flow_action_handle_create(uint16_t port_id,
 			      const struct rte_flow_indir_action_conf *conf,
lib/ethdev/rte_flow.h +46 -2

60 lines not on this page · raw message

lib/ethdev/rte_flow_driver.h +7 -0
index 2bff732d6a..f0a03bf149 100644
@@ -84,6 +84,13 @@ struct rte_flow_ops {
 		 void **context,
 		 uint32_t nb_contexts,
 		 struct rte_flow_error *err);
+	/** See rte_flow_get_q_aged_flows() */
+	int (*get_q_aged_flows)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 void **contexts,
+		 uint32_t nb_contexts,
+		 struct rte_flow_error *error);
 	/** See rte_flow_action_handle_create() */
 	struct rte_flow_action_handle *(*action_handle_create)
 		(struct rte_eth_dev *dev,
lib/ethdev/version.map +3 -0
index 03f52fee91..4a40d24d8f 100644
@@ -285,6 +285,9 @@ EXPERIMENTAL {
 	rte_mtr_color_in_protocol_priority_get;
 	rte_mtr_color_in_protocol_set;
 	rte_mtr_meter_vlan_table_update;
+
+	# added in 22.11
+	rte_flow_get_q_aged_flows;
 };
 
 INTERNAL {
Signature · 1 line
2.25.1
Acked-by on v1 2/3
#4 lore raw

RE: [PATCH 2/3] ethdev: add queue-based API to report aged flow rules

Hi Michael,

Quoted 12 lines

-----Original Message-----
From: Michael Baum <[email protected]>
Sent: Wednesday, 21 September 2022 17:54

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

Quoted 8 lines

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate
a given flow rule on different queues, the queue id parameter will be ignored.

---

Thanks,
Ori

#5 lore raw

PATCH 3/3 ethdev: add structure for indirect AGE update

In reply to Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
 app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
 app/test-pmd/config.c              | 18 +++++++-
 doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
 lib/ethdev/rte_flow.h              | 27 ++++++++++++
 4 files changed, 132 insertions(+), 4 deletions(-)
app/test-pmd/cmdline_flow.c +66 -0
index 4fb90a92cb..a315fd9ded 100644
@@ -583,6 +583,9 @@ enum index {
 	ACTION_SET_IPV6_DSCP_VALUE,
 	ACTION_AGE,
 	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
 	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
 	ACTION_SET_IPV4_DSCP,
 	ACTION_SET_IPV6_DSCP,
 	ACTION_AGE,
+	ACTION_AGE_UPDATE,
 	ACTION_SAMPLE,
 	ACTION_INDIRECT,
 	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
 	ZERO,
 };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_sample[] = {
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
 		.next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_SAMPLE] = {
 		.name = "sample",
 		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
 /** Parse eCPRI common header type field. */
 static int
 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +17 -1
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	if (!pia)
 		return -EINVAL;
 	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
 	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
 		update = action->conf;
 		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t port_id,
 	struct rte_port *port;
 	struct rte_flow_error error;
 	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
 	action_handle = port_action_handle_get_by_id(port_id, id);
 	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t port_id,
 		return -EINVAL;
 	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
 	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
 		return port_flow_complain(&error);
 	}
 	printf("Indirect action #%u update queued\n", id);
doc/guides/prog_guide/rte_flow.rst +22 -3
index 588914b231..dae9121279 100644
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
 Action: ``AGE``
 ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
 Event RTE_ETH_EVENT_FLOW_AGED will be reported if
 timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the flow.
    | ``context``  | user input flow context         |
    +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
 .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the AGE action:
    | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
    +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+   +===================+==============================================================+
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0  |
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
 Action: ``SAMPLE``
 ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +27 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
 	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
Signature · 1 line
2.25.1
Acked-by on v1 3/3
#6 lore raw

RE: [PATCH 3/3] ethdev: add structure for indirect AGE update

Hi Michael,

Quoted 6 lines

-----Original Message-----
From: Michael Baum <[email protected]>
Sent: Wednesday, 21 September 2022 17:54

Add a new structure for indirect AGE update.

Quoted 8 lines

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---

Best,
Ori

#7 lore raw

Re: [PATCH 3/3] ethdev: add structure for indirect AGE update

In reply to Michael Baum
Quoted 240 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
  app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
  app/test-pmd/config.c              | 18 +++++++-
  doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
  lib/ethdev/rte_flow.h              | 27 ++++++++++++
  4 files changed, 132 insertions(+), 4 deletions(-)
app/test-pmd/cmdline_flow.c +66 -0
index 4fb90a92cb..a315fd9ded 100644
@@ -583,6 +583,9 @@ enum index {
  	ACTION_SET_IPV6_DSCP_VALUE,
  	ACTION_AGE,
  	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
  	ACTION_SAMPLE,
  	ACTION_SAMPLE_RATIO,
  	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
  	ACTION_SET_IPV4_DSCP,
  	ACTION_SET_IPV6_DSCP,
  	ACTION_AGE,
+	ACTION_AGE_UPDATE,
  	ACTION_SAMPLE,
  	ACTION_INDIRECT,
  	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
  	ZERO,
  };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
  static const enum index action_sample[] = {
  	ACTION_SAMPLE,
  	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const struct token *,
  			 const char *, unsigned int, void *, unsigned int);
  static int parse_vc_conf(struct context *, const struct token *,
  			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
  static int parse_vc_item_ecpri_type(struct context *, const struct token *,
  				    const char *, unsigned int,
  				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
  		.next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
  		.call = parse_vc_conf,
  	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
  	[ACTION_SAMPLE] = {
  		.name = "sample",
  		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const struct token *token,
  	return len;
  }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
  /** Parse eCPRI common header type field. */
  static int
  parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +17 -1
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
  	if (!pia)
  		return -EINVAL;
  	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
  	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
  		update = action->conf;
  		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t port_id,
  	struct rte_port *port;
  	struct rte_flow_error error;
  	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
  	action_handle = port_action_handle_get_by_id(port_id, id);
  	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t port_id,
  		return -EINVAL;
  	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
  	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
  		return port_flow_complain(&error);
  	}
  	printf("Indirect action #%u update queued\n", id);
doc/guides/prog_guide/rte_flow.rst +22 -3
index 588914b231..dae9121279 100644
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
  Action: ``AGE``
  ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
  Event RTE_ETH_EVENT_FLOW_AGED will be reported if
  timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the flow.
     | ``context``  | user input flow context         |
     +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
  .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the AGE action:
     | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
     +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+   +===================+==============================================================+
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0  |
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
  Action: ``SAMPLE``
  ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +10 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
  	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
  };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2976

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 5 lines
lib/ethdev/rte_flow.h +5 -0
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

One more question: why order in the documentation above does not match order here?

Quoted 5 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
  /**
   * @warning
   * @b EXPERIMENTAL: this structure may change without prior notice
#8 lore raw

RE: [PATCH 3/3] ethdev: add structure for indirect AGE update

Hi Andrew,

Quoted 275 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 11:04

Quoted 11 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
  app/test-pmd/cmdline_flow.c        | 66

++++++++++++++++++++++++++++++

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const

Quoted 43 lines
  app/test-pmd/config.c              | 18 +++++++-
  doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
  lib/ethdev/rte_flow.h              | 27 ++++++++++++
  4 files changed, 132 insertions(+), 4 deletions(-)
app/test-pmd/cmdline_flow.c +12 -0
index 4fb90a92cb..a315fd9ded 100644
@@ -583,6 +583,9 @@ enum index {
  	ACTION_SET_IPV6_DSCP_VALUE,
  	ACTION_AGE,
  	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
  	ACTION_SAMPLE,
  	ACTION_SAMPLE_RATIO,
  	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
  	ACTION_SET_IPV4_DSCP,
  	ACTION_SET_IPV6_DSCP,
  	ACTION_AGE,
+	ACTION_AGE_UPDATE,
  	ACTION_SAMPLE,
  	ACTION_INDIRECT,
  	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
  	ZERO,
  };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
  static const enum index action_sample[] = {
  	ACTION_SAMPLE,
  	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const

struct token *,

app/test-pmd/cmdline_flow.c static const struct token token_list[] = { · line 6209

Quoted 11 lines
app/test-pmd/cmdline_flow.c +3 -0
  			 const char *, unsigned int, void *, unsigned int);
  static int parse_vc_conf(struct context *, const struct token *,
  			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
  static int parse_vc_item_ecpri_type(struct context *, const struct token *,
  				    const char *, unsigned int,
  				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
  		.next = NEXT(action_age,

NEXT_ENTRY(COMMON_UNSIGNED)),

Quoted 6 lines
app/test-pmd/cmdline_flow.c +4 -0
  		.call = parse_vc_conf,
  	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 10 lines
app/test-pmd/cmdline_flow.c +10 -0
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_UNSIGNED)),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 6 lines
app/test-pmd/cmdline_flow.c +6 -0
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_BOOLEAN)),

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const struct

Quoted 8 lines
app/test-pmd/cmdline_flow.c +4 -0
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
  	[ACTION_SAMPLE] = {
  		.name = "sample",
  		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const struct

token *token,

app/test-pmd/config.c port_action_handle_update(portid_t port_id,

Quoted 38 lines
app/test-pmd/cmdline_flow.c +27 -0
  	return len;
  }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
  /** Parse eCPRI common header type field. */
  static int
  parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +0 -0
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id,

uint32_t id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 8 lines
app/test-pmd/config.c +1 -0
  	if (!pia)
  		return -EINVAL;
  	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
  	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
  		update = action->conf;
  		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t

port_id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 9 lines
app/test-pmd/config.c +2 -0
  	struct rte_port *port;
  	struct rte_flow_error error;
  	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
  	action_handle = port_action_handle_get_by_id(port_id, id);
  	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t

port_id,

Review

Quoted 23 lines
app/test-pmd/config.c +14 -1
  		return -EINVAL;
  	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
  	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
  		return port_flow_complain(&error);
  	}
  	printf("Indirect action #%u update queued\n", id);
(quoted diff) +0 -0

b/doc/guides/prog_guide/rte_flow.rst

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

Quoted 4 lines

index 588914b231..dae9121279 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

error will be returned.

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on the

Quoted 9 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
  Action: ``AGE``
  ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
  Event RTE_ETH_EVENT_FLOW_AGED will be reported if
  timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the

flow.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE

Quoted 11 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
     | ``context``  | user input flow context         |
     +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
  .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the AGE

action:

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
     | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
     +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()``

function.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action: · line 3015

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +8 -0
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+

+===================+=====================================
=========================+

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +5 -0
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0

|

Quoted 16 lines
doc/guides/prog_guide/rte_flow.rst +4 -0
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
  Action: ``SAMPLE``
  ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +1 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
  	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
  };
 
+/**

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2967

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *

+=============+=============+=============================
=+

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2976

Quoted 9 lines
lib/ethdev/rte_flow.h +9 -0
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
Quoted 2 lines

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

What do you mean?

Quoted 11 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 6 lines
lib/ethdev/rte_flow.h +5 -0
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

+1

Quoted 3 lines

One more question: why order in the documentation above does not match order here?

I think we can remove it from the documentation since it doesn't add anything

Quoted 5 lines
Quoted 5 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
  /**
   * @warning
   * @b EXPERIMENTAL: this structure may change without prior notice
#9 lore raw

Re: [PATCH 3/3] ethdev: add structure for indirect AGE update

Quoted 277 lines · Ori Kam

Hi Andrew,

Quoted 275 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 11:04

Quoted 11 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
   app/test-pmd/cmdline_flow.c        | 66

++++++++++++++++++++++++++++++

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const

Quoted 43 lines
   app/test-pmd/config.c              | 18 +++++++-
   doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
   lib/ethdev/rte_flow.h              | 27 ++++++++++++
   4 files changed, 132 insertions(+), 4 deletions(-)
app/test-pmd/cmdline_flow.c +12 -0
index 4fb90a92cb..a315fd9ded 100644
@@ -583,6 +583,9 @@ enum index {
   	ACTION_SET_IPV6_DSCP_VALUE,
   	ACTION_AGE,
   	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
   	ACTION_SAMPLE,
   	ACTION_SAMPLE_RATIO,
   	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
   	ACTION_SET_IPV4_DSCP,
   	ACTION_SET_IPV6_DSCP,
   	ACTION_AGE,
+	ACTION_AGE_UPDATE,
   	ACTION_SAMPLE,
   	ACTION_INDIRECT,
   	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
   	ZERO,
   };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
   static const enum index action_sample[] = {
   	ACTION_SAMPLE,
   	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const

struct token *,

app/test-pmd/cmdline_flow.c static const struct token token_list[] = { · line 6209

Quoted 11 lines
app/test-pmd/cmdline_flow.c +3 -0
   			 const char *, unsigned int, void *, unsigned int);
   static int parse_vc_conf(struct context *, const struct token *,
   			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
   static int parse_vc_item_ecpri_type(struct context *, const struct token *,
   				    const char *, unsigned int,
   				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
   		.next = NEXT(action_age,

NEXT_ENTRY(COMMON_UNSIGNED)),

Quoted 6 lines
app/test-pmd/cmdline_flow.c +4 -0
   		.call = parse_vc_conf,
   	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 10 lines
app/test-pmd/cmdline_flow.c +10 -0
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_UNSIGNED)),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 6 lines
app/test-pmd/cmdline_flow.c +6 -0
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_BOOLEAN)),

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const struct

Quoted 8 lines
app/test-pmd/cmdline_flow.c +4 -0
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
   	[ACTION_SAMPLE] = {
   		.name = "sample",
   		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const struct

token *token,

app/test-pmd/config.c port_action_handle_update(portid_t port_id,

Quoted 38 lines
app/test-pmd/cmdline_flow.c +27 -0
   	return len;
   }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
   /** Parse eCPRI common header type field. */
   static int
   parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +0 -0
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id,

uint32_t id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 8 lines
app/test-pmd/config.c +1 -0
   	if (!pia)
   		return -EINVAL;
   	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
   	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
   		update = action->conf;
   		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t

port_id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 9 lines
app/test-pmd/config.c +2 -0
   	struct rte_port *port;
   	struct rte_flow_error error;
   	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
   	action_handle = port_action_handle_get_by_id(port_id, id);
   	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t

port_id,

Review

Quoted 23 lines
app/test-pmd/config.c +14 -1
   		return -EINVAL;
   	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
   	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
   		return port_flow_complain(&error);
   	}
   	printf("Indirect action #%u update queued\n", id);
(quoted diff) +0 -0

b/doc/guides/prog_guide/rte_flow.rst

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

Quoted 4 lines

index 588914b231..dae9121279 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

error will be returned.

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on the

Quoted 9 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
   Action: ``AGE``
   ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
   Event RTE_ETH_EVENT_FLOW_AGED will be reported if
   timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the

flow.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE

Quoted 11 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
      | ``context``  | user input flow context         |
      +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
   .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the AGE

action:

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
      | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
      +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()``

function.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action: · line 3015

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +8 -0
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+

+===================+=====================================
=========================+

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +5 -0
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0

|

Quoted 16 lines
doc/guides/prog_guide/rte_flow.rst +4 -0
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
   Action: ``SAMPLE``
   ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +1 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
   	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
   };
 
+/**

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2967

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *

+=============+=============+=============================
=+

Quoted 9 lines
lib/ethdev/rte_flow.h +9 -0
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
Quoted 4 lines
Quoted 2 lines

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

What do you mean?

RTE_FLOW_ACTION_TYPE_AGE has a description as enum member. Typically configuration structures are mentioned there. However, I think that it would be useful to mention specific update structure if any. Like this one. Just to make it clear that if a user wants to update the action configuration it should use specific structure. Or am I missing something? Misunderstand something?

Quoted 27 lines
Quoted 12 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 7 lines
lib/ethdev/rte_flow.h +5 -0
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

+1

Quoted 3 lines

One more question: why order in the documentation above does not match order here?

I think we can remove it from the documentation since it doesn't add anything

Quoted 5 lines
Quoted 5 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
   /**
    * @warning
    * @b EXPERIMENTAL: this structure may change without prior notice
#10 lore raw

RE: [PATCH 3/3] ethdev: add structure for indirect AGE update

Hi Andrew,

Quoted 293 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 16:18

Quoted 18 lines · Ori Kam

Hi Andrew,

Quoted 16 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 11:04

Quoted 11 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
   app/test-pmd/cmdline_flow.c        | 66
Quoted 7 lines
Quoted 7 lines

++++++++++++++++++++++++++++++

app/test-

Quoted 6 lines
   app/test-pmd/config.c              | 18 +++++++-
   doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
   lib/ethdev/rte_flow.h              | 27 ++++++++++++
   4 files changed, 132 insertions(+), 4 deletions(-)
app/test- renamed from app/test-pmd/cmdline_flow.c +0 -0

pmd/cmdline_flow.c

Quoted 38 lines
Quoted 38 lines

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const

Quoted 37 lines

index 4fb90a92cb..a315fd9ded 100644

app/test-pmd/cmdline_flow.c +12 -0
@@ -583,6 +583,9 @@ enum index {
   	ACTION_SET_IPV6_DSCP_VALUE,
   	ACTION_AGE,
   	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
   	ACTION_SAMPLE,
   	ACTION_SAMPLE_RATIO,
   	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
   	ACTION_SET_IPV4_DSCP,
   	ACTION_SET_IPV6_DSCP,
   	ACTION_AGE,
+	ACTION_AGE_UPDATE,
   	ACTION_SAMPLE,
   	ACTION_INDIRECT,
   	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
   	ZERO,
   };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
   static const enum index action_sample[] = {
   	ACTION_SAMPLE,
   	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const

struct token *,

Quoted 7 lines
Quoted 7 lines

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const struct token *,

Quoted 7 lines
app/test-pmd/cmdline_flow.c +3 -0
   			 const char *, unsigned int, void *, unsigned int);
   static int parse_vc_conf(struct context *, const struct token *,
   			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
   static int parse_vc_item_ecpri_type(struct context *, const struct token

*,

Quoted 29 lines
Quoted 29 lines

app/test-pmd/cmdline_flow.c static const struct token token_list[] = { · line 6209

Quoted 4 lines
app/test-pmd/cmdline_flow.c +0 -0
   				    const char *, unsigned int,
   				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
   		.next = NEXT(action_age,

NEXT_ENTRY(COMMON_UNSIGNED)),

Quoted 6 lines
app/test-pmd/cmdline_flow.c +4 -0
   		.call = parse_vc_conf,
   	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 10 lines
app/test-pmd/cmdline_flow.c +10 -0
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_UNSIGNED)),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 6 lines
app/test-pmd/cmdline_flow.c +6 -0
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_BOOLEAN)),

Quoted 8 lines
Quoted 8 lines

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const

Quoted 8 lines
app/test-pmd/cmdline_flow.c +4 -0
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
   	[ACTION_SAMPLE] = {
   		.name = "sample",
   		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const

struct

Quoted 26 lines
Quoted 26 lines

token *token,

Quoted 25 lines
app/test-pmd/cmdline_flow.c +22 -0
   	return len;
   }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
Quoted 8 lines
Quoted 8 lines

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const struct token *token,

Quoted 8 lines
app/test-pmd/cmdline_flow.c +5 -0
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
   /** Parse eCPRI common header type field. */
   static int
   parse_vc_item_ecpri_type(struct context *ctx, const struct token

*token,

Quoted 67 lines
Quoted 67 lines

app/test-pmd/config.c port_action_handle_update(portid_t port_id,

Quoted 5 lines
app/test-pmd/config.c +0 -0
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id,

uint32_t id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 8 lines
app/test-pmd/config.c +1 -0
   	if (!pia)
   		return -EINVAL;
   	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
   	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
   		update = action->conf;
   		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t

port_id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 9 lines
app/test-pmd/config.c +2 -0
   	struct rte_port *port;
   	struct rte_flow_error error;
   	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
   	action_handle = port_action_handle_get_by_id(port_id, id);
   	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t

port_id,

Review

Quoted 23 lines
app/test-pmd/config.c +14 -1
   		return -EINVAL;
   	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
   	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
   		return port_flow_complain(&error);
   	}
   	printf("Indirect action #%u update queued\n", id);
(quoted diff) +0 -0

b/doc/guides/prog_guide/rte_flow.rst

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

Quoted 4 lines

index 588914b231..dae9121279 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

error will be returned.

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on the

Quoted 9 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
   Action: ``AGE``
   ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
   Event RTE_ETH_EVENT_FLOW_AGED will be reported if
   timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the

flow.

Quoted 3 lines
doc/guides/prog_guide/rte_flow.rst +0 -0
      | ``context``  | user input flow context         |
      +--------------+---------------------------------+
 
Quoted 8 lines
Quoted 8 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
   .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the

AGE

Quoted 17 lines
Quoted 17 lines

action:

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
      | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
      +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()``

function.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action: · line 3015

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +8 -0
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+

+===================+=====================================
=========================+

Quoted 5 lines
Quoted 5 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +5 -0
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set

``sec_since_last_hit`` 0

Quoted 39 lines
Quoted 39 lines

|

Quoted 16 lines
doc/guides/prog_guide/rte_flow.rst +4 -0
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
   Action: ``SAMPLE``
   ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +1 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
   	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
   };
 
+/**

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2967

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *

+=============+=============+=============================
=+

Quoted 9 lines
lib/ethdev/rte_flow.h +9 -0
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
Quoted 4 lines
Quoted 2 lines

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

What do you mean?

Quoted 8 lines

RTE_FLOW_ACTION_TYPE_AGE has a description as enum member. Typically configuration structures are mentioned there. However, I think that it would be useful to mention specific update structure if any. Like this one. Just to make it clear that if a user wants to update the action configuration it should use specific structure. Or am I missing something? Misunderstand something?

Do you mean something like:
* see enum RTE_ETH_EVENT_FLOW_AGED
* See struct rte_flow_query_age
+ See struct rte_flow_update_age
*/
RTE_FLOW_ACTION_TYPE_AGE,
If so, I fully agree.

Quoted 28 lines
Quoted 13 lines
Quoted 12 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 7 lines
lib/ethdev/rte_flow.h +5 -0
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

Quoted 7 lines

+1

Quoted 3 lines

One more question: why order in the documentation above does not match order here?

I think we can remove it from the documentation since it doesn't add

anything

Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
   /**
    * @warning
    * @b EXPERIMENTAL: this structure may change without prior notice
#11 lore raw

Re: [PATCH 3/3] ethdev: add structure for indirect AGE update

Quoted 304 lines · Ori Kam

Hi Andrew,

Quoted 293 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 16:18

Quoted 18 lines · Ori Kam

Hi Andrew,

Quoted 16 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 11:04

Quoted 11 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
    app/test-pmd/cmdline_flow.c        | 66
Quoted 7 lines
Quoted 7 lines

++++++++++++++++++++++++++++++

app/test-

Quoted 6 lines
    app/test-pmd/config.c              | 18 +++++++-
    doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
    lib/ethdev/rte_flow.h              | 27 ++++++++++++
    4 files changed, 132 insertions(+), 4 deletions(-)
app/test- renamed from app/test-pmd/cmdline_flow.c +0 -0

pmd/cmdline_flow.c

Quoted 38 lines
Quoted 38 lines

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const

Quoted 37 lines

index 4fb90a92cb..a315fd9ded 100644

app/test-pmd/cmdline_flow.c +12 -0
@@ -583,6 +583,9 @@ enum index {
    	ACTION_SET_IPV6_DSCP_VALUE,
    	ACTION_AGE,
    	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
    	ACTION_SAMPLE,
    	ACTION_SAMPLE_RATIO,
    	ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
    	ACTION_SET_IPV4_DSCP,
    	ACTION_SET_IPV6_DSCP,
    	ACTION_AGE,
+	ACTION_AGE_UPDATE,
    	ACTION_SAMPLE,
    	ACTION_INDIRECT,
    	ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
    	ZERO,
    };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
    static const enum index action_sample[] = {
    	ACTION_SAMPLE,
    	ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *, const

struct token *,

Quoted 7 lines
Quoted 7 lines

app/test-pmd/cmdline_flow.c static int parse_vc_spec(struct context *, const struct token *,

Quoted 7 lines
app/test-pmd/cmdline_flow.c +3 -0
    			 const char *, unsigned int, void *, unsigned int);
    static int parse_vc_conf(struct context *, const struct token *,
    			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
    static int parse_vc_item_ecpri_type(struct context *, const struct token

*,

Quoted 29 lines
Quoted 29 lines

app/test-pmd/cmdline_flow.c static const struct token token_list[] = { · line 6209

Quoted 4 lines
app/test-pmd/cmdline_flow.c +0 -0
    				    const char *, unsigned int,
    				    void *, unsigned int);
@@ -6194,6 +6209,30 @@ static const struct token token_list[] = {
    		.next = NEXT(action_age,

NEXT_ENTRY(COMMON_UNSIGNED)),

Quoted 6 lines
app/test-pmd/cmdline_flow.c +4 -0
    		.call = parse_vc_conf,
    	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 10 lines
app/test-pmd/cmdline_flow.c +10 -0
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_UNSIGNED)),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 6 lines
app/test-pmd/cmdline_flow.c +6 -0
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_BOOLEAN)),

Quoted 8 lines
Quoted 8 lines

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const

Quoted 8 lines
app/test-pmd/cmdline_flow.c +4 -0
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
    	[ACTION_SAMPLE] = {
    		.name = "sample",
    		.help = "set a sample action",
@@ -7031,6 +7070,33 @@ parse_vc_conf(struct context *ctx, const

struct

Quoted 26 lines
Quoted 26 lines

token *token,

Quoted 25 lines
app/test-pmd/cmdline_flow.c +22 -0
    	return len;
    }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
Quoted 8 lines
Quoted 8 lines

app/test-pmd/cmdline_flow.c parse_vc_conf(struct context *ctx, const struct token *token,

Quoted 8 lines
app/test-pmd/cmdline_flow.c +5 -0
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
    /** Parse eCPRI common header type field. */
    static int
    parse_vc_item_ecpri_type(struct context *ctx, const struct token

*token,

Quoted 67 lines
Quoted 67 lines

app/test-pmd/config.c port_action_handle_update(portid_t port_id,

Quoted 5 lines
app/test-pmd/config.c +0 -0
index 31952467fb..45495385d7 100644
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t port_id,

uint32_t id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 8 lines
app/test-pmd/config.c +1 -0
    	if (!pia)
    		return -EINVAL;
    	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
    	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
    		update = action->conf;
    		break;
@@ -2904,6 +2905,8 @@ port_queue_action_handle_update(portid_t

port_id,

app/test-pmd/config.c port_queue_action_handle_update(portid_t

Quoted 9 lines
app/test-pmd/config.c +2 -0
    	struct rte_port *port;
    	struct rte_flow_error error;
    	struct rte_flow_action_handle *action_handle;
+	struct port_indirect_action *pia;
+	const void *update;
 
    	action_handle = port_action_handle_get_by_id(port_id, id);
    	if (!action_handle)
@@ -2915,8 +2918,21 @@ port_queue_action_handle_update(portid_t

port_id,

Review

Quoted 23 lines
app/test-pmd/config.c +14 -1
    		return -EINVAL;
    	}
 
+	pia = action_get_by_id(port_id, id);
+	if (!pia)
+		return -EINVAL;
+
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	default:
+		update = action;
+		break;
+	}
+
    	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
-				    action_handle, action, NULL, &error)) {
+				    action_handle, update, NULL, &error)) {
    		return port_flow_complain(&error);
    	}
    	printf("Indirect action #%u update queued\n", id);
(quoted diff) +0 -0

b/doc/guides/prog_guide/rte_flow.rst

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

Quoted 4 lines

index 588914b231..dae9121279 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2958,7 +2958,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION

error will be returned.

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on the

Quoted 9 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
    Action: ``AGE``
    ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
    Event RTE_ETH_EVENT_FLOW_AGED will be reported if
    timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on the

flow.

Quoted 3 lines
doc/guides/prog_guide/rte_flow.rst +0 -0
       | ``context``  | user input flow context         |
       +--------------+---------------------------------+
 
Quoted 8 lines
Quoted 8 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
    .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the

AGE

Quoted 17 lines
Quoted 17 lines

action:

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
       | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
       +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()``

function.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action: · line 3015

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +8 -0
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+

+===================+=====================================
=========================+

Quoted 5 lines
Quoted 5 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +5 -0
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set

``sec_since_last_hit`` 0

Quoted 39 lines
Quoted 39 lines

|

Quoted 16 lines
doc/guides/prog_guide/rte_flow.rst +4 -0
+   +-------------------+--------------------------------------------------------------+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+
    Action: ``SAMPLE``
    ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +1 -0
index d830b02321..a21d437cf8 100644
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
    	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
    };
 
+/**

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2967

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *

+=============+=============+=============================
=+

Quoted 9 lines
lib/ethdev/rte_flow.h +9 -0
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
Quoted 4 lines
Quoted 2 lines

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

What do you mean?

Quoted 8 lines

RTE_FLOW_ACTION_TYPE_AGE has a description as enum member. Typically configuration structures are mentioned there. However, I think that it would be useful to mention specific update structure if any. Like this one. Just to make it clear that if a user wants to update the action configuration it should use specific structure. Or am I missing something? Misunderstand something?

Quoted 7 lines

Do you mean something like:
* see enum RTE_ETH_EVENT_FLOW_AGED
* See struct rte_flow_query_age
+ See struct rte_flow_update_age
*/
RTE_FLOW_ACTION_TYPE_AGE,
If so, I fully agree.

Yes, exactly.

Quoted 30 lines
Quoted 29 lines
Quoted 14 lines
Quoted 13 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 8 lines
lib/ethdev/rte_flow.h +5 -0
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	uint32_t touch:1;
+	/**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

Quoted 7 lines

+1

Quoted 3 lines

One more question: why order in the documentation above does not match order here?

I think we can remove it from the documentation since it doesn't add

anything

Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
    /**
     * @warning
     * @b EXPERIMENTAL: this structure may change without prior notice
#12 lore raw

RE: [PATCH 3/3] ethdev: add structure for indirect AGE update

Hi Andrew and Ori,

Quoted 329 lines · Andrew Rybchenko
Quoted 73 lines · Ori Kam

Hi Andrew,

Quoted 71 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 16:18

Quoted 18 lines · Ori Kam

Hi Andrew,

Quoted 16 lines

-----Original Message-----
From: Andrew Rybchenko <[email protected]>
Sent: Monday, 3 October 2022 11:04

Quoted 11 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
    app/test-pmd/cmdline_flow.c        | 66
Quoted 7 lines
Quoted 7 lines

++++++++++++++++++++++++++++++

app/test-

Quoted 6 lines
    app/test-pmd/config.c              | 18 +++++++-
    doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
    lib/ethdev/rte_flow.h              | 27 ++++++++++++
    4 files changed, 132 insertions(+), 4 deletions(-)
app/test- renamed from app/test-pmd/cmdline_flow.c +0 -0

pmd/cmdline_flow.c

Quoted 40 lines
Quoted 40 lines
Quoted 33 lines

index 4fb90a92cb..a315fd9ded 100644

app/test-pmd/cmdline_flow.c +8 -0
@@ -583,6 +583,9 @@ enum index {
          ACTION_SET_IPV6_DSCP_VALUE,
          ACTION_AGE,
          ACTION_AGE_TIMEOUT,
+ ACTION_AGE_UPDATE,
+ ACTION_AGE_UPDATE_TIMEOUT,
+ ACTION_AGE_UPDATE_TOUCH,
          ACTION_SAMPLE,
          ACTION_SAMPLE_RATIO,
          ACTION_SAMPLE_INDEX,
@@ -1869,6 +1872,7 @@ static const enum index next_action[] = {
          ACTION_SET_IPV4_DSCP,
          ACTION_SET_IPV6_DSCP,
          ACTION_AGE,
+ ACTION_AGE_UPDATE,
          ACTION_SAMPLE,
          ACTION_INDIRECT,
          ACTION_MODIFY_FIELD,
@@ -2113,6 +2117,14 @@ static const enum index action_age[] = {
          ZERO,
    };
 
+static const enum index action_age_update[] = {
+ACTION_AGE_UPDATE,  ACTION_AGE_UPDATE_TIMEOUT,
+ACTION_AGE_UPDATE_TOUCH,  ACTION_NEXT,  ZERO, };
+
    static const enum index action_sample[] = {
          ACTION_SAMPLE,
          ACTION_SAMPLE_RATIO,
@@ -2191,6 +2203,9 @@ static int parse_vc_spec(struct context *,
Quoted 1 line

const

struct token *,

Quoted 5 lines

const char *, unsigned int, void *, unsigned int);
static int parse_vc_conf(struct context *, const struct token *,
const char *, unsigned int, void *,
unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token

*,

Quoted 41 lines
Quoted 41 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
app/test-pmd/cmdline_flow.c +2 -0
+                          const char *, unsigned int, void *,
+                          unsigned int);
    static int parse_vc_item_ecpri_type(struct context *, const

struct token

*,

Quoted 36 lines
Quoted 36 lines
Quoted 4 lines

const char *, unsigned int, void *, unsigned int); @@
-6194,6 +6209,30 @@ static const struct token token_list[] = {
.next = NEXT(action_age,

NEXT_ENTRY(COMMON_UNSIGNED)),

Quoted 6 lines

.call = parse_vc_conf,
},
+ [ACTION_AGE_UPDATE] = {

app/test-pmd/cmdline_flow.c +3 -0
+         .name = "age_update",
+         .help = "update aging parameter",
+         .next = NEXT(action_age_update),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 10 lines
app/test-pmd/cmdline_flow.c +10 -0
+         .priv = PRIV_ACTION(AGE,
+                             sizeof(struct rte_flow_update_age)),
+         .call = parse_vc,
+ },
+ [ACTION_AGE_UPDATE_TIMEOUT] = {
+         .name = "timeout",
+         .help = "age timeout update value",
+         .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+                                    timeout, 24)),
+         .next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_UNSIGNED)),

app/test-pmd/cmdline_flow.c static const struct token token_list[] = {

Quoted 5 lines
app/test-pmd/cmdline_flow.c +5 -0
+         .call = parse_vc_conf_timeout, },
+ [ACTION_AGE_UPDATE_TOUCH] = {
+         .name = "touch",
+         .help = "this flow is touched",
+         .next = NEXT(action_age_update,

NEXT_ENTRY(COMMON_BOOLEAN)),

Quoted 8 lines
app/test-pmd/cmdline_flow.c +5 -0
+         .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+                                    touch, 1)),
+         .call = parse_vc_conf,
+ },
          [ACTION_SAMPLE] = {
                  .name = "sample",
                  .help = "set a sample action", @@ -7031,6
+7070,33 @@ parse_vc_conf(struct context *ctx, const
Quoted 7 lines
Quoted 7 lines

struct

Quoted 6 lines
Quoted 6 lines

token *token,

app/test-pmd/cmdline_flow.c

Quoted 5 lines
          return len;
    }
app/test-pmd/cmdline_flow.c +2 -0
+/** Parse action configuration field. */ static int
+parse_vc_conf_timeout(struct context *ctx, const struct token

*token,

Quoted 25 lines
Quoted 25 lines
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
app/test-pmd/cmdline_flow.c +16 -0
+               const char *str, unsigned int len,
+               void *buf, unsigned int size) {  struct buffer
+*out = buf;  struct rte_flow_update_age *update;
+
+ (void)size;
+ if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+         return -1;
+ /* Token name must match. */
+ if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+         return -1;
+ /* Nothing else to do if there is no buffer. */ if (!out)
+         return len;
+ /* Point to selected object. */
+ ctx->object = out->args.vc.data; objmask = NULL;
+ /* Update the timeout is valid. */ update = (struct
+ rte_flow_update_age *)out->args.vc.data;
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

+ update->timeout_valid = 1;
+ return len;

app/test-pmd/cmdline_flow.c +2 -0
+}
+
    /** Parse eCPRI common header type field. */
    static int
    parse_vc_item_ecpri_type(struct context *ctx, const struct

token

*token,

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

app/test-pmd/config.c port_action_handle_update(portid_t

Quoted 5 lines
app/test-pmd/config.c index renamed from app/test-pmd/config.c +0 -0

31952467fb..45495385d7 100644

app/test-pmd/config.c +0 -0
@@ -2065,6 +2065,7 @@ port_action_handle_update(portid_t

port_id,

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

uint32_t id,

app/test-pmd/config.c

Quoted 8 lines
app/test-pmd/config.c +1 -0
          if (!pia)
                  return -EINVAL;
          switch (pia->type) {
+ case RTE_FLOW_ACTION_TYPE_AGE:
          case RTE_FLOW_ACTION_TYPE_CONNTRACK:
                  update = action->conf;
                  break;
@@ -2904,6 +2905,8 @@

port_queue_action_handle_update(portid_t

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

port_id,

app/test-pmd/config.c

Quoted 8 lines
app/test-pmd/config.c +1 -0
          struct rte_port *port;
          struct rte_flow_error error;
          struct rte_flow_action_handle *action_handle;
+ struct port_indirect_action *pia; const void *update;
 
          action_handle = port_action_handle_get_by_id(port_id, id);
          if (!action_handle)
@@ -2915,8 +2918,21 @@

port_queue_action_handle_update(portid_t

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

port_id,

Quoted 3 lines
app/test-pmd/config.c +0 -0
                  return -EINVAL;
          }
 
Quoted 13 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
app/test-pmd/config.c +5 -0
+ pia = action_get_by_id(port_id, id); if (!pia)
+         return -EINVAL;
+
+ switch (pia->type) {
+ case RTE_FLOW_ACTION_TYPE_AGE:
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

app/test-pmd/config.c port_queue_action_handle_update(portid_t port_id,

Quoted 8 lines
app/test-pmd/config.c +7 -0
+         update = action->conf;
+         break;
+ default:
+         update = action;
+         break;
+ }
+
          if (rte_flow_async_action_handle_update(port_id, queue_id,

&attr,

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
app/test-pmd/config.c +2 -2
-                             action_handle, action, NULL, &error)) {
+                             action_handle, update, NULL,
+ &error)) {
                  return port_flow_complain(&error);
          }
          printf("Indirect action #%u update queued\n", id); diff
--git a/doc/guides/prog_guide/rte_flow.rst
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

b/doc/guides/prog_guide/rte_flow.rst

doc/guides/prog_guide/rte_flow.rst Otherwise,

Quoted 4 lines

index 588914b231..dae9121279 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2958,7 +2958,7 @@ Otherwise,

RTE_FLOW_ERROR_TYPE_ACTION

Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines

error will be returned.

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on

Quoted 9 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
    Action: ``AGE``
    ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
    Event RTE_ETH_EVENT_FLOW_AGED will be reported if
    timeout passed without any matching on the flow.
@@ -2977,8 +2977,8 @@ timeout passed without any matching on

the

Quoted 13 lines
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines

flow.

Quoted 3 lines
doc/guides/prog_guide/rte_flow.rst +0 -0
       | ``context``  | user input flow context         |
       +--------------+---------------------------------+
 
Quoted 8 lines
Quoted 8 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the

Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
    .. _table_rte_flow_query_age:
 
@@ -2994,6 +2994,25 @@ shared AGE action, or a flow rule using the

AGE

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines

action:

Quoted 6 lines
doc/guides/prog_guide/rte_flow.rst +2 -1
       | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
 
+------------------------------+-----+----------------------------
------------+
 
+Update structure to modify the parameters of an indirect AGE

action.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the · line 3000

Quoted 2 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
+The update structure is used by
+``rte_flow_action_handle_update()``

function.

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action:

Quoted 6 lines
doc/guides/prog_guide/rte_flow.rst +6 -0
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+-----------------------------------------------------------

---+

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the AGE action: · line 3015

Quoted 2 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
+   | Field             | Value                                                        |
+

+===================+=====================================

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

=========================+

Quoted 2 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+-----------------------------------------------------------

---+

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the · line 3012

Quoted 2 lines
doc/guides/prog_guide/rte_flow.rst +2 -0
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+-----------------------------------------------------------

---+

Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line

doc/guides/prog_guide/rte_flow.rst shared AGE action, or a flow rule using the · line 3013

Quoted 1 line
doc/guides/prog_guide/rte_flow.rst +1 -0
+   | ``touch``         | 1 bit, touch the AGE action to set

``sec_since_last_hit`` 0

Quoted 2 lines
Quoted 2 lines

|

Quoted 1 line
doc/guides/prog_guide/rte_flow.rst +1 -0
+   +-------------------+-----------------------------------------------------------

---+

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
doc/guides/prog_guide/rte_flow.rst +5 -0
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+
+ +-------------------+-------------------------------------------
+ -------------------+
+
    Action: ``SAMPLE``
    ^^^^^^^^^^^^^^^^^^
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2954

Quoted 6 lines
lib/ethdev/rte_flow.h index renamed from lib/ethdev/rte_flow.h +0 -0

d830b02321..a21d437cf8 100644

lib/ethdev/rte_flow.h +0 -0
@@ -2954,6 +2954,33 @@ struct rte_flow_query_age {
          uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit.

*/

Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 4 lines
lib/ethdev/rte_flow.h +2 -0
    };
 
+/**
+ * @warning

lib/ethdev/rte_flow.h struct rte_flow_query_age {

Quoted 10 lines
lib/ethdev/rte_flow.h +10 -0
+ * @b EXPERIMENTAL: this structure may change without prior
+notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *

+=============+=============+=============================

Quoted 25 lines
Quoted 16 lines
Quoted 11 lines
Quoted 11 lines

=+

Quoted 9 lines
lib/ethdev/rte_flow.h +9 -0
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging                    |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
Quoted 4 lines
Quoted 2 lines

I think it worse to mention the structure in
RTE_FLOW_ACTION_TYPE_AGE description.

What do you mean?

Quoted 8 lines

RTE_FLOW_ACTION_TYPE_AGE has a description as enum member. Typically configuration structures are mentioned there. However, I think that it would be useful to mention specific update structure if any. Like this one. Just to make it clear that if a user wants to update the action configuration it should use specific structure. Or am I missing something?
Misunderstand something?

Quoted 7 lines

Do you mean something like:
* see enum RTE_ETH_EVENT_FLOW_AGED
* See struct rte_flow_query_age
+ See struct rte_flow_update_age
*/
RTE_FLOW_ACTION_TYPE_AGE,
If so, I fully agree.

Quoted 1 line

Yes, exactly.

I have updated it according your suggestion, thank you.

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

lib/ethdev/rte_flow.h struct rte_flow_query_age { · line 2981

Quoted 4 lines
lib/ethdev/rte_flow.h +4 -0
+ uint32_t reserved:6; /**< Reserved, must be zero. */ uint32_t
+ timeout_valid:1; /**< The timeout is valid for update. */
+ uint32_t timeout:24; /**< Time in seconds. */ uint32_t touch:1;
+ /**< Means that aging should assume packet passed the aging. */

Documentation after code makes sense if it is in the same line. If the documentation is in its own line, it should be before the code and use /** prefix.

Updated, thanks.

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

+1

Quoted 2 lines

One more question: why order in the documentation above does not match order here?

I updated the documentation to be align to this order.

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 2 lines

I think we can remove it from the documentation since it doesn't add

anything

Quoted 8 lines
Quoted 7 lines
Quoted 7 lines
lib/ethdev/rte_flow.h +2 -0
+};
+
    /**
     * @warning
     * @b EXPERIMENTAL: this structure may change without prior

notice

#13 lore raw
In reply to Michael Baum

@Ori, could you take a look at the patch series.

Quoted 20 lines · Michael Baum

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

Michael Baum (3):
ethdev: add strict queue to pre-configuration flow hints
ethdev: add queue-based API to report aged flow rules
ethdev: add structure for indirect AGE update

  app/test-pmd/cmdline_flow.c                 |  93 +++++++++-
  app/test-pmd/config.c                       | 177 +++++++++++++++++++-
  app/test-pmd/testpmd.h                      |   1 +
  doc/guides/prog_guide/rte_flow.rst          |  25 ++-
  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  90 +++++++++-
  lib/ethdev/rte_flow.c                       |  22 +++
  lib/ethdev/rte_flow.h                       |  89 +++++++++-
  lib/ethdev/rte_flow_driver.h                |   7 +
  lib/ethdev/version.map                      |   3 +
  9 files changed, 491 insertions(+), 16 deletions(-)
#14 lore raw

v2 cover ethdev: AGE action preparation

In reply to Michael Baum

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

v2:
- rebase.
- Add reference to "rte_flow_update_age" structure in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Add reference to "rte_flow_get_q_aged_flows" function in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Change the order of "rte_flow_update_age" structure members in documentation, to be aligned with the structure definition.
- Place long comment before struct member definition.

Michael Baum (3):
ethdev: add strict queue to pre-configuration flow hints
ethdev: add queue-based API to report aged flow rules
ethdev: add structure for indirect AGE update

 app/test-pmd/cmdline_flow.c                 |  93 +++++++++-
 app/test-pmd/config.c                       | 177 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  90 +++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  91 +++++++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 9 files changed, 486 insertions(+), 21 deletions(-)
Signature · 1 line
2.25.1
#15 lore raw

PATCH v2 1/3 ethdev: add strict queue to pre-configuration flow hints

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

This patch add flag about above situation and could be extended to cover more situations.

---
 app/test-pmd/cmdline_flow.c                 | 10 ++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++--
 lib/ethdev/rte_flow.h                       | 14 ++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)
app/test-pmd/cmdline_flow.c +10 -0
index 810dfb9854..59829371d4 100644
@@ -226,6 +226,7 @@ enum index {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 
 	/* Indirect action arguments */
 	INDIRECT_ACTION_CREATE,
@@ -1092,6 +1093,7 @@ static const enum index next_config_attr[] = {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 	END,
 	ZERO,
 };
@@ -2692,6 +2694,14 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.configure.port_attr.nb_conn_tracks)),
 	},
+	[CONFIG_FLAGS] = {
+		.name = "flags",
+		.help = "configuration flags",
+		.next = NEXT(next_config_attr,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.configure.port_attr.flags)),
+	},
 	/* Top-level command. */
 	[PATTERN_TEMPLATE] = {
 		.name = "pattern_template",
doc/guides/testpmd_app_ug/testpmd_funcs.rst +2 -2
index b3f31df69a..a8b99c8c19 100644
@@ -2891,7 +2891,7 @@ following sections.
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 - Create a pattern template::
    flow pattern_template {port_id} create [pattern_template_id {id}]
@@ -3042,7 +3042,7 @@ for asynchronous flow creation/destruction operations. It is bound to
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 If successful, it will show::
 
lib/ethdev/rte_flow.h +14 -0
index cddbe74c33..a93ec796cb 100644
@@ -4741,6 +4741,12 @@ rte_flow_flex_item_release(uint16_t port_id,
 			   const struct rte_flow_item_flex_handle *handle,
 			   struct rte_flow_error *error);
 
+/**
+ * Indicate all operations for a given flow rule will _strictly_
+ * happen on the same queue (create/destroy/query/update).
+ */
+#define RTE_FLOW_PORT_FLAG_STRICT_QUEUE RTE_BIT32(0)
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4774,6 +4780,10 @@ struct rte_flow_port_info {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t max_nb_conn_tracks;
+	/**
+	 * Port supported flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t supported_flags;
 };
 
 /**
@@ -4848,6 +4858,10 @@ struct rte_flow_port_attr {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t nb_conn_tracks;
+	/**
+	 * Port flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t flags;
 };
 
 /**
Signature · 1 line
2.25.1
#16 lore raw

PATCH v2 2/3 ethdev: add queue-based API to report aged flow rules

In reply to Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

---
 app/test-pmd/cmdline_flow.c                 |  17 ++-
 app/test-pmd/config.c                       | 159 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  86 ++++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  49 +++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 8 files changed, 332 insertions(+), 10 deletions(-)
app/test-pmd/cmdline_flow.c +15 -2
index 59829371d4..992aeb95b3 100644
@@ -129,6 +129,7 @@ enum index {
 	/* Queue arguments. */
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
@@ -1170,6 +1171,7 @@ static const enum index next_table_destroy_attr[] = {
 static const enum index next_queue_subcmd[] = {
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 	ZERO,
 };
@@ -2967,6 +2969,13 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
 		.call = parse_qo_destroy,
 	},
+	[QUEUE_AGED] = {
+		.name = "aged",
+		.help = "list and destroy aged flows",
+		.next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)),
+		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+		.call = parse_aged,
+	},
 	[QUEUE_INDIRECT_ACTION] = {
 		.name = "indirect_action",
 		.help = "queue indirect actions",
@@ -8654,8 +8663,8 @@ parse_aged(struct context *ctx, const struct token *token,
 	/* Nothing else to do if there is no buffer. */
 	if (!out)
 		return len;
-	if (!out->command) {
-		if (ctx->curr != AGED)
+	if (!out->command || out->command == QUEUE) {
+		if (ctx->curr != AGED && ctx->curr != QUEUE_AGED)
 			return -1;
 		if (sizeof(*out) > size)
 			return -1;
@@ -10610,6 +10619,10 @@ cmd_flow_parsed(const struct buffer *in)
 	case PULL:
 		port_queue_flow_pull(in->port, in->queue);
 		break;
+	case QUEUE_AGED:
+		port_queue_flow_aged(in->port, in->queue,
+				     in->args.aged.destroy);
+		break;
 	case QUEUE_INDIRECT_ACTION_CREATE:
 		port_queue_action_handle_create(
 				in->port, in->queue, in->postpone,
app/test-pmd/config.c +158 -1

177 lines not on this page · raw message

app/test-pmd/testpmd.h +1 -0
index acdb7e855d..918c2377d8 100644
@@ -941,6 +941,7 @@ int port_queue_action_handle_query(portid_t port_id, uint32_t queue_id,
 				   bool postpone, uint32_t id);
 int port_queue_flow_push(portid_t port_id, queueid_t queue_id);
 int port_queue_flow_pull(portid_t port_id, queueid_t queue_id);
+void port_queue_flow_aged(portid_t port_id, uint32_t queue_id, uint8_t destroy);
 int port_flow_validate(portid_t port_id,
 		       const struct rte_flow_attr *attr,
 		       const struct rte_flow_item *pattern,
doc/guides/testpmd_app_ug/testpmd_funcs.rst +81 -5

126 lines not on this page · raw message

lib/ethdev/rte_flow.c +22 -0
index d11ba270db..7d0c24366c 100644
@@ -1132,6 +1132,28 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
 				  NULL, rte_strerror(ENOTSUP));
 }
 
+int
+rte_flow_get_q_aged_flows(uint16_t port_id, uint32_t queue_id, void **contexts,
+			  uint32_t nb_contexts, struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	int ret;
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->get_q_aged_flows)) {
+		fts_enter(dev);
+		ret = ops->get_q_aged_flows(dev, queue_id, contexts,
+					    nb_contexts, error);
+		fts_exit(dev);
+		return flow_err(port_id, ret, error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
 struct rte_flow_action_handle *
 rte_flow_action_handle_create(uint16_t port_id,
 			      const struct rte_flow_indir_action_conf *conf,
lib/ethdev/rte_flow.h +47 -2

67 lines not on this page · raw message

lib/ethdev/rte_flow_driver.h +7 -0
index 7289deb538..c7d0699c91 100644
@@ -84,6 +84,13 @@ struct rte_flow_ops {
 		 void **context,
 		 uint32_t nb_contexts,
 		 struct rte_flow_error *err);
+	/** See rte_flow_get_q_aged_flows() */
+	int (*get_q_aged_flows)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 void **contexts,
+		 uint32_t nb_contexts,
+		 struct rte_flow_error *error);
 	/** See rte_flow_action_handle_create() */
 	struct rte_flow_action_handle *(*action_handle_create)
 		(struct rte_eth_dev *dev,
lib/ethdev/version.map +1 -0
index e749678b96..17201fbe0f 100644
@@ -295,6 +295,7 @@ EXPERIMENTAL {
 	rte_eth_rx_descriptor_dump;
 	rte_eth_tx_descriptor_dump;
 	rte_flow_async_action_handle_query;
+	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
 };
Signature · 1 line
2.25.1
#17 lore raw

PATCH v2 3/3 ethdev: add structure for indirect AGE update

In reply to Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
 app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
 app/test-pmd/config.c              | 18 +++++---
 doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
 lib/ethdev/rte_flow.h              | 28 +++++++++++++
 4 files changed, 128 insertions(+), 9 deletions(-)
app/test-pmd/cmdline_flow.c +66 -0
index 992aeb95b3..88108498e0 100644
@@ -586,6 +586,9 @@ enum index {
 	ACTION_SET_IPV6_DSCP_VALUE,
 	ACTION_AGE,
 	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
 	ACTION_SAMPLE_INDEX,
@@ -1874,6 +1877,7 @@ static const enum index next_action[] = {
 	ACTION_SET_IPV4_DSCP,
 	ACTION_SET_IPV6_DSCP,
 	ACTION_AGE,
+	ACTION_AGE_UPDATE,
 	ACTION_SAMPLE,
 	ACTION_INDIRECT,
 	ACTION_MODIFY_FIELD,
@@ -2110,6 +2114,14 @@ static const enum index action_age[] = {
 	ZERO,
 };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_sample[] = {
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
@@ -2188,6 +2200,9 @@ static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
@@ -6206,6 +6221,30 @@ static const struct token token_list[] = {
 		.next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_SAMPLE] = {
 		.name = "sample",
 		.help = "set a sample action",
@@ -7045,6 +7084,33 @@ parse_vc_conf(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
 /** Parse eCPRI common header type field. */
 static int
 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +12 -6
index 18f3543887..d036fff095 100644
@@ -1886,6 +1886,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	if (!pia)
 		return -EINVAL;
 	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
 	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
 		update = action->conf;
 		break;
@@ -2816,17 +2817,22 @@ port_queue_action_handle_update(portid_t port_id,
 		return -EINVAL;
 	}
 
-	if (pia->type == RTE_FLOW_ACTION_TYPE_METER_MARK) {
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	case RTE_FLOW_ACTION_TYPE_METER_MARK:
 		rte_memcpy(&mtr_update.meter_mark, action->conf,
 			sizeof(struct rte_flow_action_meter_mark));
 		mtr_update.profile_valid = 1;
-		mtr_update.policy_valid  = 1;
-		mtr_update.color_mode_valid  = 1;
-		mtr_update.init_color_valid  = 1;
-		mtr_update.state_valid  = 1;
+		mtr_update.policy_valid = 1;
+		mtr_update.color_mode_valid = 1;
+		mtr_update.init_color_valid = 1;
+		mtr_update.state_valid = 1;
 		update = &mtr_update;
-	} else {
+	default:
 		update = action;
+		break;
 	}
 
 	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
doc/guides/prog_guide/rte_flow.rst +22 -3
index 565868aeea..1ce0277e65 100644
@@ -2737,7 +2737,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
 Action: ``AGE``
 ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
 Event RTE_ETH_EVENT_FLOW_AGED will be reported if
 timeout passed without any matching on the flow.
@@ -2756,8 +2756,8 @@ timeout passed without any matching on the flow.
    | ``context``  | user input flow context         |
    +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
 .. _table_rte_flow_query_age:
 
@@ -2773,6 +2773,25 @@ shared AGE action, or a flow rule using the AGE action:
    | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
    +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+   +===================+==============================================================+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0  |
+   +-------------------+--------------------------------------------------------------+
+
 Action: ``SAMPLE``
 ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +28 -0
index 64ec8f0903..a2101e0e11 100644
@@ -2643,6 +2643,7 @@ enum rte_flow_action_type {
 	 * See function rte_flow_get_aged_flows
 	 * see enum RTE_ETH_EVENT_FLOW_AGED
 	 * See struct rte_flow_query_age
+	 * See struct rte_flow_update_age
 	 */
 	RTE_FLOW_ACTION_TYPE_AGE,
 
@@ -2809,6 +2810,33 @@ struct rte_flow_query_age {
 	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	/**< Means that aging should assume packet passed the aging. */
+	uint32_t touch:1;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
Signature · 1 line
2.25.1
#18 lore raw

v3 cover ethdev: AGE action preparation

In reply to Michael Baum

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

v2:
- rebase.
- Add reference to "rte_flow_update_age" structure in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Add reference to "rte_flow_get_q_aged_flows" function in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Change the order of "rte_flow_update_age" structure members in documentation, to be aligned with the structure definition.
- Place long comment before struct member definition.

v3:
- Fix miss "break" in indirect action update switch-case.

Michael Baum (3):
ethdev: add strict queue to pre-configuration flow hints
ethdev: add queue-based API to report aged flow rules
ethdev: add structure for indirect AGE update

 app/test-pmd/cmdline_flow.c                 |  93 +++++++++-
 app/test-pmd/config.c                       | 178 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  90 +++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  91 +++++++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 9 files changed, 487 insertions(+), 21 deletions(-)
Signature · 1 line
2.25.1
#19 lore raw

PATCH v3 1/3 ethdev: add strict queue to pre-configuration flow hints

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

This patch add flag about above situation and could be extended to cover more situations.

---
 app/test-pmd/cmdline_flow.c                 | 10 ++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++--
 lib/ethdev/rte_flow.h                       | 14 ++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)
app/test-pmd/cmdline_flow.c +10 -0
index 810dfb9854..59829371d4 100644
@@ -226,6 +226,7 @@ enum index {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 
 	/* Indirect action arguments */
 	INDIRECT_ACTION_CREATE,
@@ -1092,6 +1093,7 @@ static const enum index next_config_attr[] = {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 	END,
 	ZERO,
 };
@@ -2692,6 +2694,14 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.configure.port_attr.nb_conn_tracks)),
 	},
+	[CONFIG_FLAGS] = {
+		.name = "flags",
+		.help = "configuration flags",
+		.next = NEXT(next_config_attr,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.configure.port_attr.flags)),
+	},
 	/* Top-level command. */
 	[PATTERN_TEMPLATE] = {
 		.name = "pattern_template",
doc/guides/testpmd_app_ug/testpmd_funcs.rst +2 -2
index b3f31df69a..a8b99c8c19 100644
@@ -2891,7 +2891,7 @@ following sections.
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 - Create a pattern template::
    flow pattern_template {port_id} create [pattern_template_id {id}]
@@ -3042,7 +3042,7 @@ for asynchronous flow creation/destruction operations. It is bound to
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 If successful, it will show::
 
lib/ethdev/rte_flow.h +14 -0
index cddbe74c33..a93ec796cb 100644
@@ -4741,6 +4741,12 @@ rte_flow_flex_item_release(uint16_t port_id,
 			   const struct rte_flow_item_flex_handle *handle,
 			   struct rte_flow_error *error);
 
+/**
+ * Indicate all operations for a given flow rule will _strictly_
+ * happen on the same queue (create/destroy/query/update).
+ */
+#define RTE_FLOW_PORT_FLAG_STRICT_QUEUE RTE_BIT32(0)
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4774,6 +4780,10 @@ struct rte_flow_port_info {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t max_nb_conn_tracks;
+	/**
+	 * Port supported flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t supported_flags;
 };
 
 /**
@@ -4848,6 +4858,10 @@ struct rte_flow_port_attr {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t nb_conn_tracks;
+	/**
+	 * Port flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t flags;
 };
 
 /**
Signature · 1 line
2.25.1
Acked-by on v3 1/3
#20 lore raw

Re: [PATCH v3 1/3] ethdev: add strict queue to pre-configuration flow hints

Quoted 14 lines · Michael Baum

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

Quoted 5 lines

This patch add flag about above situation and could be extended to cover more situations.

#21 lore raw

PATCH v3 2/3 ethdev: add queue-based API to report aged flow rules

In reply to Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

---
 app/test-pmd/cmdline_flow.c                 |  17 ++-
 app/test-pmd/config.c                       | 159 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  86 ++++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  49 +++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 8 files changed, 332 insertions(+), 10 deletions(-)
app/test-pmd/cmdline_flow.c +15 -2
index 59829371d4..992aeb95b3 100644
@@ -129,6 +129,7 @@ enum index {
 	/* Queue arguments. */
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
@@ -1170,6 +1171,7 @@ static const enum index next_table_destroy_attr[] = {
 static const enum index next_queue_subcmd[] = {
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 	ZERO,
 };
@@ -2967,6 +2969,13 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
 		.call = parse_qo_destroy,
 	},
+	[QUEUE_AGED] = {
+		.name = "aged",
+		.help = "list and destroy aged flows",
+		.next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)),
+		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+		.call = parse_aged,
+	},
 	[QUEUE_INDIRECT_ACTION] = {
 		.name = "indirect_action",
 		.help = "queue indirect actions",
@@ -8654,8 +8663,8 @@ parse_aged(struct context *ctx, const struct token *token,
 	/* Nothing else to do if there is no buffer. */
 	if (!out)
 		return len;
-	if (!out->command) {
-		if (ctx->curr != AGED)
+	if (!out->command || out->command == QUEUE) {
+		if (ctx->curr != AGED && ctx->curr != QUEUE_AGED)
 			return -1;
 		if (sizeof(*out) > size)
 			return -1;
@@ -10610,6 +10619,10 @@ cmd_flow_parsed(const struct buffer *in)
 	case PULL:
 		port_queue_flow_pull(in->port, in->queue);
 		break;
+	case QUEUE_AGED:
+		port_queue_flow_aged(in->port, in->queue,
+				     in->args.aged.destroy);
+		break;
 	case QUEUE_INDIRECT_ACTION_CREATE:
 		port_queue_action_handle_create(
 				in->port, in->queue, in->postpone,
app/test-pmd/config.c +158 -1

177 lines not on this page · raw message

app/test-pmd/testpmd.h +1 -0
index acdb7e855d..918c2377d8 100644
@@ -941,6 +941,7 @@ int port_queue_action_handle_query(portid_t port_id, uint32_t queue_id,
 				   bool postpone, uint32_t id);
 int port_queue_flow_push(portid_t port_id, queueid_t queue_id);
 int port_queue_flow_pull(portid_t port_id, queueid_t queue_id);
+void port_queue_flow_aged(portid_t port_id, uint32_t queue_id, uint8_t destroy);
 int port_flow_validate(portid_t port_id,
 		       const struct rte_flow_attr *attr,
 		       const struct rte_flow_item *pattern,
doc/guides/testpmd_app_ug/testpmd_funcs.rst +81 -5

126 lines not on this page · raw message

lib/ethdev/rte_flow.c +22 -0
index d11ba270db..7d0c24366c 100644
@@ -1132,6 +1132,28 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
 				  NULL, rte_strerror(ENOTSUP));
 }
 
+int
+rte_flow_get_q_aged_flows(uint16_t port_id, uint32_t queue_id, void **contexts,
+			  uint32_t nb_contexts, struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	int ret;
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->get_q_aged_flows)) {
+		fts_enter(dev);
+		ret = ops->get_q_aged_flows(dev, queue_id, contexts,
+					    nb_contexts, error);
+		fts_exit(dev);
+		return flow_err(port_id, ret, error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
 struct rte_flow_action_handle *
 rte_flow_action_handle_create(uint16_t port_id,
 			      const struct rte_flow_indir_action_conf *conf,
lib/ethdev/rte_flow.h +47 -2

67 lines not on this page · raw message

lib/ethdev/rte_flow_driver.h +7 -0
index 7289deb538..c7d0699c91 100644
@@ -84,6 +84,13 @@ struct rte_flow_ops {
 		 void **context,
 		 uint32_t nb_contexts,
 		 struct rte_flow_error *err);
+	/** See rte_flow_get_q_aged_flows() */
+	int (*get_q_aged_flows)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 void **contexts,
+		 uint32_t nb_contexts,
+		 struct rte_flow_error *error);
 	/** See rte_flow_action_handle_create() */
 	struct rte_flow_action_handle *(*action_handle_create)
 		(struct rte_eth_dev *dev,
lib/ethdev/version.map +1 -0
index e749678b96..17201fbe0f 100644
@@ -295,6 +295,7 @@ EXPERIMENTAL {
 	rte_eth_rx_descriptor_dump;
 	rte_eth_tx_descriptor_dump;
 	rte_flow_async_action_handle_query;
+	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
 };
Signature · 1 line
2.25.1
Acked-by on v3 2/3
#22 lore raw

Re: [PATCH v3 2/3] ethdev: add queue-based API to report aged flow rules

Quoted 8 lines · Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

Quoted 7 lines

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

Few minor notes below, other than that

[snip]

doc/guides/testpmd_app_ug/testpmd_funcs.rst following sections. · line 2897

Quoted 9 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -0
index a8b99c8c19..8e21b2a5b7 100644
@@ -2894,9 +2894,10 @@ following sections.
         [meters_number {number}] [flags {number}]
 
  - Create a pattern template::
+

unrelated style fixes, should be in a separate patch

doc/guides/testpmd_app_ug/testpmd_funcs.rst following sections. · line 2900

Quoted 4 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -1
     flow pattern_template {port_id} create [pattern_template_id {id}]
         [relaxed {boolean}] [ingress] [egress] [transfer]
-	   template {item} [/ {item} [...]] / end
+       template {item} [/ {item} [...]] / end

unrelated style fixes

Quoted 15 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +4 -0
  - Destroy a pattern template::
 
@@ -2995,6 +2996,10 @@ following sections.
 
     flow aged {port_id} [destroy]
 
+- Enqueue list and destroy aged flow rules::
+
+   flow queue {port_id} aged {queue_id} [destroy]
+
  - Tunnel offload - create a tunnel stub::
 
     flow tunnel create {port_id} type {tunnel_type}

doc/guides/testpmd_app_ug/testpmd_funcs.rst Disabling isolated mode:: · line 4244

Quoted 5 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -1
@@ -4236,7 +4241,7 @@ Disabling isolated mode::
   testpmd>
 
  Dumping HW internal information
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

unrelated changes

doc/guides/testpmd_app_ug/testpmd_funcs.rst Otherwise, it will complain error occurred:: · line 4263

Quoted 13 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +2 -2
  ``flow dump`` dumps the hardware's internal representation information of
  all flows. It is bound to ``rte_flow_dev_dump()``::
@@ -4252,10 +4257,10 @@ Otherwise, it will complain error occurred::
     Caught error type [...] ([...]): [...]
 
  Listing and destroying aged flow rules
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
  ``flow aged`` simply lists aged flow rules be get from api ``rte_flow_get_aged_flows``,
-and ``destroy`` parameter can be used to destroy those flow rules in PMD.
+and ``destroy`` parameter can be used to destroy those flow rules in PMD::

unrelated style fixes

doc/guides/testpmd_app_ug/testpmd_funcs.rst will be ID 3, ID 1, ID 0:: · line 4298

Quoted 9 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -1
     flow aged {port_id} [destroy]
 
@@ -4290,7 +4295,7 @@ will be ID 3, ID 1, ID 0::
     1       0       0       i--
     0       0       0       i--
 
-If attach ``destroy`` parameter, the command will destroy all the list aged flow rules.
+If attach ``destroy`` parameter, the command will destroy all the list aged flow rules::

unrelated style fixes

[snip]

#23 lore raw

RE: [PATCH v3 2/3] ethdev: add queue-based API to report aged flow rules

Quoted 15 lines · Andrew Rybchenko
Quoted 13 lines · Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

Quoted 7 lines
Quoted 2 lines

Few minor notes below, other than that

Thank you, I'm sending a new version without unrelated fixes. I'll send them later in a different patch set.

Quoted 77 lines

[snip]

doc/guides/testpmd_app_ug/testpmd_funcs.rst following sections. · line 2897

Quoted 10 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -0
index a8b99c8c19..8e21b2a5b7 100644
@@ -2894,9 +2894,10 @@ following sections.
         [meters_number {number}] [flags {number}]
 
  - Create a pattern template::
+

unrelated style fixes, should be in a separate patch

doc/guides/testpmd_app_ug/testpmd_funcs.rst following sections. · line 2900

Quoted 4 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -1
     flow pattern_template {port_id} create [pattern_template_id {id}]
         [relaxed {boolean}] [ingress] [egress] [transfer]
-        template {item} [/ {item} [...]] / end
+       template {item} [/ {item} [...]] / end

unrelated style fixes

Quoted 10 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +3 -0
  - Destroy a pattern template::
 
@@ -2995,6 +2996,10 @@ following sections.
 
     flow aged {port_id} [destroy]
 
+- Enqueue list and destroy aged flow rules::
+
+   flow queue {port_id} aged {queue_id} [destroy]

doc/guides/testpmd_app_ug/testpmd_funcs.rst following sections.

Quoted 10 lines
doc/guides/testpmd_app_ug/testpmd_funcs.rst +3 -1
+
  - Tunnel offload - create a tunnel stub::
 
     flow tunnel create {port_id} type {tunnel_type} @@ -4236,7
+4241,7 @@ Disabling isolated mode::
   testpmd>
 
  Dumping HW internal information
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

unrelated changes

Quoted 11 lines

``flow dump`` dumps the hardware's internal representation information of all flows. It is bound to ``rte_flow_dev_dump()``::

doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -1
@@ -4252,10 +4257,10 @@ Otherwise, it will complain error occurred::
     Caught error type [...] ([...]): [...]
 
  Listing and destroying aged flow rules
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
  ``flow aged`` simply lists aged flow rules be get from api
Quoted 1 line

``rte_flow_get_aged_flows``, -and ``destroy`` parameter can be used to

destroy those flow rules in PMD.

Quoted 1 line

+and ``destroy`` parameter can be used to destroy those flow rules in PMD::

unrelated style fixes

doc/guides/testpmd_app_ug/testpmd_funcs.rst will be ID 3, ID 1, ID 0:: · line 4293

Quoted 8 lines

flow aged {port_id} [destroy]

doc/guides/testpmd_app_ug/testpmd_funcs.rst +0 -1
@@ -4290,7 +4295,7 @@ will be ID 3, ID 1, ID 0::
     1       0       0       i--
     0       0       0       i--
 
-If attach ``destroy`` parameter, the command will destroy all the list aged

flow rules.

doc/guides/testpmd_app_ug/testpmd_funcs.rst will be ID 3, ID 1, ID 0:: · line 4298

Quoted 1 line
doc/guides/testpmd_app_ug/testpmd_funcs.rst +1 -0
+If attach ``destroy`` parameter, the command will destroy all the list aged

flow rules::

unrelated style fixes

[snip]

#24 lore raw

PATCH v3 3/3 ethdev: add structure for indirect AGE update

In reply to Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
 app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
 app/test-pmd/config.c              | 19 ++++++---
 doc/guides/prog_guide/rte_flow.rst | 25 +++++++++--
 lib/ethdev/rte_flow.h              | 28 +++++++++++++
 4 files changed, 129 insertions(+), 9 deletions(-)
app/test-pmd/cmdline_flow.c +66 -0
index 992aeb95b3..88108498e0 100644
@@ -586,6 +586,9 @@ enum index {
 	ACTION_SET_IPV6_DSCP_VALUE,
 	ACTION_AGE,
 	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
 	ACTION_SAMPLE_INDEX,
@@ -1874,6 +1877,7 @@ static const enum index next_action[] = {
 	ACTION_SET_IPV4_DSCP,
 	ACTION_SET_IPV6_DSCP,
 	ACTION_AGE,
+	ACTION_AGE_UPDATE,
 	ACTION_SAMPLE,
 	ACTION_INDIRECT,
 	ACTION_MODIFY_FIELD,
@@ -2110,6 +2114,14 @@ static const enum index action_age[] = {
 	ZERO,
 };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_sample[] = {
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
@@ -2188,6 +2200,9 @@ static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
@@ -6206,6 +6221,30 @@ static const struct token token_list[] = {
 		.next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_SAMPLE] = {
 		.name = "sample",
 		.help = "set a sample action",
@@ -7045,6 +7084,33 @@ parse_vc_conf(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
 /** Parse eCPRI common header type field. */
 static int
 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +13 -6
index 18f3543887..e8a1b77c2a 100644
@@ -1886,6 +1886,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	if (!pia)
 		return -EINVAL;
 	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
 	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
 		update = action->conf;
 		break;
@@ -2816,17 +2817,23 @@ port_queue_action_handle_update(portid_t port_id,
 		return -EINVAL;
 	}
 
-	if (pia->type == RTE_FLOW_ACTION_TYPE_METER_MARK) {
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	case RTE_FLOW_ACTION_TYPE_METER_MARK:
 		rte_memcpy(&mtr_update.meter_mark, action->conf,
 			sizeof(struct rte_flow_action_meter_mark));
 		mtr_update.profile_valid = 1;
-		mtr_update.policy_valid  = 1;
-		mtr_update.color_mode_valid  = 1;
-		mtr_update.init_color_valid  = 1;
-		mtr_update.state_valid  = 1;
+		mtr_update.policy_valid = 1;
+		mtr_update.color_mode_valid = 1;
+		mtr_update.init_color_valid = 1;
+		mtr_update.state_valid = 1;
 		update = &mtr_update;
-	} else {
+		break;
+	default:
 		update = action;
+		break;
 	}
 
 	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
doc/guides/prog_guide/rte_flow.rst +22 -3
index 565868aeea..1ce0277e65 100644
@@ -2737,7 +2737,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
 Action: ``AGE``
 ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.
 
 Event RTE_ETH_EVENT_FLOW_AGED will be reported if
 timeout passed without any matching on the flow.
@@ -2756,8 +2756,8 @@ timeout passed without any matching on the flow.
    | ``context``  | user input flow context         |
    +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:
 
 .. _table_rte_flow_query_age:
 
@@ -2773,6 +2773,25 @@ shared AGE action, or a flow rule using the AGE action:
    | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
    +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+   +===================+==============================================================+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0  |
+   +-------------------+--------------------------------------------------------------+
+
 Action: ``SAMPLE``
 ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +28 -0
index 64ec8f0903..8858b56428 100644
@@ -2643,6 +2643,7 @@ enum rte_flow_action_type {
 	 * See function rte_flow_get_aged_flows
 	 * see enum RTE_ETH_EVENT_FLOW_AGED
 	 * See struct rte_flow_query_age
+	 * See struct rte_flow_update_age
 	 */
 	RTE_FLOW_ACTION_TYPE_AGE,
 
@@ -2809,6 +2810,33 @@ struct rte_flow_query_age {
 	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	/** Means that aging should assume packet passed the aging. */
+	uint32_t touch:1;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
Signature · 1 line
2.25.1
Acked-by on v3 3/3
#25 lore raw

Re: [PATCH v3 3/3] ethdev: add structure for indirect AGE update

Quoted 10 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

Few minor notes below, other than that

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned. · line 2740

Quoted 11 lines
app/test-pmd/config.c +0 -0
doc/guides/prog_guide/rte_flow.rst +1 -1
index 565868aeea..1ce0277e65 100644
@@ -2737,7 +2737,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
  Action: ``AGE``
  ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.

Unrelated fixes

doc/guides/prog_guide/rte_flow.rst timeout passed without any matching on the flow. · line 2760

Quoted 11 lines
doc/guides/prog_guide/rte_flow.rst +2 -2
  Event RTE_ETH_EVENT_FLOW_AGED will be reported if
  timeout passed without any matching on the flow.
@@ -2756,8 +2756,8 @@ timeout passed without any matching on the flow.
     | ``context``  | user input flow context         |
     +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a
-shared AGE action, or a flow rule using the AGE action:
+Query structure to retrieve aging status information of an
+indirect AGE action, or a flow rule using the AGE action:

Unrelated fixes

#26 lore raw

RE: [PATCH v3 3/3] ethdev: add structure for indirect AGE update

Quoted 10 lines · Andrew Rybchenko
Quoted 8 lines · Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

Quoted 7 lines
Quoted 2 lines

Few minor notes below, other than that

Thank you, I'm sending a new version without unrelated fixes. I'll send them later in a different patch set.

Quoted 29 lines

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error

Quoted 7 lines
app/test-pmd/config.c diff --git renamed from app/test-pmd/config.c +0 -0

a/doc/guides/prog_guide/rte_flow.rst
b/doc/guides/prog_guide/rte_flow.rst
index 565868aeea..1ce0277e65 100644

doc/guides/prog_guide/rte_flow.rst +0 -0
@@ -2737,7 +2737,7 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error

will be returned.

doc/guides/prog_guide/rte_flow.rst Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned. · line 2740

Quoted 5 lines
doc/guides/prog_guide/rte_flow.rst +1 -1
  Action: ``AGE``
  ^^^^^^^^^^^^^^^
 
-Set ageing timeout configuration to a flow.
+Set aging timeout configuration to a flow.

Unrelated fixes

doc/guides/prog_guide/rte_flow.rst

Quoted 11 lines
doc/guides/prog_guide/rte_flow.rst +0 -1
  Event RTE_ETH_EVENT_FLOW_AGED will be reported if
  timeout passed without any matching on the flow.
@@ -2756,8 +2756,8 @@ timeout passed without any matching on the flow.
     | ``context``  | user input flow context         |
     +--------------+---------------------------------+
 
-Query structure to retrieve ageing status information of a -shared

AGE action, or a flow rule using the AGE action:

doc/guides/prog_guide/rte_flow.rst +2 -0
+Query structure to retrieve aging status information of an indirect
+AGE action, or a flow rule using the AGE action:

Unrelated fixes

#27 lore raw

v4 cover ethdev: AGE action preparation

In reply to Michael Baum

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

v2:
- rebase.
- Add reference to "rte_flow_update_age" structure in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Add reference to "rte_flow_get_q_aged_flows" function in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Change the order of "rte_flow_update_age" structure members in documentation, to be aligned with the structure definition.
- Place long comment before struct member definition.

v3:
- Fix miss "break" in indirect action update switch-case.

v4:
- Remove unrelated doc fixes.

Michael Baum (3):
ethdev: add strict queue to pre-configuration flow hints
ethdev: add queue-based API to report aged flow rules
ethdev: add structure for indirect AGE update

 app/test-pmd/cmdline_flow.c                 |  93 +++++++++-
 app/test-pmd/config.c                       | 178 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/prog_guide/rte_flow.rst          |  19 +++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  79 ++++++++-
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  91 +++++++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 9 files changed, 478 insertions(+), 13 deletions(-)
Signature · 1 line
2.25.1
#28 lore raw

PATCH v4 1/3 ethdev: add strict queue to pre-configuration flow hints

The data-path focused flow rule management can manage flow rules in more optimized way than traditional one by using hints provided by application in initialization phase.

In addition to the current hints we have in port attr, more hints could be provided by application about its behaviour.

One example is how the application do with the same flow rule ? A. create/destroy flow on same queue but query flow on different queue
or queue-less way (i.e, counter query)
B. All flow operations will be exactly on the same queue, by which PMD
could be in more optimized way then A because resource could be isolated and access based on queue, without lock, for example.

This patch add flag about above situation and could be extended to cover more situations.

---
 app/test-pmd/cmdline_flow.c                 | 10 ++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  4 ++--
 lib/ethdev/rte_flow.h                       | 14 ++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)
app/test-pmd/cmdline_flow.c +10 -0
index 810dfb9854..59829371d4 100644
@@ -226,6 +226,7 @@ enum index {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 
 	/* Indirect action arguments */
 	INDIRECT_ACTION_CREATE,
@@ -1092,6 +1093,7 @@ static const enum index next_config_attr[] = {
 	CONFIG_AGING_OBJECTS_NUMBER,
 	CONFIG_METERS_NUMBER,
 	CONFIG_CONN_TRACK_NUMBER,
+	CONFIG_FLAGS,
 	END,
 	ZERO,
 };
@@ -2692,6 +2694,14 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer,
 					args.configure.port_attr.nb_conn_tracks)),
 	},
+	[CONFIG_FLAGS] = {
+		.name = "flags",
+		.help = "configuration flags",
+		.next = NEXT(next_config_attr,
+			     NEXT_ENTRY(COMMON_UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct buffer,
+					args.configure.port_attr.flags)),
+	},
 	/* Top-level command. */
 	[PATTERN_TEMPLATE] = {
 		.name = "pattern_template",
doc/guides/testpmd_app_ug/testpmd_funcs.rst +2 -2
index d0fe73dff6..81e502b369 100644
@@ -2891,7 +2891,7 @@ following sections.
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 - Create a pattern template::
    flow pattern_template {port_id} create [pattern_template_id {id}]
@@ -3042,7 +3042,7 @@ for asynchronous flow creation/destruction operations. It is bound to
        [queues_number {number}] [queues_size {size}]
        [counters_number {number}]
        [aging_counters_number {number}]
-       [meters_number {number}]
+       [meters_number {number}] [flags {number}]
 
 If successful, it will show::
 
lib/ethdev/rte_flow.h +14 -0
index cddbe74c33..a93ec796cb 100644
@@ -4741,6 +4741,12 @@ rte_flow_flex_item_release(uint16_t port_id,
 			   const struct rte_flow_item_flex_handle *handle,
 			   struct rte_flow_error *error);
 
+/**
+ * Indicate all operations for a given flow rule will _strictly_
+ * happen on the same queue (create/destroy/query/update).
+ */
+#define RTE_FLOW_PORT_FLAG_STRICT_QUEUE RTE_BIT32(0)
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4774,6 +4780,10 @@ struct rte_flow_port_info {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t max_nb_conn_tracks;
+	/**
+	 * Port supported flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t supported_flags;
 };
 
 /**
@@ -4848,6 +4858,10 @@ struct rte_flow_port_attr {
 	 * @see RTE_FLOW_ACTION_TYPE_CONNTRACK
 	 */
 	uint32_t nb_conn_tracks;
+	/**
+	 * Port flags (RTE_FLOW_PORT_FLAG_*).
+	 */
+	uint32_t flags;
 };
 
 /**
Signature · 1 line
2.25.1
#29 lore raw

PATCH v4 2/3 ethdev: add queue-based API to report aged flow rules

In reply to Michael Baum

When application use queue-based flow rule management and operate the same flow rule on the same queue, e.g create/destroy/query, API of querying aged flow rules should also have queue id parameter just like other queue-based flow APIs.

By this way, PMD can work in more optimized way since resources are isolated by queue and needn't synchronize.

If application do use queue-based flow management but configure port without RTE_FLOW_PORT_FLAG_STRICT_QUEUE, which means application operate a given flow rule on different queues, the queue id parameter will be ignored.

---
 app/test-pmd/cmdline_flow.c                 |  17 ++-
 app/test-pmd/config.c                       | 159 +++++++++++++++++++-
 app/test-pmd/testpmd.h                      |   1 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  75 +++++++++
 lib/ethdev/rte_flow.c                       |  22 +++
 lib/ethdev/rte_flow.h                       |  49 +++++-
 lib/ethdev/rte_flow_driver.h                |   7 +
 lib/ethdev/version.map                      |   1 +
 8 files changed, 326 insertions(+), 5 deletions(-)
app/test-pmd/cmdline_flow.c +15 -2
index 59829371d4..992aeb95b3 100644
@@ -129,6 +129,7 @@ enum index {
 	/* Queue arguments. */
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 
 	/* Queue create arguments. */
@@ -1170,6 +1171,7 @@ static const enum index next_table_destroy_attr[] = {
 static const enum index next_queue_subcmd[] = {
 	QUEUE_CREATE,
 	QUEUE_DESTROY,
+	QUEUE_AGED,
 	QUEUE_INDIRECT_ACTION,
 	ZERO,
 };
@@ -2967,6 +2969,13 @@ static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
 		.call = parse_qo_destroy,
 	},
+	[QUEUE_AGED] = {
+		.name = "aged",
+		.help = "list and destroy aged flows",
+		.next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)),
+		.args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+		.call = parse_aged,
+	},
 	[QUEUE_INDIRECT_ACTION] = {
 		.name = "indirect_action",
 		.help = "queue indirect actions",
@@ -8654,8 +8663,8 @@ parse_aged(struct context *ctx, const struct token *token,
 	/* Nothing else to do if there is no buffer. */
 	if (!out)
 		return len;
-	if (!out->command) {
-		if (ctx->curr != AGED)
+	if (!out->command || out->command == QUEUE) {
+		if (ctx->curr != AGED && ctx->curr != QUEUE_AGED)
 			return -1;
 		if (sizeof(*out) > size)
 			return -1;
@@ -10610,6 +10619,10 @@ cmd_flow_parsed(const struct buffer *in)
 	case PULL:
 		port_queue_flow_pull(in->port, in->queue);
 		break;
+	case QUEUE_AGED:
+		port_queue_flow_aged(in->port, in->queue,
+				     in->args.aged.destroy);
+		break;
 	case QUEUE_INDIRECT_ACTION_CREATE:
 		port_queue_action_handle_create(
 				in->port, in->queue, in->postpone,
app/test-pmd/config.c +158 -1

177 lines not on this page · raw message

app/test-pmd/testpmd.h +1 -0
index 7fef96f9b1..e1efd34be9 100644
@@ -941,6 +941,7 @@ int port_queue_action_handle_query(portid_t port_id, uint32_t queue_id,
 				   bool postpone, uint32_t id);
 int port_queue_flow_push(portid_t port_id, queueid_t queue_id);
 int port_queue_flow_pull(portid_t port_id, queueid_t queue_id);
+void port_queue_flow_aged(portid_t port_id, uint32_t queue_id, uint8_t destroy);
 int port_flow_validate(portid_t port_id,
 		       const struct rte_flow_attr *attr,
 		       const struct rte_flow_item *pattern,
doc/guides/testpmd_app_ug/testpmd_funcs.rst +75 -0

87 lines not on this page · raw message

lib/ethdev/rte_flow.c +22 -0
index d11ba270db..7d0c24366c 100644
@@ -1132,6 +1132,28 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
 				  NULL, rte_strerror(ENOTSUP));
 }
 
+int
+rte_flow_get_q_aged_flows(uint16_t port_id, uint32_t queue_id, void **contexts,
+			  uint32_t nb_contexts, struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	int ret;
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->get_q_aged_flows)) {
+		fts_enter(dev);
+		ret = ops->get_q_aged_flows(dev, queue_id, contexts,
+					    nb_contexts, error);
+		fts_exit(dev);
+		return flow_err(port_id, ret, error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
 struct rte_flow_action_handle *
 rte_flow_action_handle_create(uint16_t port_id,
 			      const struct rte_flow_indir_action_conf *conf,
lib/ethdev/rte_flow.h +47 -2

67 lines not on this page · raw message

lib/ethdev/rte_flow_driver.h +7 -0
index 7289deb538..c7d0699c91 100644
@@ -84,6 +84,13 @@ struct rte_flow_ops {
 		 void **context,
 		 uint32_t nb_contexts,
 		 struct rte_flow_error *err);
+	/** See rte_flow_get_q_aged_flows() */
+	int (*get_q_aged_flows)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 void **contexts,
+		 uint32_t nb_contexts,
+		 struct rte_flow_error *error);
 	/** See rte_flow_action_handle_create() */
 	struct rte_flow_action_handle *(*action_handle_create)
 		(struct rte_eth_dev *dev,
lib/ethdev/version.map +1 -0
index e749678b96..17201fbe0f 100644
@@ -295,6 +295,7 @@ EXPERIMENTAL {
 	rte_eth_rx_descriptor_dump;
 	rte_eth_tx_descriptor_dump;
 	rte_flow_async_action_handle_query;
+	rte_flow_get_q_aged_flows;
 	rte_mtr_meter_policy_get;
 	rte_mtr_meter_profile_get;
 };
Signature · 1 line
2.25.1
#30 lore raw

PATCH v4 3/3 ethdev: add structure for indirect AGE update

In reply to Michael Baum

Add a new structure for indirect AGE update.

This new structure enables:
1. Update timeout value.
2. Stop AGE checking.
3. Start AGE checking.
4. restart AGE checking.

---
 app/test-pmd/cmdline_flow.c        | 66 ++++++++++++++++++++++++++++++
 app/test-pmd/config.c              | 19 ++++++---
 doc/guides/prog_guide/rte_flow.rst | 19 +++++++++
 lib/ethdev/rte_flow.h              | 28 +++++++++++++
 4 files changed, 126 insertions(+), 6 deletions(-)
app/test-pmd/cmdline_flow.c +66 -0
index 992aeb95b3..88108498e0 100644
@@ -586,6 +586,9 @@ enum index {
 	ACTION_SET_IPV6_DSCP_VALUE,
 	ACTION_AGE,
 	ACTION_AGE_TIMEOUT,
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
 	ACTION_SAMPLE_INDEX,
@@ -1874,6 +1877,7 @@ static const enum index next_action[] = {
 	ACTION_SET_IPV4_DSCP,
 	ACTION_SET_IPV6_DSCP,
 	ACTION_AGE,
+	ACTION_AGE_UPDATE,
 	ACTION_SAMPLE,
 	ACTION_INDIRECT,
 	ACTION_MODIFY_FIELD,
@@ -2110,6 +2114,14 @@ static const enum index action_age[] = {
 	ZERO,
 };
 
+static const enum index action_age_update[] = {
+	ACTION_AGE_UPDATE,
+	ACTION_AGE_UPDATE_TIMEOUT,
+	ACTION_AGE_UPDATE_TOUCH,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_sample[] = {
 	ACTION_SAMPLE,
 	ACTION_SAMPLE_RATIO,
@@ -2188,6 +2200,9 @@ static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf_timeout(struct context *, const struct token *,
+				 const char *, unsigned int, void *,
+				 unsigned int);
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
@@ -6206,6 +6221,30 @@ static const struct token token_list[] = {
 		.next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_AGE_UPDATE] = {
+		.name = "age_update",
+		.help = "update aging parameter",
+		.next = NEXT(action_age_update),
+		.priv = PRIV_ACTION(AGE,
+				    sizeof(struct rte_flow_update_age)),
+		.call = parse_vc,
+	},
+	[ACTION_AGE_UPDATE_TIMEOUT] = {
+		.name = "timeout",
+		.help = "age timeout update value",
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   timeout, 24)),
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)),
+		.call = parse_vc_conf_timeout,
+	},
+	[ACTION_AGE_UPDATE_TOUCH] = {
+		.name = "touch",
+		.help = "this flow is touched",
+		.next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)),
+		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age,
+					   touch, 1)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_SAMPLE] = {
 		.name = "sample",
 		.help = "set a sample action",
@@ -7045,6 +7084,33 @@ parse_vc_conf(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse action configuration field. */
+static int
+parse_vc_conf_timeout(struct context *ctx, const struct token *token,
+		      const char *str, unsigned int len,
+		      void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_update_age *update;
+
+	(void)size;
+	if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT)
+		return -1;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return len;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Update the timeout is valid. */
+	update = (struct rte_flow_update_age *)out->args.vc.data;
+	update->timeout_valid = 1;
+	return len;
+}
+
 /** Parse eCPRI common header type field. */
 static int
 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
app/test-pmd/config.c +13 -6
index 18f3543887..e8a1b77c2a 100644
@@ -1886,6 +1886,7 @@ port_action_handle_update(portid_t port_id, uint32_t id,
 	if (!pia)
 		return -EINVAL;
 	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
 	case RTE_FLOW_ACTION_TYPE_CONNTRACK:
 		update = action->conf;
 		break;
@@ -2816,17 +2817,23 @@ port_queue_action_handle_update(portid_t port_id,
 		return -EINVAL;
 	}
 
-	if (pia->type == RTE_FLOW_ACTION_TYPE_METER_MARK) {
+	switch (pia->type) {
+	case RTE_FLOW_ACTION_TYPE_AGE:
+		update = action->conf;
+		break;
+	case RTE_FLOW_ACTION_TYPE_METER_MARK:
 		rte_memcpy(&mtr_update.meter_mark, action->conf,
 			sizeof(struct rte_flow_action_meter_mark));
 		mtr_update.profile_valid = 1;
-		mtr_update.policy_valid  = 1;
-		mtr_update.color_mode_valid  = 1;
-		mtr_update.init_color_valid  = 1;
-		mtr_update.state_valid  = 1;
+		mtr_update.policy_valid = 1;
+		mtr_update.color_mode_valid = 1;
+		mtr_update.init_color_valid = 1;
+		mtr_update.state_valid = 1;
 		update = &mtr_update;
-	} else {
+		break;
+	default:
 		update = action;
+		break;
 	}
 
 	if (rte_flow_async_action_handle_update(port_id, queue_id, &attr,
doc/guides/prog_guide/rte_flow.rst +19 -0
index 565868aeea..3e6242803d 100644
@@ -2773,6 +2773,25 @@ shared AGE action, or a flow rule using the AGE action:
    | ``sec_since_last_hit``       | out | Seconds since last traffic hit         |
    +------------------------------+-----+----------------------------------------+
 
+Update structure to modify the parameters of an indirect AGE action.
+The update structure is used by ``rte_flow_action_handle_update()`` function.
+
+.. _table_rte_flow_update_age:
+
+.. table:: AGE update
+
+   +-------------------+--------------------------------------------------------------+
+   | Field             | Value                                                        |
+   +===================+==============================================================+
+   | ``reserved``      | 6 bits reserved, must be zero                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout_valid`` | 1 bit, timeout value is valid                                |
+   +-------------------+--------------------------------------------------------------+
+   | ``timeout``       | 24 bits timeout value                                        |
+   +-------------------+--------------------------------------------------------------+
+   | ``touch``         | 1 bit, touch the AGE action to set ``sec_since_last_hit`` 0  |
+   +-------------------+--------------------------------------------------------------+
+
 Action: ``SAMPLE``
 ^^^^^^^^^^^^^^^^^^
 
lib/ethdev/rte_flow.h +28 -0
index 64ec8f0903..8858b56428 100644
@@ -2643,6 +2643,7 @@ enum rte_flow_action_type {
 	 * See function rte_flow_get_aged_flows
 	 * see enum RTE_ETH_EVENT_FLOW_AGED
 	 * See struct rte_flow_query_age
+	 * See struct rte_flow_update_age
 	 */
 	RTE_FLOW_ACTION_TYPE_AGE,
 
@@ -2809,6 +2810,33 @@ struct rte_flow_query_age {
 	uint32_t sec_since_last_hit:24; /**< Seconds since last traffic hit. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Update indirect AGE action attributes:
+ *  - Timeout can be updated including stop/start action:
+ *     +-------------+-------------+------------------------------+
+ *     | Old Timeout | New Timeout | Updating                     |
+ *     +=============+=============+==============================+
+ *     | 0           | positive    | Start aging with new value   |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | 0           | Stop aging			  |
+ *     +-------------+-------------+------------------------------+
+ *     | positive    | positive    | Change timeout to new value  |
+ *     +-------------+-------------+------------------------------+
+ *  - sec_since_last_hit can be reset.
+ */
+struct rte_flow_update_age {
+	uint32_t reserved:6; /**< Reserved, must be zero. */
+	uint32_t timeout_valid:1; /**< The timeout is valid for update. */
+	uint32_t timeout:24; /**< Time in seconds. */
+	/** Means that aging should assume packet passed the aging. */
+	uint32_t touch:1;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this structure may change without prior notice
Signature · 1 line
2.25.1
#31 lore raw
In reply to Michael Baum
Quoted 14 lines · Michael Baum

RFC's:
https://patchwork.dpdk.org/project/dpdk/patch/7a45693f478b1b721b4e05131141b526185a175c.1654063912.git.jackmin@nvidia.com/
https://patchwork.dpdk.org/project/dpdk/patch/608febf8d5d3c434a1eddb2e56f425ebbd6ff0b4.1654063912.git.jackmin@nvidia.com/

v2:
- rebase.
- Add reference to "rte_flow_update_age" structure in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Add reference to "rte_flow_get_q_aged_flows" function in "RTE_FLOW_ACTION_TYPE_AGE" definition.
- Change the order of "rte_flow_update_age" structure members in documentation, to be aligned with the structure definition.
- Place long comment before struct member definition.

Quoted 5 lines

v3:
- Fix miss "break" in indirect action update switch-case.

v4:
- Remove unrelated doc fixes.

Applied to dpdk-next-net/main, thanks.