]> git.droids-corp.org - dpdk.git/commitdiff
ethdev: add shared counter to flow API
authorDeclan Doherty <declan.doherty@intel.com>
Thu, 26 Apr 2018 17:29:19 +0000 (18:29 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 27 Apr 2018 17:00:57 +0000 (18:00 +0100)
Add rte_flow_action_count action data structure to enable shared
counters across multiple flows on a single port or across multiple
flows on multiple ports within the same switch domain. Also this enables
multiple count actions to be specified in a single flow action.

This patch also modifies the existing rte_flow_query API to take the
rte_flow_action structure as an input parameter instead of the
rte_flow_action_type enumeration to allow querying a specific action
from a flow rule when multiple actions of the same type are specified.

This patch also contains updates for the bonding, failsafe and mlx5 PMDs
and testpmd application which are affected by this API change.

Signed-off-by: Declan Doherty <declan.doherty@intel.com>
12 files changed:
app/test-pmd/cmdline_flow.c
app/test-pmd/config.c
app/test-pmd/testpmd.h
doc/guides/prog_guide/rte_flow.rst
doc/guides/rel_notes/release_18_05.rst
drivers/net/bonding/rte_eth_bond_flow.c
drivers/net/failsafe/failsafe_flow.c
drivers/net/mlx5/mlx5.h
drivers/net/mlx5/mlx5_flow.c
lib/librte_ether/rte_flow.c
lib/librte_ether/rte_flow.h
lib/librte_ether/rte_flow_driver.h

index 1ac04a0abcbcb00a90994a5b4b886420e6f9cfd9..5754e7858780357f8f5408bc5ee6b9fd09874bb6 100644 (file)
@@ -420,7 +420,7 @@ struct buffer {
                } destroy; /**< Destroy arguments. */
                struct {
                        uint32_t rule;
-                       enum rte_flow_action_type action;
+                       struct rte_flow_action action;
                } query; /**< Query arguments. */
                struct {
                        uint32_t *group;
@@ -1101,7 +1101,7 @@ static const struct token token_list[] = {
                .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
                             NEXT_ENTRY(RULE_ID),
                             NEXT_ENTRY(PORT_ID)),
-               .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action),
+               .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type),
                             ARGS_ENTRY(struct buffer, args.query.rule),
                             ARGS_ENTRY(struct buffer, port)),
                .call = parse_query,
@@ -3842,7 +3842,7 @@ cmd_flow_parsed(const struct buffer *in)
                break;
        case QUERY:
                port_flow_query(in->port, in->args.query.rule,
-                               in->args.query.action);
+                               &in->args.query.action);
                break;
        case LIST:
                port_flow_list(in->port, in->args.list.group_n,
index 617d3cbd72882998b82b0555fd9a508ae2428720..16fc481ce93eebb6e31dbd6a5a88ff8c5685fe26 100644 (file)
@@ -1114,7 +1114,7 @@ static const struct {
        MK_FLOW_ACTION(FLAG, 0),
        MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
        MK_FLOW_ACTION(DROP, 0),
-       MK_FLOW_ACTION(COUNT, 0),
+       MK_FLOW_ACTION(COUNT, sizeof(struct rte_flow_action_count)),
        MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)),
        MK_FLOW_ACTION(PF, 0),
        MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
