get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 82847,
    "url": "https://patches.dpdk.org/api/patches/82847/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1604008681-414157-8-git-send-email-matan@nvidia.com/",
    "project": {
        "id": 1,
        "url": "https://patches.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": "<1604008681-414157-8-git-send-email-matan@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1604008681-414157-8-git-send-email-matan@nvidia.com",
    "date": "2020-10-29T21:58:00",
    "name": "[7/8] net/mlx5: optimize shared RSS action memory",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fbc96fa8b23f636b050d8733aa1f9bc8892051ff",
    "submitter": {
        "id": 1911,
        "url": "https://patches.dpdk.org/api/people/1911/?format=api",
        "name": "Matan Azrad",
        "email": "matan@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "https://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1604008681-414157-8-git-send-email-matan@nvidia.com/mbox/",
    "series": [
        {
            "id": 13477,
            "url": "https://patches.dpdk.org/api/series/13477/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=13477",
            "date": "2020-10-29T21:57:53",
            "name": "net/mlx5: support flow hit steering action",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/13477/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/82847/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/82847/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 17BADA04B5;\n\tThu, 29 Oct 2020 23:00:34 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 91258CBA8;\n\tThu, 29 Oct 2020 22:58:23 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id AA890CAC0\n for <dev@dpdk.org>; Thu, 29 Oct 2020 22:58:11 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n matan@nvidia.com) with SMTP; 29 Oct 2020 23:58:05 +0200",
            "from nvidia.com (pegasus25.mtr.labs.mlnx [10.210.16.10])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TLw4Tu022832;\n Thu, 29 Oct 2020 23:58:05 +0200"
        ],
        "From": "Matan Azrad <matan@nvidia.com>",
        "To": "Viacheslav Ovsiienko <viacheslavo@nvidia.com>",
        "Cc": "dev@dpdk.org",
        "Date": "Thu, 29 Oct 2020 21:58:00 +0000",
        "Message-Id": "<1604008681-414157-8-git-send-email-matan@nvidia.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1604008681-414157-1-git-send-email-matan@nvidia.com>",
        "References": "<1604008681-414157-1-git-send-email-matan@nvidia.com>",
        "Subject": "[dpdk-dev] [PATCH 7/8] net/mlx5: optimize shared RSS action memory",
        "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": "The RSS shared action was saved in flow memory by a pointer.\nIt means that every flow memory includes 8B only for optional shared\nRSS case.\n\nMove the RSS objects to be used by indexed pool which reduces the flow\nhandle memory to 4B.\n\nSo, now, the shared action handler is also just a 4B index.\n\nSigned-off-by: Matan Azrad <matan@nvidia.com>\n---\n drivers/net/mlx5/mlx5.c         |  12 +++\n drivers/net/mlx5/mlx5.h         |   8 +-\n drivers/net/mlx5/mlx5_flow.c    | 128 +++++++++++++--------------\n drivers/net/mlx5/mlx5_flow.h    |  24 +++---\n drivers/net/mlx5/mlx5_flow_dv.c | 186 +++++++++++++++++++++++-----------------\n 5 files changed, 194 insertions(+), 164 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex a5c50ff..245685e 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -336,6 +336,18 @@ static LIST_HEAD(, mlx5_dev_ctx_shared) mlx5_dev_ctx_list =\n \t\t.need_lock = 1,\n \t\t.type = \"mlx5_flow_tnl_tbl_ipool\",\n \t},\n+\t{\n+\t\t.size = sizeof(struct mlx5_shared_action_rss),\n+\t\t.trunk_size = 64,\n+\t\t.grow_trunk = 3,\n+\t\t.grow_shift = 2,\n+\t\t.need_lock = 1,\n+\t\t.release_mem_en = 1,\n+\t\t.malloc = mlx5_malloc,\n+\t\t.free = mlx5_free,\n+\t\t.type = \"mlx5_shared_action_rss\",\n+\t},\n+\n };\n \n \ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex cf6975d..9b1e5d5 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -53,6 +53,7 @@ enum mlx5_ipool_index {\n \tMLX5_IPOOL_RSS_EXPANTION_FLOW_ID, /* Pool for Queue/RSS flow ID. */\n \tMLX5_IPOOL_TUNNEL_ID, /* Pool for flow tunnel ID. */\n \tMLX5_IPOOL_TNL_TBL_ID, /* Pool for tunnel table ID. */\n+\tMLX5_IPOOL_RSS_SHARED_ACTIONS, /* Pool for RSS shared actions. */\n \tMLX5_IPOOL_MAX,\n };\n \n@@ -895,8 +896,6 @@ enum mlx5_txq_modify_type {\n \tMLX5_TXQ_MOD_ERR2RDY, /* modify state from error to ready. */\n };\n \n-\n-\n /* HW objects operations structure. */\n struct mlx5_obj_ops {\n \tint (*rxq_obj_modify_vlan_strip)(struct mlx5_rxq_obj *rxq_obj, int on);\n@@ -922,6 +921,8 @@ struct mlx5_obj_ops {\n \tvoid (*txq_obj_release)(struct mlx5_txq_obj *txq_obj);\n };\n \n+#define MLX5_RSS_HASH_FIELDS_LEN RTE_DIM(mlx5_rss_hash_fields)\n+\n struct mlx5_priv {\n \tstruct rte_eth_dev_data *dev_data;  /* Pointer to device data. */\n \tstruct mlx5_dev_ctx_shared *sh; /* Shared device context. */\n@@ -998,8 +999,7 @@ struct mlx5_priv {\n \tstruct mlx5_mp_id mp_id; /* ID of a multi-process process */\n \tLIST_HEAD(fdir, mlx5_fdir_flow) fdir_flows; /* fdir flows. */\n \trte_spinlock_t shared_act_sl; /* Shared actions spinlock. */\n-\tLIST_HEAD(shared_action, rte_flow_shared_action) shared_actions;\n-\t/* shared actions */\n+\tuint32_t rss_shared_actions; /* RSS shared actions. */\n };\n \n #define PORT_ID(priv) ((priv)->dev_data->port_id)\ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex a6e60af..29e67f4 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -3306,6 +3306,8 @@ struct mlx5_translated_shared_action {\n  * action handling should be preformed on *shared* actions list returned\n  * from this call.\n  *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n  * @param[in] actions\n  *   List of actions to translate.\n  * @param[out] shared\n@@ -3323,12 +3325,14 @@ struct mlx5_translated_shared_action {\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n static int\n-flow_shared_actions_translate(const struct rte_flow_action actions[],\n-\tstruct mlx5_translated_shared_action *shared,\n-\tint *shared_n,\n-\tstruct rte_flow_action **translated_actions,\n-\tstruct rte_flow_error *error)\n+flow_shared_actions_translate(struct rte_eth_dev *dev,\n+\t\t\t      const struct rte_flow_action actions[],\n+\t\t\t      struct mlx5_translated_shared_action *shared,\n+\t\t\t      int *shared_n,\n+\t\t\t      struct rte_flow_action **translated_actions,\n+\t\t\t      struct rte_flow_error *error)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct rte_flow_action *translated = NULL;\n \tsize_t actions_size;\n \tint n;\n@@ -3360,15 +3364,20 @@ struct mlx5_translated_shared_action {\n \t}\n \tmemcpy(translated, actions, actions_size);\n \tfor (shared_end = shared + copied_n; shared < shared_end; shared++) {\n-\t\tconst struct rte_flow_shared_action *shared_action;\n-\n-\t\tshared_action = shared->action;\n-\t\tswitch (shared_action->type) {\n-\t\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n+\t\tstruct mlx5_shared_action_rss *shared_rss;\n+\t\tuint32_t act_idx = (uint32_t)(uintptr_t)shared->action;\n+\t\tuint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;\n+\t\tuint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET)\n+\t\t\t\t\t\t\t\t\t   - 1);\n+\n+\t\tswitch (type) {\n+\t\tcase MLX5_SHARED_ACTION_TYPE_RSS:\n+\t\t\tshared_rss = mlx5_ipool_get\n+\t\t\t  (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx);\n \t\t\ttranslated[shared->index].type =\n \t\t\t\tRTE_FLOW_ACTION_TYPE_RSS;\n \t\t\ttranslated[shared->index].conf =\n-\t\t\t\t&shared_action->rss.origin;\n+\t\t\t\t&shared_rss->origin;\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tmlx5_free(translated);\n@@ -3384,44 +3393,44 @@ struct mlx5_translated_shared_action {\n /**\n  * Get Shared RSS action from the action list.\n  *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n  * @param[in] shared\n  *   Pointer to the list of actions.\n  * @param[in] shared_n\n  *   Actions list length.\n  *\n  * @return\n- *   Pointer to the MLX5 RSS action if exists, otherwise return NULL.\n+ *   The MLX5 RSS action ID if exists, otherwise return 0.\n  */\n-static struct mlx5_shared_action_rss *\n-flow_get_shared_rss_action(struct mlx5_translated_shared_action *shared,\n+static uint32_t\n+flow_get_shared_rss_action(struct rte_eth_dev *dev,\n+\t\t\t   struct mlx5_translated_shared_action *shared,\n \t\t\t   int shared_n)\n {\n \tstruct mlx5_translated_shared_action *shared_end;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_shared_action_rss *shared_rss;\n \n-\tfor (shared_end = shared + shared_n; shared < shared_end; shared++) {\n-\t\tstruct rte_flow_shared_action *shared_action;\n \n-\t\tshared_action = shared->action;\n-\t\tswitch (shared_action->type) {\n-\t\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n-\t\t\t__atomic_add_fetch(&shared_action->refcnt, 1,\n+\tfor (shared_end = shared + shared_n; shared < shared_end; shared++) {\n+\t\tuint32_t act_idx = (uint32_t)(uintptr_t)shared->action;\n+\t\tuint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;\n+\t\tuint32_t idx = act_idx &\n+\t\t\t\t   ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);\n+\t\tswitch (type) {\n+\t\tcase MLX5_SHARED_ACTION_TYPE_RSS:\n+\t\t\tshared_rss = mlx5_ipool_get\n+\t\t\t\t(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t\t\t\t\t\t\t\t   idx);\n+\t\t\t__atomic_add_fetch(&shared_rss->refcnt, 1,\n \t\t\t\t\t   __ATOMIC_RELAXED);\n-\t\t\treturn &shared_action->rss;\n+\t\t\treturn idx;\n \t\tdefault:\n \t\t\tbreak;\n \t\t}\n \t}\n-\treturn NULL;\n-}\n-\n-struct rte_flow_shared_action *\n-mlx5_flow_get_shared_rss(struct rte_flow *flow)\n-{\n-\tif (flow->shared_rss)\n-\t\treturn container_of(flow->shared_rss,\n-\t\t\t\t    struct rte_flow_shared_action, rss);\n-\telse\n-\t\treturn NULL;\n+\treturn 0;\n }\n \n static unsigned int\n@@ -5538,7 +5547,7 @@ struct tunnel_default_miss_ctx {\n \n \tMLX5_ASSERT(wks);\n \trss_desc = &wks->rss_desc[fidx];\n-\tret = flow_shared_actions_translate(original_actions,\n+\tret = flow_shared_actions_translate(dev, original_actions,\n \t\t\t\t\t    shared_actions,\n \t\t\t\t\t    &shared_actions_n,\n \t\t\t\t\t    &translated_actions, error);\n@@ -5599,7 +5608,7 @@ struct tunnel_default_miss_ctx {\n \t\tbuf->entries = 1;\n \t\tbuf->entry[0].pattern = (void *)(uintptr_t)items;\n \t}\n-\tflow->shared_rss = flow_get_shared_rss_action(shared_actions,\n+\tflow->shared_rss = flow_get_shared_rss_action(dev, shared_actions,\n \t\t\t\t\t\t      shared_actions_n);\n \t/*\n \t * Record the start index when there is a nested call. All sub-flows\n@@ -5787,7 +5796,7 @@ struct rte_flow *\n \tint shared_actions_n = MLX5_MAX_SHARED_ACTIONS;\n \tconst struct rte_flow_action *actions;\n \tstruct rte_flow_action *translated_actions = NULL;\n-\tint ret = flow_shared_actions_translate(original_actions,\n+\tint ret = flow_shared_actions_translate(dev, original_actions,\n \t\t\t\t\t\tshared_actions,\n \t\t\t\t\t\t&shared_actions_n,\n \t\t\t\t\t\t&translated_actions, error);\n@@ -7856,25 +7865,11 @@ struct mlx5_meter_domains_infos *\n \t\t\tflow_get_drv_ops(flow_get_drv_type(dev, &attr));\n \tint ret;\n \n-\tswitch (shared_action->type) {\n-\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n-\t\tif (action->type != RTE_FLOW_ACTION_TYPE_RSS) {\n-\t\t\treturn rte_flow_error_set(error, EINVAL,\n-\t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n-\t\t\t\t\t\t  NULL,\n-\t\t\t\t\t\t  \"update action type invalid\");\n-\t\t}\n-\t\tret = flow_drv_action_validate(dev, NULL, action, fops, error);\n-\t\tif (ret)\n-\t\t\treturn ret;\n-\t\treturn flow_drv_action_update(dev, shared_action, action->conf,\n-\t\t\t\t\t      fops, error);\n-\tdefault:\n-\t\treturn rte_flow_error_set(error, ENOTSUP,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n-\t\t\t\t\t  NULL,\n-\t\t\t\t\t  \"action type not supported\");\n-\t}\n+\tret = flow_drv_action_validate(dev, NULL, action, fops, error);\n+\tif (ret)\n+\t\treturn ret;\n+\treturn flow_drv_action_update(dev, shared_action, action->conf, fops,\n+\t\t\t\t      error);\n }\n \n /**\n@@ -7906,17 +7901,10 @@ struct mlx5_meter_domains_infos *\n \t\t\t struct rte_flow_error *error)\n {\n \t(void)dev;\n-\tswitch (action->type) {\n-\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n-\t\t__atomic_load(&action->refcnt, (uint32_t *)data,\n-\t\t\t      __ATOMIC_RELAXED);\n-\t\treturn 0;\n-\tdefault:\n-\t\treturn rte_flow_error_set(error, ENOTSUP,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n-\t\t\t\t\t  NULL,\n-\t\t\t\t\t  \"action type not supported\");\n-\t}\n+\t(void)action;\n+\t(void)data;\n+\treturn rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t  NULL, \"action type query not supported\");\n }\n \n /**\n@@ -7933,12 +7921,14 @@ struct mlx5_meter_domains_infos *\n {\n \tstruct rte_flow_error error;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct rte_flow_shared_action *action;\n+\tstruct mlx5_shared_action_rss *action;\n \tint ret = 0;\n+\tuint32_t idx;\n \n-\twhile (!LIST_EMPTY(&priv->shared_actions)) {\n-\t\taction = LIST_FIRST(&priv->shared_actions);\n-\t\tret = mlx5_shared_action_destroy(dev, action, &error);\n+\tILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t      priv->rss_shared_actions, idx, action, next) {\n+\t\tret |= mlx5_shared_action_destroy(dev,\n+\t\t       (struct rte_flow_shared_action *)(uintptr_t)idx, &error);\n \t}\n \treturn ret;\n }\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 1b4a9d1..742971c 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -35,10 +35,15 @@ enum mlx5_rte_flow_action_type {\n \tMLX5_RTE_FLOW_ACTION_TYPE_MARK,\n \tMLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG,\n \tMLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS,\n-\tMLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS,\n \tMLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET,\n };\n \n+#define MLX5_SHARED_ACTION_TYPE_OFFSET 30\n+\n+enum {\n+\tMLX5_SHARED_ACTION_TYPE_RSS,\n+};\n+\n /* Matches on selected register. */\n struct mlx5_rte_flow_item_tag {\n \tenum modify_reg id;\n@@ -1024,7 +1029,7 @@ struct tunnel_tbl_entry {\n /* Flow structure. */\n struct rte_flow {\n \tILIST_ENTRY(uint32_t)next; /**< Index to the next flow structure. */\n-\tstruct mlx5_shared_action_rss *shared_rss; /** < Shred RSS action. */\n+\tuint32_t shared_rss; /** < Shared RSS action ID. */\n \tuint32_t dev_handles;\n \t/**< Device flow handles that are part of the flow. */\n \tuint32_t drv_type:2; /**< Driver type. */\n@@ -1069,10 +1074,10 @@ struct rte_flow {\n \tMLX5_RSS_HASH_NONE,\n };\n \n-#define MLX5_RSS_HASH_FIELDS_LEN RTE_DIM(mlx5_rss_hash_fields)\n-\n /* Shared RSS action structure */\n struct mlx5_shared_action_rss {\n+\tILIST_ENTRY(uint32_t)next; /**< Index to the next RSS structure. */\n+\tuint32_t refcnt; /**< Atomically accessed refcnt. */\n \tstruct rte_flow_action_rss origin; /**< Original rte RSS action. */\n \tuint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */\n \tuint16_t *queue; /**< Queue indices to use. */\n@@ -1083,15 +1088,7 @@ struct mlx5_shared_action_rss {\n };\n \n struct rte_flow_shared_action {\n-\tLIST_ENTRY(rte_flow_shared_action) next;\n-\t\t/**< Pointer to the next element. */\n-\tuint32_t refcnt; /**< Atomically accessed refcnt. */\n-\tuint64_t type;\n-\t\t/**< Shared action type (see MLX5_FLOW_ACTION_SHARED_*). */\n-\tunion {\n-\t\tstruct mlx5_shared_action_rss rss;\n-\t\t\t/**< Shared RSS action. */\n-\t};\n+\tuint32_t id;\n };\n \n /* Thread specific flow workspace intermediate data. */\n@@ -1391,7 +1388,6 @@ int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev,\n int mlx5_flow_meter_flush(struct rte_eth_dev *dev,\n \t\t\t  struct rte_mtr_error *error);\n int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev);\n-struct rte_flow_shared_action *mlx5_flow_get_shared_rss(struct rte_flow *flow);\n int mlx5_shared_action_flush(struct rte_eth_dev *dev);\n void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id);\n int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh);\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex dcc397d..05f5871 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -10509,8 +10509,10 @@ struct mlx5_cache_entry *\n  * Look up for hash RX queue by hash fields (see enum ibv_rx_hash_fields)\n  * and tunnel.\n  *\n- * @param[in] action\n- *   Shred RSS action holding hash RX queue objects.\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n+ * @param[in] idx\n+ *   Shared RSS action ID holding hash RX queue objects.\n  * @param[in] hash_fields\n  *   Defines combination of packet fields to participate in RX hash.\n  * @param[in] tunnel\n@@ -10520,11 +10522,15 @@ struct mlx5_cache_entry *\n  *   Valid hash RX queue index, otherwise 0.\n  */\n static uint32_t\n-__flow_dv_action_rss_hrxq_lookup(const struct mlx5_shared_action_rss *action,\n+__flow_dv_action_rss_hrxq_lookup(struct rte_eth_dev *dev, uint32_t idx,\n \t\t\t\t const uint64_t hash_fields,\n \t\t\t\t const int tunnel)\n {\n-\tconst uint32_t *hrxqs = tunnel ? action->hrxq : action->hrxq_tunnel;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_shared_action_rss *shared_rss =\n+\t    mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx);\n+\tconst uint32_t *hrxqs = tunnel ? shared_rss->hrxq :\n+\t\t\t\t\t\t\tshared_rss->hrxq_tunnel;\n \n \tswitch (hash_fields & ~IBV_RX_HASH_INNER) {\n \tcase MLX5_RSS_HASH_IPV4:\n@@ -10551,6 +10557,8 @@ struct mlx5_cache_entry *\n  * If shared action configured for *flow* suitable hash RX queue will be\n  * retrieved from attached shared action.\n  *\n+ * @param[in] dev\n+ *   Pointer to the Ethernet device structure.\n  * @param[in] flow\n  *   Shred RSS action holding hash RX queue objects.\n  * @param[in] dev_flow\n@@ -10572,7 +10580,7 @@ struct mlx5_cache_entry *\n \n \tif (flow->shared_rss) {\n \t\thrxq_idx = __flow_dv_action_rss_hrxq_lookup\n-\t\t\t\t(flow->shared_rss, dev_flow->hash_fields,\n+\t\t\t\t(dev, flow->shared_rss, dev_flow->hash_fields,\n \t\t\t\t !!(dev_flow->handle->layers &\n \t\t\t\t    MLX5_FLOW_LAYER_TUNNEL));\n \t\tif (hrxq_idx) {\n@@ -11101,16 +11109,19 @@ struct mlx5_cache_entry *\n static void\n flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n-\tstruct rte_flow_shared_action *shared;\n \tstruct mlx5_flow_handle *dev_handle;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \n \tif (!flow)\n \t\treturn;\n \tflow_dv_remove(dev, flow);\n-\tshared = mlx5_flow_get_shared_rss(flow);\n-\tif (shared)\n-\t\t__atomic_sub_fetch(&shared->refcnt, 1, __ATOMIC_RELAXED);\n+\tif (flow->shared_rss) {\n+\t\tstruct mlx5_shared_action_rss *shared_rss = mlx5_ipool_get\n+\t\t\t\t(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t\t\t\t\t\t      flow->shared_rss);\n+\n+\t\t__atomic_sub_fetch(&shared_rss->refcnt, 1, __ATOMIC_RELAXED);\n+\t}\n \tif (flow->counter) {\n \t\tflow_dv_counter_free(dev, flow->counter);\n \t\tflow->counter = 0;\n@@ -11281,56 +11292,69 @@ struct mlx5_cache_entry *\n  *   error only.\n  *\n  * @return\n- *   A valid shared action handle in case of success, NULL otherwise and\n+ *   A valid shared action ID in case of success, 0 otherwise and\n  *   rte_errno is set.\n  */\n-static struct rte_flow_shared_action *\n+static uint32_t\n __flow_dv_action_rss_create(struct rte_eth_dev *dev,\n \t\t\t    const struct rte_flow_shared_action_conf *conf,\n \t\t\t    const struct rte_flow_action_rss *rss,\n \t\t\t    struct rte_flow_error *error)\n {\n-\tstruct rte_flow_shared_action *shared_action = NULL;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_shared_action_rss *shared_action = NULL;\n \tvoid *queue = NULL;\n-\tstruct mlx5_shared_action_rss *shared_rss;\n \tstruct rte_flow_action_rss *origin;\n \tconst uint8_t *rss_key;\n \tuint32_t queue_size = rss->queue_num * sizeof(uint16_t);\n+\tuint32_t idx;\n \n \tRTE_SET_USED(conf);\n \tqueue = mlx5_malloc(0, RTE_ALIGN_CEIL(queue_size, sizeof(void *)),\n \t\t\t    0, SOCKET_ID_ANY);\n-\tshared_action = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*shared_action), 0,\n-\t\t\t\t    SOCKET_ID_ANY);\n+\tshared_action = mlx5_ipool_zmalloc\n+\t\t\t (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], &idx);\n \tif (!shared_action || !queue) {\n \t\trte_flow_error_set(error, ENOMEM,\n \t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t   \"cannot allocate resource memory\");\n \t\tgoto error_rss_init;\n \t}\n-\tshared_rss = &shared_action->rss;\n-\tshared_rss->queue = queue;\n-\torigin = &shared_rss->origin;\n+\tif (idx > (1u << MLX5_SHARED_ACTION_TYPE_OFFSET)) {\n+\t\trte_flow_error_set(error, E2BIG,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t   \"rss action number out of range\");\n+\t\tgoto error_rss_init;\n+\t}\n+\tshared_action->queue = queue;\n+\torigin = &shared_action->origin;\n \torigin->func = rss->func;\n \torigin->level = rss->level;\n \t/* RSS type 0 indicates default RSS type (ETH_RSS_IP). */\n \torigin->types = !rss->types ? ETH_RSS_IP : rss->types;\n \t/* NULL RSS key indicates default RSS key. */\n \trss_key = !rss->key ? rss_hash_default_key : rss->key;\n-\tmemcpy(shared_rss->key, rss_key, MLX5_RSS_HASH_KEY_LEN);\n-\torigin->key = &shared_rss->key[0];\n+\tmemcpy(shared_action->key, rss_key, MLX5_RSS_HASH_KEY_LEN);\n+\torigin->key = &shared_action->key[0];\n \torigin->key_len = MLX5_RSS_HASH_KEY_LEN;\n-\tmemcpy(shared_rss->queue, rss->queue, queue_size);\n-\torigin->queue = shared_rss->queue;\n+\tmemcpy(shared_action->queue, rss->queue, queue_size);\n+\torigin->queue = shared_action->queue;\n \torigin->queue_num = rss->queue_num;\n-\tif (__flow_dv_action_rss_setup(dev, shared_rss, error))\n+\tif (__flow_dv_action_rss_setup(dev, shared_action, error))\n \t\tgoto error_rss_init;\n-\tshared_action->type = MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS;\n-\treturn shared_action;\n+\t__atomic_add_fetch(&shared_action->refcnt, 2, __ATOMIC_RELAXED);\n+\trte_spinlock_lock(&priv->shared_act_sl);\n+\tILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t     &priv->rss_shared_actions, idx, shared_action, next);\n+\trte_spinlock_unlock(&priv->shared_act_sl);\n+\treturn idx;\n error_rss_init:\n-\tmlx5_free(shared_action);\n-\tmlx5_free(queue);\n-\treturn NULL;\n+\tif (shared_action)\n+\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t\t\tidx);\n+\tif (queue)\n+\t\tmlx5_free(queue);\n+\treturn 0;\n }\n \n /**\n@@ -11339,8 +11363,8 @@ struct mlx5_cache_entry *\n  *\n  * @param[in] dev\n  *   Pointer to the Ethernet device structure.\n- * @param[in] shared_rss\n- *   The shared RSS action object to be removed.\n+ * @param[in] idx\n+ *   The shared RSS action object ID to be removed.\n  * @param[out] error\n  *   Perform verbose error reporting if not NULL. Initialized in case of\n  *   error only.\n@@ -11349,31 +11373,39 @@ struct mlx5_cache_entry *\n  *   0 on success, otherwise negative errno value.\n  */\n static int\n-__flow_dv_action_rss_release(struct rte_eth_dev *dev,\n-\t\t\t struct mlx5_shared_action_rss *shared_rss,\n-\t\t\t struct rte_flow_error *error)\n+__flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,\n+\t\t\t     struct rte_flow_error *error)\n {\n-\tstruct rte_flow_shared_action *shared_action = NULL;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_shared_action_rss *shared_rss =\n+\t    mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx);\n \tuint32_t old_refcnt = 1;\n-\tint remaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss);\n+\tint remaining;\n \n-\tif (remaining) {\n+\tif (!shared_rss)\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t  \"invalid shared action\");\n+\tremaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss);\n+\tif (remaining)\n \t\treturn rte_flow_error_set(error, ETOOMANYREFS,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"shared rss hrxq has references\");\n-\t}\n-\tshared_action = container_of(shared_rss,\n-\t\t\t\t     struct rte_flow_shared_action, rss);\n-\tif (!__atomic_compare_exchange_n(&shared_action->refcnt, &old_refcnt,\n-\t\t\t\t\t 0, 0,\n-\t\t\t\t\t __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {\n+\tif (!__atomic_compare_exchange_n(&shared_rss->refcnt, &old_refcnt,\n+\t\t\t\t\t 0, 0, __ATOMIC_ACQUIRE,\n+\t\t\t\t\t __ATOMIC_RELAXED))\n \t\treturn rte_flow_error_set(error, ETOOMANYREFS,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"shared rss has references\");\n-\t}\n \trte_free(shared_rss->queue);\n+\trte_spinlock_lock(&priv->shared_act_sl);\n+\tILIST_REMOVE(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t     &priv->rss_shared_actions, idx, shared_rss, next);\n+\trte_spinlock_unlock(&priv->shared_act_sl);\n+\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS],\n+\t\t\tidx);\n \treturn 0;\n }\n \n@@ -11400,30 +11432,23 @@ struct mlx5_cache_entry *\n flow_dv_action_create(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\t      struct rte_flow_error *err)\n {\n-\tstruct rte_flow_shared_action *shared_action = NULL;\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t idx = 0;\n+\tuint32_t ret = 0;\n \n \tswitch (action->type) {\n \tcase RTE_FLOW_ACTION_TYPE_RSS:\n-\t\tshared_action = __flow_dv_action_rss_create(dev, conf,\n-\t\t\t\t\t\t\t    action->conf,\n-\t\t\t\t\t\t\t    error);\n+\t\tret = __flow_dv_action_rss_create(dev, conf, action->conf, err);\n+\t\tidx = (MLX5_SHARED_ACTION_TYPE_RSS <<\n+\t\t       MLX5_SHARED_ACTION_TYPE_OFFSET) | ret;\n \t\tbreak;\n \tdefault:\n-\t\trte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\trte_flow_error_set(err, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t   NULL, \"action type not supported\");\n \t\tbreak;\n \t}\n-\tif (shared_action) {\n-\t\t__atomic_add_fetch(&shared_action->refcnt, 1,\n-\t\t\t\t   __ATOMIC_RELAXED);\n-\t\trte_spinlock_lock(&priv->shared_act_sl);\n-\t\tLIST_INSERT_HEAD(&priv->shared_actions, shared_action, next);\n-\t\trte_spinlock_unlock(&priv->shared_act_sl);\n-\t}\n-\treturn shared_action;\n+\treturn ret ? (struct rte_flow_shared_action *)(uintptr_t)idx : NULL;\n }\n \n /**\n@@ -11448,12 +11473,14 @@ struct mlx5_cache_entry *\n \t\t       struct rte_flow_shared_action *action,\n \t\t       struct rte_flow_error *error)\n {\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t act_idx = (uint32_t)(uintptr_t)action;\n+\tuint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;\n+\tuint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);\n \tint ret;\n \n-\tswitch (action->type) {\n-\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n-\t\tret = __flow_dv_action_rss_release(dev, &action->rss, error);\n+\tswitch (type) {\n+\tcase MLX5_SHARED_ACTION_TYPE_RSS:\n+\t\tret = __flow_dv_action_rss_release(dev, idx, error);\n \t\tbreak;\n \tdefault:\n \t\treturn rte_flow_error_set(error, ENOTSUP,\n@@ -11463,10 +11490,6 @@ struct mlx5_cache_entry *\n \t}\n \tif (ret)\n \t\treturn ret;\n-\trte_spinlock_lock(&priv->shared_act_sl);\n-\tLIST_REMOVE(action, next);\n-\trte_spinlock_unlock(&priv->shared_act_sl);\n-\trte_free(action);\n \treturn 0;\n }\n \n@@ -11475,8 +11498,8 @@ struct mlx5_cache_entry *\n  *\n  * @param[in] dev\n  *   Pointer to the Ethernet device structure.\n- * @param[in] shared_rss\n- *   The shared RSS action object to be updated.\n+ * @param[in] idx\n+ *   The shared RSS action object ID to be updated.\n  * @param[in] action_conf\n  *   RSS action specification used to modify *shared_rss*.\n  * @param[out] error\n@@ -11488,11 +11511,13 @@ struct mlx5_cache_entry *\n  * @note: currently only support update of RSS queues.\n  */\n static int\n-__flow_dv_action_rss_update(struct rte_eth_dev *dev,\n-\t\t\t    struct mlx5_shared_action_rss *shared_rss,\n+__flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t idx,\n \t\t\t    const struct rte_flow_action_rss *action_conf,\n \t\t\t    struct rte_flow_error *error)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_shared_action_rss *shared_rss =\n+\t    mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx);\n \tsize_t i;\n \tint ret;\n \tvoid *queue = NULL;\n@@ -11500,6 +11525,10 @@ struct mlx5_cache_entry *\n \tuint32_t rss_key_len;\n \tuint32_t queue_size = action_conf->queue_num * sizeof(uint16_t);\n \n+\tif (!shared_rss)\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t  \"invalid shared action to update\");\n \tqueue = mlx5_malloc(MLX5_MEM_ZERO,\n \t\t\t    RTE_ALIGN_CEIL(queue_size, sizeof(void *)),\n \t\t\t    0, SOCKET_ID_ANY);\n@@ -11522,7 +11551,7 @@ struct mlx5_cache_entry *\n \n \t\tfor (tunnel = 0; tunnel < 2; tunnel++) {\n \t\t\thrxq_idx = __flow_dv_action_rss_hrxq_lookup\n-\t\t\t\t\t(shared_rss, hash_fields, tunnel);\n+\t\t\t\t\t(dev, idx, hash_fields, tunnel);\n \t\t\tMLX5_ASSERT(hrxq_idx);\n \t\t\tret = mlx5_hrxq_modify\n \t\t\t\t(dev, hrxq_idx,\n@@ -11569,14 +11598,17 @@ struct mlx5_cache_entry *\n flow_dv_action_update(struct rte_eth_dev *dev,\n \t\t\tstruct rte_flow_shared_action *action,\n \t\t\tconst void *action_conf,\n-\t\t\tstruct rte_flow_error *error)\n+\t\t\tstruct rte_flow_error *err)\n {\n-\tswitch (action->type) {\n-\tcase MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS:\n-\t\treturn __flow_dv_action_rss_update(dev, &action->rss,\n-\t\t\t\t\t\t   action_conf, error);\n+\tuint32_t act_idx = (uint32_t)(uintptr_t)action;\n+\tuint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET;\n+\tuint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1);\n+\n+\tswitch (type) {\n+\tcase MLX5_SHARED_ACTION_TYPE_RSS:\n+\t\treturn __flow_dv_action_rss_update(dev, idx, action_conf, err);\n \tdefault:\n-\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\treturn rte_flow_error_set(err, ENOTSUP,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n \t\t\t\t\t  NULL,\n \t\t\t\t\t  \"action type not supported\");\n",
    "prefixes": [
        "7/8"
    ]
}