get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/80721/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 80721,
    "url": "http://patchwork.dpdk.org/api/patches/80721/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20201014114015.17197-2-andreyv@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20201014114015.17197-2-andreyv@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20201014114015.17197-2-andreyv@nvidia.com",
    "date": "2020-10-14T11:40:14",
    "name": "[v8,1/2] ethdev: add shared actions to flow API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "b527905a6fefe79f28ad78f800a88cef7bd8adce",
    "submitter": {
        "id": 1969,
        "url": "http://patchwork.dpdk.org/api/people/1969/?format=api",
        "name": "Andrey Vesnovaty",
        "email": "andreyv@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20201014114015.17197-2-andreyv@nvidia.com/mbox/",
    "series": [
        {
            "id": 12955,
            "url": "http://patchwork.dpdk.org/api/series/12955/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=12955",
            "date": "2020-10-14T11:40:13",
            "name": "RTE flow shared action",
            "version": 8,
            "mbox": "http://patchwork.dpdk.org/series/12955/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/80721/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/80721/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id AC7EBA04B7;\n\tWed, 14 Oct 2020 13:40:45 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id DD62A1DE04;\n\tWed, 14 Oct 2020 13:40:29 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 9FDE81DDF9\n for <dev@dpdk.org>; Wed, 14 Oct 2020 13:40:26 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n andreyv@nvidia.com) with SMTP; 14 Oct 2020 14:40:23 +0300",
            "from nvidia.com (r-arch-host11.mtr.labs.mlnx [10.213.43.60])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09EBeKD7000998;\n Wed, 14 Oct 2020 14:40:23 +0300"
        ],
        "From": "Andrey Vesnovaty <andreyv@nvidia.com>",
        "To": "dev@dpdk.org",
        "Cc": "jer@marvell.com, jerinjacobk@gmail.com, thomas@monjalon.net,\n ferruh.yigit@intel.com, stephen@networkplumber.org,\n bruce.richardson@intel.com, orika@nvidia.com, viacheslavo@nvidia.com,\n andrey.vesnovaty@gmail.com, mdr@ashroe.eu, nhorman@tuxdriver.com,\n ajit.khaparde@broadcom.com, samik.gupta@broadcom.com,\n andrew.rybchenko@oktetlabs.ru",
        "Date": "Wed, 14 Oct 2020 14:40:14 +0300",
        "Message-Id": "<20201014114015.17197-2-andreyv@nvidia.com>",
        "X-Mailer": "git-send-email 2.26.2",
        "In-Reply-To": "<20201014114015.17197-1-andreyv@nvidia.com>",
        "References": "<20200702120511.16315-1-andreyv@mellanox.com>\n <20201014114015.17197-1-andreyv@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v8 1/2] ethdev: add shared actions to flow API",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Introduce extension of flow action API enabling sharing of single\nrte_flow_action in multiple flows. The API intended for PMDs, where\nmultiple HW offloaded flows can reuse the same HW essence/object\nrepresenting flow action and modification of such an essence/object\naffects all the rules using it.\n\nMotivation and example\n===\nAdding or removing one or more queues to RSS used by multiple flow rules\nimposes per rule toll for current DPDK flow API; the scenario requires\nfor each flow sharing cloned RSS action:\n- call `rte_flow_destroy()`\n- call `rte_flow_create()` with modified RSS action\n\nAPI for sharing action and its in-place update benefits:\n- reduce the overhead of multiple RSS flow rules reconfiguration\n- optimize resource utilization by sharing action across multiple\n  flows\n\nChange description\n===\n\nShared action\n===\nIn order to represent flow action shared by multiple flows new action\ntype RTE_FLOW_ACTION_TYPE_SHARED is introduced (see `enum\nrte_flow_action_type`).\nActually the introduced API decouples action from any specific flow and\nenables sharing of single action by its handle across multiple flows.\n\nShared action create/use/destroy\n===\nShared action may be reused by some or none flow rules at any given\nmoment, i.e. shared action resides outside of the context of any flow.\nShared action represent HW resources/objects used for action offloading\nimplementation.\nAPI for shared action create (see `rte_flow_shared_action_create()`):\n- should allocate HW resources and make related initializations required\n  for shared action implementation.\n- make necessary preparations to maintain shared access to\n  the action resources, configuration and state.\nAPI for shared action destroy (see `rte_flow_shared_action_destroy()`)\nshould release HW resources and make related cleanups required for shared\naction implementation.\n\nIn order to share some flow action reuse the handle of type\n`struct rte_flow_shared_action` returned by\nrte_flow_shared_action_create() as a `conf` field of\n`struct rte_flow_action` (see \"example\" section).\n\nIf some shared action not used by any flow rule all resources allocated\nby the shared action can be released by rte_flow_shared_action_destroy()\n(see \"example\" section). The shared action handle passed as argument to\ndestroy API should not be used any further i.e. result of the usage is\nundefined.\n\nShared action re-configuration\n===\nShared action behavior defined by its configuration can be updated via\nrte_flow_shared_action_update() (see \"example\" section). The shared\naction update operation modifies HW related resources/objects allocated\non the action creation. The number of operations performed by the update\noperation should not depend on the number of flows sharing the related\naction. On return of shared action update API action behavior should be\naccording to updated configuration for all flows sharing the action.\n\nShared action query\n===\nProvide separate API to query shared action state (see\nrte_flow_shared_action_update()). Taking a counter as an example: query\nreturns value aggregating all counter increments across all flow rules\nsharing the counter. This API doesn't query shared action configuration\nsince it is controlled by rte_flow_shared_action_create() and\nrte_flow_shared_action_update() APIs and no supposed to change by other\nmeans.\n\nexample\n===\n\nstruct rte_flow_action actions[2];\nstruct rte_flow_shared_action_conf conf;\nstruct rte_flow_action action;\n/* skipped: initialize conf and action */\nstruct rte_flow_shared_action *handle =\n\trte_flow_shared_action_create(port_id, &conf, &action, &error);\nactions[0].type = RTE_FLOW_ACTION_TYPE_SHARED;\nactions[0].conf = handle;\nactions[1].type = RTE_FLOW_ACTION_TYPE_END;\n/* skipped: init attr0 & pattern0 args */\nstruct rte_flow *flow0 = rte_flow_create(port_id, &attr0, pattern0,\n\t\t\t\t\tactions, error);\n/* create more rules reusing shared action */\nstruct rte_flow *flow1 = rte_flow_create(port_id, &attr1, pattern1,\n\t\t\t\t\tactions, error);\n/* skipped: for flows 2 till N */\nstruct rte_flow *flowN = rte_flow_create(port_id, &attrN, patternN,\n\t\t\t\t\tactions, error);\n/* update shared action */\nstruct rte_flow_action updated_action;\n/*\n * skipped: initialize updated_action according to desired action\n * configuration change\n */\nrte_flow_shared_action_update(port_id, handle, &updated_action, error);\n/*\n * from now on all flows 1 till N will act according to configuration of\n * updated_action\n */\n/* skipped: destroy all flows 1 till N */\nrte_flow_shared_action_destroy(port_id, handle, error);\n\nSigned-off-by: Andrey Vesnovaty <andreyv@nvidia.com>\nAcked-by: Ori Kam <orika@nvidia.com>\nAcked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\n---\n doc/guides/prog_guide/rte_flow.rst       |  19 +++\n doc/guides/rel_notes/release_20_11.rst   |  10 ++\n lib/librte_ethdev/rte_ethdev_version.map |   4 +\n lib/librte_ethdev/rte_flow.c             |  90 ++++++++++++\n lib/librte_ethdev/rte_flow.h             | 172 ++++++++++++++++++++++-\n lib/librte_ethdev/rte_flow_driver.h      |  23 +++\n 6 files changed, 317 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst\nindex 119b128739..ca74aa1d7a 100644\n--- a/doc/guides/prog_guide/rte_flow.rst\n+++ b/doc/guides/prog_guide/rte_flow.rst\n@@ -2666,6 +2666,25 @@ timeout passed without any matching on the flow.\n    | ``context``  | user input flow context         |\n    +--------------+---------------------------------+\n \n+Action: ``SHARED``\n+^^^^^^^^^^^^^^^^^^\n+\n+Flow utilize shared action by handle as returned from\n+``rte_flow_shared_action_create()``.\n+\n+The behaviour of the shared action defined by ``action`` argument of type\n+``struct rte_flow_action`` passed to ``rte_flow_shared_action_create()``.\n+\n+.. _table_rte_flow_shared_action:\n+\n+.. table:: SHARED\n+\n+   +---------------+\n+   | Field         |\n+   +===============+\n+   | no properties |\n+   +---------------+\n+\n Negative types\n ~~~~~~~~~~~~~~\n \ndiff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst\nindex bcc0fc211a..0e8765dd10 100644\n--- a/doc/guides/rel_notes/release_20_11.rst\n+++ b/doc/guides/rel_notes/release_20_11.rst\n@@ -148,6 +148,16 @@ New Features\n   * Extern objects and functions can be plugged into the pipeline.\n   * Transaction-oriented table updates.\n \n+* **Added ethdev API to support shared action for RTE flow.**\n+\n+  Added shared action support to utilize single flow action in multiple flow\n+  rules. An update of shared action configuration alters the behavior of all\n+  flow rules using it.\n+\n+  * Added new action: ``RTE_FLOW_ACTION_TYPE_SHARED`` to use shared action\n+    as flow action.\n+  * Added new flow APIs to create/update/destroy/query shared action.\n+\n \n Removed Items\n -------------\ndiff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map\nindex f8a0945812..31242dabbf 100644\n--- a/lib/librte_ethdev/rte_ethdev_version.map\n+++ b/lib/librte_ethdev/rte_ethdev_version.map\n@@ -232,6 +232,10 @@ EXPERIMENTAL {\n \trte_eth_fec_get_capability;\n \trte_eth_fec_get;\n \trte_eth_fec_set;\n+\trte_flow_shared_action_create;\n+\trte_flow_shared_action_destroy;\n+\trte_flow_shared_action_query;\n+\trte_flow_shared_action_update;\n };\n \n INTERNAL {\ndiff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c\nindex 8d1b279bcb..652170cc25 100644\n--- a/lib/librte_ethdev/rte_flow.c\n+++ b/lib/librte_ethdev/rte_flow.c\n@@ -174,6 +174,13 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {\n \tMK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),\n \tMK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),\n \tMK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),\n+\t/**\n+\t * Shared action represented as handle of type\n+\t * (struct rte_flow_shared action *) stored in conf field (see\n+\t * struct rte_flow_action); no need for additional structure to * store\n+\t * shared action handle.\n+\t */\n+\tMK_FLOW_ACTION(SHARED, 0),\n };\n \n int\n@@ -989,3 +996,86 @@ rte_flow_get_aged_flows(uint16_t port_id, void **contexts,\n \t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n \t\t\t\t  NULL, rte_strerror(ENOTSUP));\n }\n+\n+struct rte_flow_shared_action *\n+rte_flow_shared_action_create(uint16_t port_id,\n+\t\t\t      const struct rte_flow_shared_action_conf *conf,\n+\t\t\t      const struct rte_flow_action *action,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tstruct rte_flow_shared_action *shared_action;\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\n+\tif (unlikely(!ops))\n+\t\treturn NULL;\n+\tif (unlikely(!ops->shared_action_create)) {\n+\t\trte_flow_error_set(error, ENOSYS,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   rte_strerror(ENOSYS));\n+\t\treturn NULL;\n+\t}\n+\tshared_action = ops->shared_action_create(&rte_eth_devices[port_id],\n+\t\t\t\t\t\t  conf, action, error);\n+\tif (shared_action == NULL)\n+\t\tflow_err(port_id, -rte_errno, error);\n+\treturn shared_action;\n+}\n+\n+int\n+rte_flow_shared_action_destroy(uint16_t port_id,\n+\t\t\t      struct rte_flow_shared_action *action,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tint ret;\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\n+\tif (unlikely(!ops))\n+\t\treturn -rte_errno;\n+\tif (unlikely(!ops->shared_action_destroy))\n+\t\treturn rte_flow_error_set(error, ENOSYS,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, rte_strerror(ENOSYS));\n+\tret = ops->shared_action_destroy(&rte_eth_devices[port_id], action,\n+\t\t\t\t\t error);\n+\treturn flow_err(port_id, ret, error);\n+}\n+\n+int\n+rte_flow_shared_action_update(uint16_t port_id,\n+\t\t\t      struct rte_flow_shared_action *action,\n+\t\t\t      const struct rte_flow_action *update,\n+\t\t\t      struct rte_flow_error *error)\n+{\n+\tint ret;\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\n+\tif (unlikely(!ops))\n+\t\treturn -rte_errno;\n+\tif (unlikely(!ops->shared_action_update))\n+\t\treturn rte_flow_error_set(error, ENOSYS,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, rte_strerror(ENOSYS));\n+\tret = ops->shared_action_update(&rte_eth_devices[port_id], action,\n+\t\t\t\t\tupdate, error);\n+\treturn flow_err(port_id, ret, error);\n+}\n+\n+int\n+rte_flow_shared_action_query(uint16_t port_id,\n+\t\t\t     const struct rte_flow_shared_action *action,\n+\t\t\t     void *data,\n+\t\t\t     struct rte_flow_error *error)\n+{\n+\tint ret;\n+\tconst struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);\n+\n+\tif (unlikely(!ops))\n+\t\treturn -rte_errno;\n+\tif (unlikely(!ops->shared_action_query))\n+\t\treturn rte_flow_error_set(error, ENOSYS,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, rte_strerror(ENOSYS));\n+\tret = ops->shared_action_query(&rte_eth_devices[port_id], action,\n+\t\t\t\t       data, error);\n+\treturn flow_err(port_id, ret, error);\n+}\ndiff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h\nindex da8bfa5489..ede8bf7230 100644\n--- a/lib/librte_ethdev/rte_flow.h\n+++ b/lib/librte_ethdev/rte_flow.h\n@@ -1714,7 +1714,8 @@ enum rte_flow_action_type {\n \t/**\n \t * Enables counters for this flow rule.\n \t *\n-\t * These counters can be retrieved and reset through rte_flow_query(),\n+\t * These counters can be retrieved and reset through rte_flow_query() or\n+\t * rte_flow_shared_action_query() if the action provided via handle,\n \t * see struct rte_flow_query_count.\n \t *\n \t * See struct rte_flow_action_count.\n@@ -2132,6 +2133,14 @@ enum rte_flow_action_type {\n \t * see enum RTE_ETH_EVENT_FLOW_AGED\n \t */\n \tRTE_FLOW_ACTION_TYPE_AGE,\n+\n+\t/**\n+\t * Describe action shared across multiple flow rules.\n+\t *\n+\t * Allow multiple rules reference the same action by handle (see\n+\t * struct rte_flow_shared_action).\n+\t */\n+\tRTE_FLOW_ACTION_TYPE_SHARED,\n };\n \n /**\n@@ -2693,6 +2702,20 @@ struct rte_flow_action_set_dscp {\n \tuint8_t dscp;\n };\n \n+\n+/**\n+ * RTE_FLOW_ACTION_TYPE_SHARED\n+ *\n+ * Opaque type returned after successfully creating a shared action.\n+ *\n+ * This handle can be used to manage and query the related action:\n+ * - share it across multiple flow rules\n+ * - update action configuration\n+ * - query action data\n+ * - destroy action\n+ */\n+struct rte_flow_shared_action;\n+\n /* Mbuf dynamic field offset for metadata. */\n extern int32_t rte_flow_dynf_metadata_offs;\n \n@@ -3357,6 +3380,153 @@ int\n rte_flow_get_aged_flows(uint16_t port_id, void **contexts,\n \t\t\tuint32_t nb_contexts, struct rte_flow_error *error);\n \n+/**\n+ * Specify shared action configuration\n+ */\n+struct rte_flow_shared_action_conf {\n+\t/**\n+\t * Flow direction for shared action configuration.\n+\t *\n+\t * Shared action should be valid at least for one flow direction,\n+\t * otherwise it is invalid for both ingress and egress rules.\n+\t */\n+\tuint32_t ingress:1;\n+\t/**< Action valid for rules applied to ingress traffic. */\n+\tuint32_t egress:1;\n+\t/**< Action valid for rules applied to egress traffic. */\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Create shared action for reuse in multiple flow rules.\n+ * The created shared action has single state and configuration\n+ * across all flow rules using it.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] conf\n+ *   Shared action configuration.\n+ * @param[in] action\n+ *   Action configuration for shared action creation.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   A valid handle in case of success, NULL otherwise and rte_errno is set\n+ *   to one of the error codes defined:\n+ *   - (ENODEV) if *port_id* invalid.\n+ *   - (ENOSYS) if underlying device does not support this functionality.\n+ *   - (EIO) if underlying device is removed.\n+ *   - (EINVAL) if *action* invalid.\n+ *   - (ENOTSUP) if *action* valid but unsupported.\n+ */\n+__rte_experimental\n+struct rte_flow_shared_action *\n+rte_flow_shared_action_create(uint16_t port_id,\n+\t\t\t      const struct rte_flow_shared_action_conf *conf,\n+\t\t\t      const struct rte_flow_action *action,\n+\t\t\t      struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Destroy the shared action by handle.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] action\n+ *   Handle for the shared action to be destroyed.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   - (0) if success.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-ENOSYS) if underlying device does not support this functionality.\n+ *   - (-EIO) if underlying device is removed.\n+ *   - (-ENOENT) if action pointed by *action* handle was not found.\n+ *   - (-ETOOMANYREFS) if action pointed by *action* handle still used by one or\n+ *     more rules\n+ *   rte_errno is also set.\n+ */\n+__rte_experimental\n+int\n+rte_flow_shared_action_destroy(uint16_t port_id,\n+\t\t\t       struct rte_flow_shared_action *action,\n+\t\t\t       struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Update in-place the shared action configuration pointed by *action* handle\n+ * with the configuration provided as *update* argument.\n+ * The update of the shared action configuration effects all flow rules reusing\n+ * the action via handle.\n+ *\n+ * @param[in] port_id\n+ *    The port identifier of the Ethernet device.\n+ * @param[in] action\n+ *   Handle for the shared action to be updated.\n+ * @param[in] update\n+ *   Action specification used to modify the action pointed by handle.\n+ *   *update* should be of same type with the action pointed by the *action*\n+ *   handle argument, otherwise considered as invalid.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ * @return\n+ *   - (0) if success.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-ENOSYS) if underlying device does not support this functionality.\n+ *   - (-EIO) if underlying device is removed.\n+ *   - (-EINVAL) if *update* invalid.\n+ *   - (-ENOTSUP) if *update* valid but unsupported.\n+ *   - (-ENOENT) if action pointed by *ctx* was not found.\n+ *   rte_errno is also set.\n+ */\n+__rte_experimental\n+int\n+rte_flow_shared_action_update(uint16_t port_id,\n+\t\t\t      struct rte_flow_shared_action *action,\n+\t\t\t      const struct rte_flow_action *update,\n+\t\t\t      struct rte_flow_error *error);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Query the shared action by handle.\n+ *\n+ * Retrieve action-specific data such as counters.\n+ * Data is gathered by special action which may be present/referenced in\n+ * more than one flow rule definition.\n+ *\n+ * \\see RTE_FLOW_ACTION_TYPE_COUNT\n+ *\n+ * @param port_id\n+ *   Port identifier of Ethernet device.\n+ * @param[in] action\n+ *   Handle for the shared action to query.\n+ * @param[in, out] data\n+ *   Pointer to storage for the associated query data type.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL. PMDs initialize this\n+ *   structure in case of error only.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+__rte_experimental\n+int\n+rte_flow_shared_action_query(uint16_t port_id,\n+\t\t\t     const struct rte_flow_shared_action *action,\n+\t\t\t     void *data,\n+\t\t\t     struct rte_flow_error *error);\n+\n #ifdef __cplusplus\n }\n #endif\ndiff --git a/lib/librte_ethdev/rte_flow_driver.h b/lib/librte_ethdev/rte_flow_driver.h\nindex 11a0f77cc2..58f56b0262 100644\n--- a/lib/librte_ethdev/rte_flow_driver.h\n+++ b/lib/librte_ethdev/rte_flow_driver.h\n@@ -108,6 +108,29 @@ struct rte_flow_ops {\n \t\t void **context,\n \t\t uint32_t nb_contexts,\n \t\t struct rte_flow_error *err);\n+\t/** See rte_flow_shared_action_create() */\n+\tstruct rte_flow_shared_action *(*shared_action_create)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_shared_action_conf *conf,\n+\t\t const struct rte_flow_action *action,\n+\t\t struct rte_flow_error *error);\n+\t/** See rte_flow_shared_action_destroy() */\n+\tint (*shared_action_destroy)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t struct rte_flow_shared_action *shared_action,\n+\t\t struct rte_flow_error *error);\n+\t/** See rte_flow_shared_action_update() */\n+\tint (*shared_action_update)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t struct rte_flow_shared_action *shared_action,\n+\t\t const struct rte_flow_action *update,\n+\t\t struct rte_flow_error *error);\n+\t/** See rte_flow_shared_action_query() */\n+\tint (*shared_action_query)\n+\t\t(struct rte_eth_dev *dev,\n+\t\t const struct rte_flow_shared_action *shared_action,\n+\t\t void *data,\n+\t\t struct rte_flow_error *error);\n };\n \n /**\n",
    "prefixes": [
        "v8",
        "1/2"
    ]
}