@@ -1467,7 +1467,7 @@ port_flow_flush(portid_t port_id)
 /** Query a flow rule. */
 int
 port_flow_query(portid_t port_id, uint32_t rule,
-               enum rte_flow_action_type action)
+               const struct rte_flow_action *action)
 {
        struct rte_flow_error error;
        struct rte_port *port;
@@ -1488,16 +1488,17 @@ port_flow_query(portid_t port_id, uint32_t rule,
                printf("Flow rule #%u not found\n", rule);
                return -ENOENT;
        }
-       if ((unsigned int)action >= RTE_DIM(flow_action) ||
-           !flow_action[action].name)
+       if ((unsigned int)action->type >= RTE_DIM(flow_action) ||
+           !flow_action[action->type].name)
                name = "unknown";
        else
-               name = flow_action[action].name;
-       switch (action) {
+               name = flow_action[action->type].name;
+       switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_COUNT:
                break;
        default:
-               printf("Cannot query action type %d (%s)\n", action, name);
+               printf("Cannot query action type %d (%s)\n",
+                       action->type, name);
                return -ENOTSUP;
        }
        /* Poisoning to make sure PMDs update it in case of error. */
@@ -1505,7 +1506,7 @@ port_flow_query(portid_t port_id, uint32_t rule,
        memset(&query, 0, sizeof(query));
        if (rte_flow_query(port_id, pf->flow, action, &query, &error))
                return port_flow_complain(&error);
-       switch (action) {
+       switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_COUNT:
                printf("%s:\n"
                       " hits_set: %u\n"
@@ -1520,7 +1521,7 @@ port_flow_query(portid_t port_id, uint32_t rule,
                break;
        default:
                printf("Cannot display result for action type %d (%s)\n",
-                      action, name);
+                      action->type, name);
                break;
        }
        return 0;
index a33b525e2dedbd9f67c55dd9ab9dffb9d3e4d072..1af87b8f41833a41f24d75029e9b4db62f78493c 100644 (file)
@@ -620,7 +620,7 @@ int port_flow_create(portid_t port_id,
 int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule);
 int port_flow_flush(portid_t port_id);
 int port_flow_query(portid_t port_id, uint32_t rule,
-                   enum rte_flow_action_type action);
+                   const struct rte_flow_action *action);
 void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group);
 int port_flow_isolate(portid_t port_id, int set);
 
index 5b23778c761a0cb4c2213548409e76f9dd06af70..7af132ebfee5ae2e61589112ccaf7eb3abac1a75 100644 (file)
@@ -1277,17 +1277,19 @@ Actions are performed in list order:
 
 .. table:: Mark, count then redirect
 
-   +-------+--------+-----------+-------+
-   | Index | Action | Field     | Value |
-   +=======+========+===========+=======+
-   | 0     | MARK   | ``mark``  | 0x2a  |
-   +-------+--------+-----------+-------+
-   | 1     | COUNT                      |
-   +-------+--------+-----------+-------+
-   | 2     | QUEUE  | ``queue`` | 10    |
-   +-------+--------+-----------+-------+
-   | 3     | END                        |
-   +-------+----------------------------+
+   +-------+--------+------------+-------+
+   | Index | Action | Field      | Value |
+   +=======+========+============+=======+
+   | 0     | MARK   | ``mark``   | 0x2a  |
+   +-------+--------+------------+-------+
+   | 1     | COUNT  | ``shared`` | 0     |
+   |       |        +------------+-------+
+   |       |        | ``id``     | 0     |
+   +-------+--------+------------+-------+
+   | 2     | QUEUE  | ``queue``  | 10    |
+   +-------+--------+------------+-------+
+   | 3     | END                         |
+   +-------+-----------------------------+
 
 |
 
@@ -1516,23 +1518,36 @@ Drop packets.
 Action: ``COUNT``
 ^^^^^^^^^^^^^^^^^
 
-Enables counters for this rule.
+Adds a counter action to a matched flow.
+
+If more than one count action is specified in a single flow rule, then each
+action must specify a unique id.
 
-These counters can be retrieved and reset through ``rte_flow_query()``, see
+Counters can be retrieved and reset through ``rte_flow_query()``, see
 ``struct rte_flow_query_count``.
 
-- Counters can be retrieved with ``rte_flow_query()``.
-- No configurable properties.
+The shared flag indicates whether the counter is unique to the flow rule the
+action is specified with, or whether it is a shared counter.
+
+For a count action with the shared flag set, then then a global device
+namespace is assumed for the counter id, so that any matched flow rules using
+a count action with the same counter id on the same port will contribute to
+that counter.
+
+For ports within the same switch domain then the counter id namespace extends
+to all ports within that switch domain.
 
 .. _table_rte_flow_action_count:
 
 .. table:: COUNT
 
-   +---------------+
-   | Field         |
-   +===============+
-   | no properties |
-   +---------------+
+   +------------+---------------------+
+   | Field      | Value               |
+   +============+=====================+
+   | ``shared`` | shared counter flag |
+   +------------+---------------------+
+   | ``id``     | counter id          |
+   +------------+---------------------+
 
 Query structure to retrieve and reset flow rule counters:
 
@@ -2282,7 +2297,7 @@ definition.
    int
    rte_flow_query(uint16_t port_id,
                   struct rte_flow *flow,
-                  enum rte_flow_action_type action,
+                  const struct rte_flow_action *action,
                   void *data,
                   struct rte_flow_error *error);
 
@@ -2290,7 +2305,7 @@ Arguments:
 
 - ``port_id``: port identifier of Ethernet device.
 - ``flow``: flow rule handle to query.
-- ``action``: action type to query.
+- ``action``: action to query, this must match prototype from flow rule.
 - ``data``: pointer to storage for the associated query data type.
 - ``error``: perform verbose error reporting if not NULL. PMDs initialize
   this structure in case of error only.
index 4af28156cfb2556607964867d3ed967e69e9883a..a005e77dca3ceae073cfab09902a22a92db690e1 100644 (file)
@@ -293,6 +293,10 @@ API Changes
   * PORT_ID pattern item and actions were added to match and target DPDK
     port IDs at a higher level than PHY_PORT.
 
+* ethdev: change flow APIs regarding count action:
+  * ``rte_flow_create()`` API count action now requires the ``struct rte_flow_action_count``.
+  * ``rte_flow_query()`` API parameter changed from action type to action structure.
+
 
 ABI Changes
 -----------
index 8093c04f57bd08ef33d56913479873fd76ffd90c..31e4bcaeb3470ba359f935c9c8938daa6ef9441c 100644 (file)
@@ -152,6 +152,7 @@ bond_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *err)
 
 static int
 bond_flow_query_count(struct rte_eth_dev *dev, struct rte_flow *flow,
+                     const struct rte_flow_action *action,
                      struct rte_flow_query_count *count,
                      struct rte_flow_error *err)
 {
@@ -165,7 +166,7 @@ bond_flow_query_count(struct rte_eth_dev *dev, struct rte_flow *flow,
        rte_memcpy(&slave_count, count, sizeof(slave_count));
        for (i = 0; i < internals->slave_count; i++) {
                ret = rte_flow_query(internals->slaves[i].port_id,
-                                    flow->flows[i], RTE_FLOW_ACTION_TYPE_COUNT,
+                                    flow->flows[i], action,
                                     &slave_count, err);
                if (unlikely(ret != 0)) {
                        RTE_BOND_LOG(ERR, "Failed to query flow on"
@@ -182,12 +183,12 @@ bond_flow_query_count(struct rte_eth_dev *dev, struct rte_flow *flow,
 
 static int
 bond_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
-               enum rte_flow_action_type type, void *arg,
+               const struct rte_flow_action *action, void *arg,
                struct rte_flow_error *err)
 {
-       switch (type) {
+       switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_COUNT:
-               return bond_flow_query_count(dev, flow, arg, err);
+               return bond_flow_query_count(dev, flow, action, arg, err);
        default:
                return rte_flow_error_set(err, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ACTION, arg,
index a97f4075df23776140d02c7626d2cda8111e4805..bfe42fcee00798e611fe43c7af9adbe83986486b 100644 (file)
@@ -174,7 +174,7 @@ fs_flow_flush(struct rte_eth_dev *dev,
 static int
 fs_flow_query(struct rte_eth_dev *dev,
              struct rte_flow *flow,
-             enum rte_flow_action_type type,
+             const struct rte_flow_action *action,
              void *arg,
              struct rte_flow_error *error)
 {
@@ -185,7 +185,7 @@ fs_flow_query(struct rte_eth_dev *dev,
        if (sdev != NULL) {
                int ret = rte_flow_query(PORT_ID(sdev),
                                         flow->flows[SUB_ID(sdev)],
-                                        type, arg, error);
+                                        action, arg, error);
 
                if ((ret = fs_err(sdev, ret))) {
                        fs_unlock(dev, 0);
index 874978baa8c413eff90bb66196d07da08d1c46b8..c4d1d456b8c7274e8550e8f96276a8cc4a2b6f09 100644 (file)
@@ -277,7 +277,7 @@ int mlx5_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
 void mlx5_flow_list_flush(struct rte_eth_dev *dev, struct mlx5_flows *list);
 int mlx5_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error);
 int mlx5_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
-                   enum rte_flow_action_type action, void *data,
+                   const struct rte_flow_action *action, void *data,
                    struct rte_flow_error *error);
 int mlx5_flow_isolate(struct rte_eth_dev *dev, int enable,
                      struct rte_flow_error *error);
index 8f5fcf4d69dbe5b6a474026f893a35ae74959ca3..c385f6ced100a7f4b8b435b7e189308ff33b3c59 100644 (file)
@@ -3079,7 +3079,7 @@ mlx5_flow_query_count(struct ibv_counter_set *cs,
 int
 mlx5_flow_query(struct rte_eth_dev *dev __rte_unused,
                struct rte_flow *flow,
-               enum rte_flow_action_type action __rte_unused,
+               const struct rte_flow_action *action __rte_unused,
                void *data,
                struct rte_flow_error *error)
 {
index 4f94ac9b5129e5f0b88fbe2b4ff3c456a0daff19..7947529da77e29c30aed2f15021188418a47a0d9 100644 (file)
@@ -233,7 +233,7 @@ rte_flow_flush(uint16_t port_id,
 int
 rte_flow_query(uint16_t port_id,
               struct rte_flow *flow,
-              enum rte_flow_action_type action,
+              const struct rte_flow_action *action,
               void *data,
               struct rte_flow_error *error)
 {
index d390bbf5af9d95ccdeae92494f181b76943655af..f8ba71cdb78b51bbc9b6d7bafde48b206df9e6d1 100644 (file)
@@ -1314,7 +1314,7 @@ enum rte_flow_action_type {
         * These counters can be retrieved and reset through rte_flow_query(),
         * see struct rte_flow_query_count.
         *
-        * No associated configuration structure.
+        * See struct rte_flow_action_count.
         */
        RTE_FLOW_ACTION_TYPE_COUNT,
 
@@ -1546,6 +1546,38 @@ struct rte_flow_action_queue {
        uint16_t index; /**< Queue index to use. */
 };
 
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_COUNT
+ *
+ * Adds a counter action to a matched flow.
+ *
+ * If more than one count action is specified in a single flow rule, then each
+ * action must specify a unique id.
+ *
+ * Counters can be retrieved and reset through ``rte_flow_query()``, see
+ * ``struct rte_flow_query_count``.
+ *
+ * The shared flag indicates whether the counter is unique to the flow rule the
+ * action is specified with, or whether it is a shared counter.
+ *
+ * For a count action with the shared flag set, then then a global device
+ * namespace is assumed for the counter id, so that any matched flow rules using
+ * a count action with the same counter id on the same port will contribute to
+ * that counter.
+ *
+ * For ports within the same switch domain then the counter id namespace extends
+ * to all ports within that switch domain.
+ */
+struct rte_flow_action_count {
+       uint32_t shared:1; /**< Share counter ID with other flow rules. */
+       uint32_t reserved:31; /**< Reserved, must be zero. */
+       uint32_t id; /**< Counter ID. */
+};
+
 /**
  * RTE_FLOW_ACTION_TYPE_COUNT (query)
  *
@@ -2044,7 +2076,7 @@ rte_flow_flush(uint16_t port_id,
  * @param flow
  *   Flow rule handle to query.
  * @param action
- *   Action type to query.
+ *   Action definition as defined in original flow rule.
  * @param[in, out] data
  *   Pointer to storage for the associated query data type.
  * @param[out] error
@@ -2057,7 +2089,7 @@ rte_flow_flush(uint16_t port_id,
 int
 rte_flow_query(uint16_t port_id,
               struct rte_flow *flow,
-              enum rte_flow_action_type action,
+              const struct rte_flow_action *action,
               void *data,
               struct rte_flow_error *error);
 
index 3800310ba1380579534da0584c7c2c1447096b30..1c90c600da020aa9adeaa6d279f22e319ca18169 100644 (file)
@@ -88,7 +88,7 @@ struct rte_flow_ops {
        int (*query)
                (struct rte_eth_dev *,
                 struct rte_flow *,
-                enum rte_flow_action_type,
+                const struct rte_flow_action *,
                 void *,
                 struct rte_flow_error *);
        /** See rte_flow_isolate(). */