From: Matan Azrad Date: Sun, 1 Nov 2020 17:57:50 +0000 (+0000) Subject: net/mlx5: optimize shared RSS action memory X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=4a42ac1f1ccda89450c0bbb8ee5816246033b785;p=dpdk.git net/mlx5: optimize shared RSS action memory The RSS shared action was saved in flow memory by a pointer. It means that every flow memory includes 8B only for optional shared RSS case. Move the RSS objects to be used by indexed pool which reduces the flow handle memory to 4B. So, now, the shared action handler is also just a 4B index. Signed-off-by: Matan Azrad Acked-by: Dekel Peled --- diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 4ea905336f..9e51916a90 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -336,6 +336,18 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = { .need_lock = 1, .type = "mlx5_flow_tnl_tbl_ipool", }, + { + .size = sizeof(struct mlx5_shared_action_rss), + .trunk_size = 64, + .grow_trunk = 3, + .grow_shift = 2, + .need_lock = 1, + .release_mem_en = 1, + .malloc = mlx5_malloc, + .free = mlx5_free, + .type = "mlx5_shared_action_rss", + }, + }; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index ba5a90edec..547733f471 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -53,6 +53,7 @@ enum mlx5_ipool_index { MLX5_IPOOL_RSS_EXPANTION_FLOW_ID, /* Pool for Queue/RSS flow ID. */ MLX5_IPOOL_TUNNEL_ID, /* Pool for flow tunnel ID. */ MLX5_IPOOL_TNL_TBL_ID, /* Pool for tunnel table ID. */ + MLX5_IPOOL_RSS_SHARED_ACTIONS, /* Pool for RSS shared actions. */ MLX5_IPOOL_MAX, }; @@ -921,6 +922,8 @@ struct mlx5_obj_ops { void (*txq_obj_release)(struct mlx5_txq_obj *txq_obj); }; +#define MLX5_RSS_HASH_FIELDS_LEN RTE_DIM(mlx5_rss_hash_fields) + struct mlx5_priv { struct rte_eth_dev_data *dev_data; /* Pointer to device data. */ struct mlx5_dev_ctx_shared *sh; /* Shared device context. */ @@ -997,8 +1000,7 @@ struct mlx5_priv { struct mlx5_mp_id mp_id; /* ID of a multi-process process */ LIST_HEAD(fdir, mlx5_fdir_flow) fdir_flows; /* fdir flows. */ rte_spinlock_t shared_act_sl; /* Shared actions spinlock. */ - LIST_HEAD(shared_action, rte_flow_shared_action) shared_actions; - /* shared actions */ + uint32_t rss_shared_actions; /* RSS shared actions. */ }; #define PORT_ID(priv) ((priv)->dev_data->port_id) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index d01a4ce590..b08ee30f17 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -3280,6 +3280,8 @@ struct mlx5_translated_shared_action { * action handling should be preformed on *shared* actions list returned * from this call. * + * @param[in] dev + * Pointer to Ethernet device. * @param[in] actions * List of actions to translate. * @param[out] shared @@ -3297,12 +3299,14 @@ struct mlx5_translated_shared_action { * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_shared_actions_translate(const struct rte_flow_action actions[], - struct mlx5_translated_shared_action *shared, - int *shared_n, - struct rte_flow_action **translated_actions, - struct rte_flow_error *error) +flow_shared_actions_translate(struct rte_eth_dev *dev, + const struct rte_flow_action actions[], + struct mlx5_translated_shared_action *shared, + int *shared_n, + struct rte_flow_action **translated_actions, + struct rte_flow_error *error) { + struct mlx5_priv *priv = dev->data->dev_private; struct rte_flow_action *translated = NULL; size_t actions_size; int n; @@ -3334,15 +3338,20 @@ flow_shared_actions_translate(const struct rte_flow_action actions[], } memcpy(translated, actions, actions_size); for (shared_end = shared + copied_n; shared < shared_end; shared++) { - const struct rte_flow_shared_action *shared_action; - - shared_action = shared->action; - switch (shared_action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: + struct mlx5_shared_action_rss *shared_rss; + uint32_t act_idx = (uint32_t)(uintptr_t)shared->action; + uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET; + uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) + - 1); + + switch (type) { + case MLX5_SHARED_ACTION_TYPE_RSS: + shared_rss = mlx5_ipool_get + (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx); translated[shared->index].type = RTE_FLOW_ACTION_TYPE_RSS; translated[shared->index].conf = - &shared_action->rss.origin; + &shared_rss->origin; break; default: mlx5_free(translated); @@ -3358,44 +3367,44 @@ flow_shared_actions_translate(const struct rte_flow_action actions[], /** * Get Shared RSS action from the action list. * + * @param[in] dev + * Pointer to Ethernet device. * @param[in] shared * Pointer to the list of actions. * @param[in] shared_n * Actions list length. * * @return - * Pointer to the MLX5 RSS action if exists, otherwise return NULL. + * The MLX5 RSS action ID if exists, otherwise return 0. */ -static struct mlx5_shared_action_rss * -flow_get_shared_rss_action(struct mlx5_translated_shared_action *shared, +static uint32_t +flow_get_shared_rss_action(struct rte_eth_dev *dev, + struct mlx5_translated_shared_action *shared, int shared_n) { struct mlx5_translated_shared_action *shared_end; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_shared_action_rss *shared_rss; - for (shared_end = shared + shared_n; shared < shared_end; shared++) { - struct rte_flow_shared_action *shared_action; - shared_action = shared->action; - switch (shared_action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: - __atomic_add_fetch(&shared_action->refcnt, 1, + for (shared_end = shared + shared_n; shared < shared_end; shared++) { + uint32_t act_idx = (uint32_t)(uintptr_t)shared->action; + uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET; + uint32_t idx = act_idx & + ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1); + switch (type) { + case MLX5_SHARED_ACTION_TYPE_RSS: + shared_rss = mlx5_ipool_get + (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + idx); + __atomic_add_fetch(&shared_rss->refcnt, 1, __ATOMIC_RELAXED); - return &shared_action->rss; + return idx; default: break; } } - return NULL; -} - -struct rte_flow_shared_action * -mlx5_flow_get_shared_rss(struct rte_flow *flow) -{ - if (flow->shared_rss) - return container_of(flow->shared_rss, - struct rte_flow_shared_action, rss); - else - return NULL; + return 0; } static unsigned int @@ -5512,7 +5521,7 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list, MLX5_ASSERT(wks); rss_desc = &wks->rss_desc[fidx]; - ret = flow_shared_actions_translate(original_actions, + ret = flow_shared_actions_translate(dev, original_actions, shared_actions, &shared_actions_n, &translated_actions, error); @@ -5573,7 +5582,7 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list, buf->entries = 1; buf->entry[0].pattern = (void *)(uintptr_t)items; } - flow->shared_rss = flow_get_shared_rss_action(shared_actions, + flow->shared_rss = flow_get_shared_rss_action(dev, shared_actions, shared_actions_n); /* * Record the start index when there is a nested call. All sub-flows @@ -5761,7 +5770,7 @@ mlx5_flow_validate(struct rte_eth_dev *dev, int shared_actions_n = MLX5_MAX_SHARED_ACTIONS; const struct rte_flow_action *actions; struct rte_flow_action *translated_actions = NULL; - int ret = flow_shared_actions_translate(original_actions, + int ret = flow_shared_actions_translate(dev, original_actions, shared_actions, &shared_actions_n, &translated_actions, error); @@ -7331,25 +7340,11 @@ mlx5_shared_action_update(struct rte_eth_dev *dev, flow_get_drv_ops(flow_get_drv_type(dev, &attr)); int ret; - switch (shared_action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: - if (action->type != RTE_FLOW_ACTION_TYPE_RSS) { - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, - "update action type invalid"); - } - ret = flow_drv_action_validate(dev, NULL, action, fops, error); - if (ret) - return ret; - return flow_drv_action_update(dev, shared_action, action->conf, - fops, error); - default: - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, - "action type not supported"); - } + ret = flow_drv_action_validate(dev, NULL, action, fops, error); + if (ret) + return ret; + return flow_drv_action_update(dev, shared_action, action->conf, fops, + error); } /** @@ -7381,17 +7376,10 @@ mlx5_shared_action_query(struct rte_eth_dev *dev, struct rte_flow_error *error) { (void)dev; - switch (action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: - __atomic_load(&action->refcnt, (uint32_t *)data, - __ATOMIC_RELAXED); - return 0; - default: - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, - "action type not supported"); - } + (void)action; + (void)data; + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "action type query not supported"); } /** @@ -7408,12 +7396,14 @@ mlx5_shared_action_flush(struct rte_eth_dev *dev) { struct rte_flow_error error; struct mlx5_priv *priv = dev->data->dev_private; - struct rte_flow_shared_action *action; + struct mlx5_shared_action_rss *action; int ret = 0; + uint32_t idx; - while (!LIST_EMPTY(&priv->shared_actions)) { - action = LIST_FIRST(&priv->shared_actions); - ret = mlx5_shared_action_destroy(dev, action, &error); + ILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + priv->rss_shared_actions, idx, action, next) { + ret |= mlx5_shared_action_destroy(dev, + (struct rte_flow_shared_action *)(uintptr_t)idx, &error); } return ret; } diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index e50f1c9ba6..b77df50cab 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -35,10 +35,15 @@ enum mlx5_rte_flow_action_type { MLX5_RTE_FLOW_ACTION_TYPE_MARK, MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS, - MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS, MLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET, }; +#define MLX5_SHARED_ACTION_TYPE_OFFSET 30 + +enum { + MLX5_SHARED_ACTION_TYPE_RSS, +}; + /* Matches on selected register. */ struct mlx5_rte_flow_item_tag { enum modify_reg id; @@ -1017,7 +1022,7 @@ flow_items_to_tunnel(const struct rte_flow_item items[]) /* Flow structure. */ struct rte_flow { ILIST_ENTRY(uint32_t)next; /**< Index to the next flow structure. */ - struct mlx5_shared_action_rss *shared_rss; /** < Shred RSS action. */ + uint32_t shared_rss; /** < Shared RSS action ID. */ uint32_t dev_handles; /**< Device flow handles that are part of the flow. */ uint32_t drv_type:2; /**< Driver type. */ @@ -1061,10 +1066,10 @@ static const uint64_t mlx5_rss_hash_fields[] = { MLX5_RSS_HASH_NONE, }; -#define MLX5_RSS_HASH_FIELDS_LEN RTE_DIM(mlx5_rss_hash_fields) - /* Shared RSS action structure */ struct mlx5_shared_action_rss { + ILIST_ENTRY(uint32_t)next; /**< Index to the next RSS structure. */ + uint32_t refcnt; /**< Atomically accessed refcnt. */ struct rte_flow_action_rss origin; /**< Original rte RSS action. */ uint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */ uint16_t *queue; /**< Queue indices to use. */ @@ -1075,15 +1080,7 @@ struct mlx5_shared_action_rss { }; struct rte_flow_shared_action { - LIST_ENTRY(rte_flow_shared_action) next; - /**< Pointer to the next element. */ - uint32_t refcnt; /**< Atomically accessed refcnt. */ - uint64_t type; - /**< Shared action type (see MLX5_FLOW_ACTION_SHARED_*). */ - union { - struct mlx5_shared_action_rss rss; - /**< Shared RSS action. */ - }; + uint32_t id; }; /* Thread specific flow workspace intermediate data. */ @@ -1383,7 +1380,6 @@ int mlx5_flow_destroy_policer_rules(struct rte_eth_dev *dev, int mlx5_flow_meter_flush(struct rte_eth_dev *dev, struct rte_mtr_error *error); int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev); -struct rte_flow_shared_action *mlx5_flow_get_shared_rss(struct rte_flow *flow); int mlx5_shared_action_flush(struct rte_eth_dev *dev); void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id); int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh); diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index bc21389273..be93ba97bc 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -10507,8 +10507,10 @@ __flow_dv_action_rss_hrxq_set(struct mlx5_shared_action_rss *action, * Look up for hash RX queue by hash fields (see enum ibv_rx_hash_fields) * and tunnel. * - * @param[in] action - * Shred RSS action holding hash RX queue objects. + * @param[in] dev + * Pointer to the Ethernet device structure. + * @param[in] idx + * Shared RSS action ID holding hash RX queue objects. * @param[in] hash_fields * Defines combination of packet fields to participate in RX hash. * @param[in] tunnel @@ -10518,11 +10520,15 @@ __flow_dv_action_rss_hrxq_set(struct mlx5_shared_action_rss *action, * Valid hash RX queue index, otherwise 0. */ static uint32_t -__flow_dv_action_rss_hrxq_lookup(const struct mlx5_shared_action_rss *action, +__flow_dv_action_rss_hrxq_lookup(struct rte_eth_dev *dev, uint32_t idx, const uint64_t hash_fields, const int tunnel) { - const uint32_t *hrxqs = tunnel ? action->hrxq : action->hrxq_tunnel; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_shared_action_rss *shared_rss = + mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx); + const uint32_t *hrxqs = tunnel ? shared_rss->hrxq : + shared_rss->hrxq_tunnel; switch (hash_fields & ~IBV_RX_HASH_INNER) { case MLX5_RSS_HASH_IPV4: @@ -10549,6 +10555,8 @@ __flow_dv_action_rss_hrxq_lookup(const struct mlx5_shared_action_rss *action, * If shared action configured for *flow* suitable hash RX queue will be * retrieved from attached shared action. * + * @param[in] dev + * Pointer to the Ethernet device structure. * @param[in] flow * Shred RSS action holding hash RX queue objects. * @param[in] dev_flow @@ -10570,7 +10578,7 @@ __flow_dv_rss_get_hrxq(struct rte_eth_dev *dev, struct rte_flow *flow, if (flow->shared_rss) { hrxq_idx = __flow_dv_action_rss_hrxq_lookup - (flow->shared_rss, dev_flow->hash_fields, + (dev, flow->shared_rss, dev_flow->hash_fields, !!(dev_flow->handle->layers & MLX5_FLOW_LAYER_TUNNEL)); if (hrxq_idx) { @@ -11099,16 +11107,19 @@ flow_dv_remove(struct rte_eth_dev *dev, struct rte_flow *flow) static void flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) { - struct rte_flow_shared_action *shared; struct mlx5_flow_handle *dev_handle; struct mlx5_priv *priv = dev->data->dev_private; if (!flow) return; flow_dv_remove(dev, flow); - shared = mlx5_flow_get_shared_rss(flow); - if (shared) - __atomic_sub_fetch(&shared->refcnt, 1, __ATOMIC_RELAXED); + if (flow->shared_rss) { + struct mlx5_shared_action_rss *shared_rss = mlx5_ipool_get + (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + flow->shared_rss); + + __atomic_sub_fetch(&shared_rss->refcnt, 1, __ATOMIC_RELAXED); + } if (flow->counter) { flow_dv_counter_free(dev, flow->counter); flow->counter = 0; @@ -11279,56 +11290,69 @@ error_hrxq_new: * error only. * * @return - * A valid shared action handle in case of success, NULL otherwise and + * A valid shared action ID in case of success, 0 otherwise and * rte_errno is set. */ -static struct rte_flow_shared_action * +static uint32_t __flow_dv_action_rss_create(struct rte_eth_dev *dev, const struct rte_flow_shared_action_conf *conf, const struct rte_flow_action_rss *rss, struct rte_flow_error *error) { - struct rte_flow_shared_action *shared_action = NULL; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_shared_action_rss *shared_action = NULL; void *queue = NULL; - struct mlx5_shared_action_rss *shared_rss; struct rte_flow_action_rss *origin; const uint8_t *rss_key; uint32_t queue_size = rss->queue_num * sizeof(uint16_t); + uint32_t idx; RTE_SET_USED(conf); queue = mlx5_malloc(0, RTE_ALIGN_CEIL(queue_size, sizeof(void *)), 0, SOCKET_ID_ANY); - shared_action = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*shared_action), 0, - SOCKET_ID_ANY); + shared_action = mlx5_ipool_zmalloc + (priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], &idx); if (!shared_action || !queue) { rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "cannot allocate resource memory"); goto error_rss_init; } - shared_rss = &shared_action->rss; - shared_rss->queue = queue; - origin = &shared_rss->origin; + if (idx > (1u << MLX5_SHARED_ACTION_TYPE_OFFSET)) { + rte_flow_error_set(error, E2BIG, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "rss action number out of range"); + goto error_rss_init; + } + shared_action->queue = queue; + origin = &shared_action->origin; origin->func = rss->func; origin->level = rss->level; /* RSS type 0 indicates default RSS type (ETH_RSS_IP). */ origin->types = !rss->types ? ETH_RSS_IP : rss->types; /* NULL RSS key indicates default RSS key. */ rss_key = !rss->key ? rss_hash_default_key : rss->key; - memcpy(shared_rss->key, rss_key, MLX5_RSS_HASH_KEY_LEN); - origin->key = &shared_rss->key[0]; + memcpy(shared_action->key, rss_key, MLX5_RSS_HASH_KEY_LEN); + origin->key = &shared_action->key[0]; origin->key_len = MLX5_RSS_HASH_KEY_LEN; - memcpy(shared_rss->queue, rss->queue, queue_size); - origin->queue = shared_rss->queue; + memcpy(shared_action->queue, rss->queue, queue_size); + origin->queue = shared_action->queue; origin->queue_num = rss->queue_num; - if (__flow_dv_action_rss_setup(dev, shared_rss, error)) + if (__flow_dv_action_rss_setup(dev, shared_action, error)) goto error_rss_init; - shared_action->type = MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS; - return shared_action; + __atomic_add_fetch(&shared_action->refcnt, 1, __ATOMIC_RELAXED); + rte_spinlock_lock(&priv->shared_act_sl); + ILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + &priv->rss_shared_actions, idx, shared_action, next); + rte_spinlock_unlock(&priv->shared_act_sl); + return idx; error_rss_init: - mlx5_free(shared_action); - mlx5_free(queue); - return NULL; + if (shared_action) + mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + idx); + if (queue) + mlx5_free(queue); + return 0; } /** @@ -11337,8 +11361,8 @@ error_rss_init: * * @param[in] dev * Pointer to the Ethernet device structure. - * @param[in] shared_rss - * The shared RSS action object to be removed. + * @param[in] idx + * The shared RSS action object ID to be removed. * @param[out] error * Perform verbose error reporting if not NULL. Initialized in case of * error only. @@ -11347,31 +11371,39 @@ error_rss_init: * 0 on success, otherwise negative errno value. */ static int -__flow_dv_action_rss_release(struct rte_eth_dev *dev, - struct mlx5_shared_action_rss *shared_rss, - struct rte_flow_error *error) +__flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx, + struct rte_flow_error *error) { - struct rte_flow_shared_action *shared_action = NULL; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_shared_action_rss *shared_rss = + mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx); uint32_t old_refcnt = 1; - int remaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss); + int remaining; - if (remaining) { + if (!shared_rss) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "invalid shared action"); + remaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss); + if (remaining) return rte_flow_error_set(error, ETOOMANYREFS, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "shared rss hrxq has references"); - } - shared_action = container_of(shared_rss, - struct rte_flow_shared_action, rss); - if (!__atomic_compare_exchange_n(&shared_action->refcnt, &old_refcnt, - 0, 0, - __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { + if (!__atomic_compare_exchange_n(&shared_rss->refcnt, &old_refcnt, + 0, 0, __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED)) return rte_flow_error_set(error, ETOOMANYREFS, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "shared rss has references"); - } rte_free(shared_rss->queue); + rte_spinlock_lock(&priv->shared_act_sl); + ILIST_REMOVE(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + &priv->rss_shared_actions, idx, shared_rss, next); + rte_spinlock_unlock(&priv->shared_act_sl); + mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], + idx); return 0; } @@ -11398,30 +11430,23 @@ static struct rte_flow_shared_action * flow_dv_action_create(struct rte_eth_dev *dev, const struct rte_flow_shared_action_conf *conf, const struct rte_flow_action *action, - struct rte_flow_error *error) + struct rte_flow_error *err) { - struct rte_flow_shared_action *shared_action = NULL; - struct mlx5_priv *priv = dev->data->dev_private; + uint32_t idx = 0; + uint32_t ret = 0; switch (action->type) { case RTE_FLOW_ACTION_TYPE_RSS: - shared_action = __flow_dv_action_rss_create(dev, conf, - action->conf, - error); + ret = __flow_dv_action_rss_create(dev, conf, action->conf, err); + idx = (MLX5_SHARED_ACTION_TYPE_RSS << + MLX5_SHARED_ACTION_TYPE_OFFSET) | ret; break; default: - rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + rte_flow_error_set(err, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "action type not supported"); break; } - if (shared_action) { - __atomic_add_fetch(&shared_action->refcnt, 1, - __ATOMIC_RELAXED); - rte_spinlock_lock(&priv->shared_act_sl); - LIST_INSERT_HEAD(&priv->shared_actions, shared_action, next); - rte_spinlock_unlock(&priv->shared_act_sl); - } - return shared_action; + return ret ? (struct rte_flow_shared_action *)(uintptr_t)idx : NULL; } /** @@ -11446,12 +11471,14 @@ flow_dv_action_destroy(struct rte_eth_dev *dev, struct rte_flow_shared_action *action, struct rte_flow_error *error) { - struct mlx5_priv *priv = dev->data->dev_private; + uint32_t act_idx = (uint32_t)(uintptr_t)action; + uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET; + uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1); int ret; - switch (action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: - ret = __flow_dv_action_rss_release(dev, &action->rss, error); + switch (type) { + case MLX5_SHARED_ACTION_TYPE_RSS: + ret = __flow_dv_action_rss_release(dev, idx, error); break; default: return rte_flow_error_set(error, ENOTSUP, @@ -11461,10 +11488,6 @@ flow_dv_action_destroy(struct rte_eth_dev *dev, } if (ret) return ret; - rte_spinlock_lock(&priv->shared_act_sl); - LIST_REMOVE(action, next); - rte_spinlock_unlock(&priv->shared_act_sl); - rte_free(action); return 0; } @@ -11473,8 +11496,8 @@ flow_dv_action_destroy(struct rte_eth_dev *dev, * * @param[in] dev * Pointer to the Ethernet device structure. - * @param[in] shared_rss - * The shared RSS action object to be updated. + * @param[in] idx + * The shared RSS action object ID to be updated. * @param[in] action_conf * RSS action specification used to modify *shared_rss*. * @param[out] error @@ -11486,11 +11509,13 @@ flow_dv_action_destroy(struct rte_eth_dev *dev, * @note: currently only support update of RSS queues. */ static int -__flow_dv_action_rss_update(struct rte_eth_dev *dev, - struct mlx5_shared_action_rss *shared_rss, +__flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t idx, const struct rte_flow_action_rss *action_conf, struct rte_flow_error *error) { + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_shared_action_rss *shared_rss = + mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_RSS_SHARED_ACTIONS], idx); size_t i; int ret; void *queue = NULL; @@ -11498,6 +11523,10 @@ __flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t rss_key_len; uint32_t queue_size = action_conf->queue_num * sizeof(uint16_t); + if (!shared_rss) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "invalid shared action to update"); queue = mlx5_malloc(MLX5_MEM_ZERO, RTE_ALIGN_CEIL(queue_size, sizeof(void *)), 0, SOCKET_ID_ANY); @@ -11520,7 +11549,7 @@ __flow_dv_action_rss_update(struct rte_eth_dev *dev, for (tunnel = 0; tunnel < 2; tunnel++) { hrxq_idx = __flow_dv_action_rss_hrxq_lookup - (shared_rss, hash_fields, tunnel); + (dev, idx, hash_fields, tunnel); MLX5_ASSERT(hrxq_idx); ret = mlx5_hrxq_modify (dev, hrxq_idx, @@ -11567,14 +11596,17 @@ static int flow_dv_action_update(struct rte_eth_dev *dev, struct rte_flow_shared_action *action, const void *action_conf, - struct rte_flow_error *error) + struct rte_flow_error *err) { - switch (action->type) { - case MLX5_RTE_FLOW_ACTION_TYPE_SHARED_RSS: - return __flow_dv_action_rss_update(dev, &action->rss, - action_conf, error); + uint32_t act_idx = (uint32_t)(uintptr_t)action; + uint32_t type = act_idx >> MLX5_SHARED_ACTION_TYPE_OFFSET; + uint32_t idx = act_idx & ((1u << MLX5_SHARED_ACTION_TYPE_OFFSET) - 1); + + switch (type) { + case MLX5_SHARED_ACTION_TYPE_RSS: + return __flow_dv_action_rss_update(dev, idx, action_conf, err); default: - return rte_flow_error_set(error, ENOTSUP, + return rte_flow_error_set(err, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "action type not supported");