From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A3754A04B5; Thu, 29 Oct 2020 23:00:12 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2BEEFCB7F; Thu, 29 Oct 2020 22:58:22 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id AFB9ECAC5 for ; Thu, 29 Oct 2020 22:58:11 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from matan@nvidia.com) with SMTP; 29 Oct 2020 23:58:05 +0200 Received: from nvidia.com (pegasus25.mtr.labs.mlnx [10.210.16.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 09TLw4Tv022832; Thu, 29 Oct 2020 23:58:05 +0200 From: Matan Azrad To: Viacheslav Ovsiienko Cc: dev@dpdk.org Date: Thu, 29 Oct 2020 21:58:01 +0000 Message-Id: <1604008681-414157-9-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 8/8] net/mlx5: support shared age action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add support for rte_flow shared action API for age action. First step here to support validate, create, query and destroy. The support is only for age ASO mode. Signed-off-by: Matan Azrad --- drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.c | 61 +++++++++++++++-- drivers/net/mlx5/mlx5_flow.h | 11 ++++ drivers/net/mlx5/mlx5_flow_dv.c | 140 ++++++++++++++++++++++++++++------------ 4 files changed, 165 insertions(+), 48 deletions(-) diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 9b1e5d5..da994db 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -524,6 +524,7 @@ struct mlx5_aso_sq { struct mlx5_aso_age_action { LIST_ENTRY(mlx5_aso_age_action) next; void *dr_action; + uint32_t refcnt; /* Following fields relevant only when action is active. */ uint16_t offset; /* Offset of ASO Flow Hit flag in DevX object. */ struct mlx5_age_param age_params; diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 29e67f4..d62d8ff 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -3292,6 +3292,29 @@ struct mlx5_flow_tunnel_info { return NULL; } +/** + * Get ASO age action by index. + * + * @param[in] dev + * Pointer to the Ethernet device structure. + * @param[in] age_idx + * Index to the ASO age action. + * + * @return + * The specified ASO age action. + */ +struct mlx5_aso_age_action* +flow_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx) +{ + uint16_t pool_idx = age_idx & UINT16_MAX; + uint16_t offset = (age_idx >> 16) & UINT16_MAX; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_aso_age_mng *mng = priv->sh->aso_age_mng; + struct mlx5_aso_age_pool *pool = mng->pools[pool_idx]; + + return &pool->actions[offset - 1]; +} + /* maps shared action to translated non shared in some actions array */ struct mlx5_translated_shared_action { struct rte_flow_shared_action *action; /**< Shared action */ @@ -3379,6 +3402,15 @@ struct mlx5_translated_shared_action { translated[shared->index].conf = &shared_rss->origin; break; + case MLX5_SHARED_ACTION_TYPE_AGE: + if (priv->sh->flow_hit_aso_en) { + translated[shared->index].type = + MLX5_RTE_FLOW_ACTION_TYPE_AGE; + translated[shared->index].conf = + (void *)(uintptr_t)idx; + break; + } + /* Fall-through */ default: mlx5_free(translated); return rte_flow_error_set @@ -7798,6 +7830,25 @@ struct mlx5_meter_domains_infos * return fops->action_update(dev, action, action_conf, error); } +/* Wrapper for driver action_destroy op callback */ +static int +flow_drv_action_query(struct rte_eth_dev *dev, + const struct rte_flow_shared_action *action, + void *data, + const struct mlx5_flow_driver_ops *fops, + struct rte_flow_error *error) +{ + static const char err_msg[] = "shared action query unsupported"; + + if (!fops->action_query) { + DRV_LOG(ERR, "port %u %s.", dev->data->port_id, err_msg); + rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + NULL, err_msg); + return -rte_errno; + } + return fops->action_query(dev, action, data, error); +} + /** * Create shared action for reuse in multiple flow rules. * @@ -7900,11 +7951,11 @@ struct mlx5_meter_domains_infos * void *data, struct rte_flow_error *error) { - (void)dev; - (void)action; - (void)data; - return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, - NULL, "action type query not supported"); + struct rte_flow_attr attr = { .transfer = 0 }; + const struct mlx5_flow_driver_ops *fops = + flow_get_drv_ops(flow_get_drv_type(dev, &attr)); + + return flow_drv_action_query(dev, action, data, fops, error); } /** diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 742971c..adb293c 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -36,12 +36,14 @@ enum mlx5_rte_flow_action_type { MLX5_RTE_FLOW_ACTION_TYPE_COPY_MREG, MLX5_RTE_FLOW_ACTION_TYPE_DEFAULT_MISS, MLX5_RTE_FLOW_ACTION_TYPE_TUNNEL_SET, + MLX5_RTE_FLOW_ACTION_TYPE_AGE, }; #define MLX5_SHARED_ACTION_TYPE_OFFSET 30 enum { MLX5_SHARED_ACTION_TYPE_RSS, + MLX5_SHARED_ACTION_TYPE_AGE, }; /* Matches on selected register. */ @@ -1173,6 +1175,12 @@ typedef int (*mlx5_flow_action_update_t) struct rte_flow_shared_action *action, const void *action_conf, struct rte_flow_error *error); +typedef int (*mlx5_flow_action_query_t) + (struct rte_eth_dev *dev, + const struct rte_flow_shared_action *action, + void *data, + struct rte_flow_error *error); + typedef int (*mlx5_flow_sync_domain_t) (struct rte_eth_dev *dev, uint32_t domains, @@ -1197,6 +1205,7 @@ struct mlx5_flow_driver_ops { mlx5_flow_action_create_t action_create; mlx5_flow_action_destroy_t action_destroy; mlx5_flow_action_update_t action_update; + mlx5_flow_action_query_t action_query; mlx5_flow_sync_domain_t sync_domain; }; @@ -1465,4 +1474,6 @@ struct mlx5_cache_entry *flow_dv_dest_array_create_cb struct mlx5_cache_entry *entry, void *cb_ctx); void flow_dv_dest_array_remove_cb(struct mlx5_cache_list *list, struct mlx5_cache_entry *entry); +struct mlx5_aso_age_action *flow_aso_age_get_by_idx(struct rte_eth_dev *dev, + uint32_t age_idx); #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 05f5871..b587b3f 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -5926,6 +5926,10 @@ struct mlx5_hlist_entry * /* Meter action will add one more TAG action. */ rw_act_num += MLX5_ACT_NUM_SET_TAG; break; + case MLX5_RTE_FLOW_ACTION_TYPE_AGE: + action_flags |= MLX5_FLOW_ACTION_AGE; + ++actions_n; + break; case RTE_FLOW_ACTION_TYPE_AGE: ret = flow_dv_validate_action_age(action_flags, actions, dev, @@ -9241,29 +9245,6 @@ struct mlx5_cache_entry * } /** - * Get ASO age action by index. - * - * @param[in] dev - * Pointer to the Ethernet device structure. - * @param[in] age_idx - * Index to the ASO age action. - * - * @return - * The specified ASO age action. - */ -static struct mlx5_aso_age_action* -flow_dv_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx) -{ - uint16_t pool_idx = age_idx & UINT16_MAX; - uint16_t offset = (age_idx >> 16) & UINT16_MAX; - struct mlx5_priv *priv = dev->data->dev_private; - struct mlx5_aso_age_mng *mng = priv->sh->aso_age_mng; - struct mlx5_aso_age_pool *pool = mng->pools[pool_idx]; - - return &pool->actions[offset - 1]; -} - -/** * Remove a flow counter from aged counter list. * * @param[in] dev @@ -9295,18 +9276,22 @@ struct mlx5_cache_entry * } } -static void +/* Return 0 when age action was removed, otherwise the number of references. */ +static int flow_dv_aso_age_release(struct rte_eth_dev *dev, uint32_t age_idx) { struct mlx5_priv *priv = dev->data->dev_private; struct mlx5_aso_age_mng *mng = priv->sh->aso_age_mng; - struct mlx5_aso_age_action *age = flow_dv_aso_age_get_by_idx(dev, - age_idx); + struct mlx5_aso_age_action *age = flow_aso_age_get_by_idx(dev, age_idx); + uint32_t ret = __atomic_sub_fetch(&age->refcnt, 1, __ATOMIC_RELAXED); - flow_dv_aso_age_remove_from_age(dev, age); - rte_spinlock_lock(&mng->free_sl); - LIST_INSERT_HEAD(&mng->free, age, next); - rte_spinlock_unlock(&mng->free_sl); + if (!ret) { + flow_dv_aso_age_remove_from_age(dev, age); + rte_spinlock_lock(&mng->free_sl); + LIST_INSERT_HEAD(&mng->free, age, next); + rte_spinlock_unlock(&mng->free_sl); + } + return ret; } /** @@ -9445,6 +9430,7 @@ struct mlx5_cache_entry * if (!age_free->dr_action) goto err; } + __atomic_store_n(&age_free->refcnt, 1, __ATOMIC_RELAXED); return pool->index | ((age_free->offset + 1) << 16); err: if (age_free) { @@ -9471,12 +9457,12 @@ struct mlx5_cache_entry * const struct rte_flow_action_age *age) { uint32_t age_idx = 0; - struct mlx5_aso_age_action *aso_age = NULL; + struct mlx5_aso_age_action *aso_age; age_idx = flow_dv_aso_age_alloc(dev); if (!age_idx) return 0; - aso_age = flow_dv_aso_age_get_by_idx(dev, age_idx); + aso_age = flow_aso_age_get_by_idx(dev, age_idx); aso_age->age_params.context = age->context; aso_age->age_params.timeout = age->timeout; aso_age->age_params.port_id = dev->data->port_id; @@ -9640,6 +9626,7 @@ struct mlx5_cache_entry * const uint8_t *rss_key; const struct rte_flow_action_meter *mtr; struct mlx5_flow_tbl_resource *tbl; + struct mlx5_aso_age_action *age_act; uint32_t port_id = 0; struct mlx5_flow_dv_port_id_action_resource port_id_resource; int action_type = actions->type; @@ -9776,6 +9763,14 @@ struct mlx5_cache_entry * action_flags |= MLX5_FLOW_ACTION_RSS; dev_flow->handle->fate_action = MLX5_FLOW_FATE_QUEUE; break; + case MLX5_RTE_FLOW_ACTION_TYPE_AGE: + flow->age = (uint32_t)(uintptr_t)(action->conf); + age_act = flow_aso_age_get_by_idx(dev, flow->age); + __atomic_fetch_add(&age_act->refcnt, 1, + __ATOMIC_RELAXED); + dev_flow->dv.actions[actions_n++] = age_act->dr_action; + action_flags |= MLX5_FLOW_ACTION_AGE; + break; case RTE_FLOW_ACTION_TYPE_AGE: if (priv->sh->flow_hit_aso_en) { flow->age = flow_dv_translate_create_aso_age @@ -9787,7 +9782,7 @@ struct mlx5_cache_entry * NULL, "can't create age action"); dev_flow->dv.actions[actions_n++] = - (flow_dv_aso_age_get_by_idx + (flow_aso_age_get_by_idx (dev, flow->age))->dr_action; action_flags |= MLX5_FLOW_ACTION_AGE; break; @@ -11443,6 +11438,19 @@ struct mlx5_cache_entry * idx = (MLX5_SHARED_ACTION_TYPE_RSS << MLX5_SHARED_ACTION_TYPE_OFFSET) | ret; break; + case RTE_FLOW_ACTION_TYPE_AGE: + ret = flow_dv_translate_create_aso_age(dev, action->conf); + idx = (MLX5_SHARED_ACTION_TYPE_AGE << + MLX5_SHARED_ACTION_TYPE_OFFSET) | ret; + if (ret) { + struct mlx5_aso_age_action *aso_age = + flow_aso_age_get_by_idx(dev, ret); + + if (!aso_age->age_params.context) + aso_age->age_params.context = + (void *)(uintptr_t)idx; + } + break; default: rte_flow_error_set(err, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "action type not supported"); @@ -11480,17 +11488,21 @@ struct mlx5_cache_entry * switch (type) { case MLX5_SHARED_ACTION_TYPE_RSS: - ret = __flow_dv_action_rss_release(dev, idx, error); - break; + return __flow_dv_action_rss_release(dev, idx, error); + case MLX5_SHARED_ACTION_TYPE_AGE: + ret = flow_dv_aso_age_release(dev, idx); + if (ret) + return rte_flow_error_set(error, ETOOMANYREFS, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "shared age has references"); + return ret; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, "action type not supported"); } - if (ret) - return ret; - return 0; } /** @@ -11611,9 +11623,41 @@ struct mlx5_cache_entry * return rte_flow_error_set(err, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, NULL, - "action type not supported"); + "action type update not supported"); } } + +static int +flow_dv_action_query(struct rte_eth_dev *dev, + const struct rte_flow_shared_action *action, void *data, + struct rte_flow_error *error) +{ + struct mlx5_age_param *age_param; + struct rte_flow_query_age *resp; + 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_AGE: + age_param = &flow_aso_age_get_by_idx(dev, idx)->age_params; + resp = data; + resp->aged = __atomic_load_n(&age_param->state, + __ATOMIC_RELAXED) == AGE_TMOUT ? + 1 : 0; + resp->sec_since_last_hit_valid = !resp->aged; + if (resp->sec_since_last_hit_valid) + resp->sec_since_last_hit = __atomic_load_n + (&age_param->sec_since_last_hit, __ATOMIC_RELAXED); + return 0; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "action type query not supported"); + } +} + /** * Query a dv flow rule for its statistics via devx. * @@ -11694,7 +11738,7 @@ struct mlx5_cache_entry * if (flow->age) { struct mlx5_aso_age_action *act = - flow_dv_aso_age_get_by_idx(dev, flow->age); + flow_aso_age_get_by_idx(dev, flow->age); age_param = &act->age_params; } else if (flow->counter) { @@ -12404,14 +12448,23 @@ struct mlx5_cache_entry * flow_dv_action_validate(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 mlx5_priv *priv = dev->data->dev_private; + RTE_SET_USED(conf); switch (action->type) { case RTE_FLOW_ACTION_TYPE_RSS: - return mlx5_validate_action_rss(dev, action, error); + return mlx5_validate_action_rss(dev, action, err); + case RTE_FLOW_ACTION_TYPE_AGE: + if (!priv->sh->aso_age_mng) + return rte_flow_error_set(err, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "shared age action not supported"); + return flow_dv_validate_action_age(0, action, dev, 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"); @@ -12463,6 +12516,7 @@ struct mlx5_cache_entry * .action_create = flow_dv_action_create, .action_destroy = flow_dv_action_destroy, .action_update = flow_dv_action_update, + .action_query = flow_dv_action_query, .sync_domain = flow_dv_sync_domain, }; -- 1.8.3.1