Skip to content

Commit 0cacbcd

Browse files
sodarraslandarawsheh
authored andcommitted
net/mlx5: support flow count and age on root group
This patch enables support for count and age flow actions in root table i.e. flow group 0, when working with HW Steering flow engine (dv_flow_en = 2). It depends on support in HWS layer introduced in previous patches. Specifically this patch: - Adjusts action validation during flow actions translation to allow count and age on root group. - Adds creation and destruction of mlx5dr count action for use on root group. - Adjusts count action construction (done during rule create) to select correct action variant based on the group where the rule is created. Signed-off-by: Dariusz Sosnowski <[email protected]> Acked-by: Bing Zhao <[email protected]>
1 parent 65ccacc commit 0cacbcd

File tree

5 files changed

+107
-43
lines changed

5 files changed

+107
-43
lines changed

doc/guides/nics/mlx5.rst

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,19 +2701,27 @@ DPDK 19.05 19.02 21.05 21.05
27012701
Limitations
27022702
^^^^^^^^^^^
27032703

2704-
Because freeing a counter (by destroying a flow rule or destroying indirect action)
2705-
does not immediately make it available for the application,
2706-
the PMD might return:
2704+
With :ref:`HW steering <mlx5_hws>`:
27072705

2708-
- ``ENOENT`` if no counter is available in ``free``, ``reuse``
2709-
or ``wait_reset`` rings.
2710-
No counter will be available until the application releases some of them.
2711-
- ``EAGAIN`` if no counter is available in ``free`` and ``reuse`` rings,
2712-
but there are counters in ``wait_reset`` ring.
2713-
This means that after the next service thread cycle new counters will be available.
2706+
#. Because freeing a counter (by destroying a flow rule or destroying indirect action)
2707+
does not immediately make it available for the application,
2708+
the PMD might return:
27142709

2715-
The application has to be aware that flow rule create or indirect action create
2716-
might need be retried.
2710+
- ``ENOENT`` if no counter is available in ``free``, ``reuse``
2711+
or ``wait_reset`` rings.
2712+
No counter will be available until the application releases some of them.
2713+
- ``EAGAIN`` if no counter is available in ``free`` and ``reuse`` rings,
2714+
but there are counters in ``wait_reset`` ring.
2715+
This means that after the next service thread cycle,
2716+
new counters will be available.
2717+
2718+
The application has to be aware that flow rule or indirect action creation
2719+
might need to be retried.
2720+
2721+
#. Using count action on root tables requires:
2722+
2723+
- Linux kernel >= 6.4
2724+
- rdma-core >= 60.0
27172725

27182726

27192727
.. _mlx5_age:
@@ -2757,6 +2765,11 @@ With :ref:`HW steering <mlx5_hws>`,
27572765
(``RTE_FLOW_PORT_FLAG_STRICT_QUEUE`` passed to ``rte_flow_configure()``),
27582766
indirect age actions can be created only through asynchronous flow API.
27592767

2768+
#. Using age action on root tables requires:
2769+
2770+
- Linux kernel >= 6.4
2771+
- rdma-core >= 60.0
2772+
27602773

27612774
.. _mlx5_quota:
27622775

doc/guides/rel_notes/release_25_11.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ New Features
127127
* **Updated NVIDIA mlx5 driver.**
128128

129129
* Added support for NVIDIA ConnectX-9 SuperNIC adapters.
130+
* Added support for count and age flow actions on root tables
131+
with HW steering flow engine.
130132

131133
* **Updated NXP DPAA2 ethernet driver.**
132134

drivers/net/mlx5/mlx5_flow_hw.c

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,7 +1801,7 @@ flow_hw_represented_port_compile(struct rte_eth_dev *dev,
18011801

18021802
static __rte_always_inline int
18031803
flow_hw_cnt_compile(struct rte_eth_dev *dev, uint32_t start_pos,
1804-
struct mlx5_hw_actions *acts)
1804+
struct mlx5_hw_actions *acts, bool is_root)
18051805
{
18061806
struct mlx5_priv *priv = dev->data->dev_private;
18071807
uint32_t pos = start_pos;
@@ -1815,7 +1815,8 @@ flow_hw_cnt_compile(struct rte_eth_dev *dev, uint32_t start_pos,
18151815
(priv->hws_cpool,
18161816
cnt_id,
18171817
&acts->rule_acts[pos].action,
1818-
&acts->rule_acts[pos].counter.offset);
1818+
&acts->rule_acts[pos].counter.offset,
1819+
is_root);
18191820
if (ret != 0)
18201821
return ret;
18211822
acts->cnt_id = cnt_id;
@@ -2463,6 +2464,18 @@ mlx5_create_ipv6_ext_reformat(struct rte_eth_dev *dev,
24632464
return -EINVAL;
24642465
}
24652466

2467+
static bool
2468+
is_indirect_action_type_supported_root(const enum rte_flow_action_type type)
2469+
{
2470+
switch (type) {
2471+
case RTE_FLOW_ACTION_TYPE_COUNT:
2472+
case RTE_FLOW_ACTION_TYPE_AGE:
2473+
return mlx5dr_action_counter_root_is_supported();
2474+
default:
2475+
return false;
2476+
}
2477+
}
2478+
24662479
/**
24672480
* Translate rte_flow actions to DR action.
24682481
*
@@ -2547,8 +2560,9 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
25472560
goto err;
25482561
break;
25492562
case RTE_FLOW_ACTION_TYPE_INDIRECT:
2550-
if (is_root) {
2551-
DRV_LOG(ERR, "Indirect action is not supported in root table.");
2563+
if (is_root && !is_indirect_action_type_supported_root(masks->type)) {
2564+
DRV_LOG(ERR, "Indirect action type (%d) is not supported on root.",
2565+
masks->type);
25522566
goto err;
25532567
}
25542568
if (actions->conf && masks->conf) {
@@ -2787,12 +2801,10 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
27872801
goto err;
27882802
break;
27892803
case RTE_FLOW_ACTION_TYPE_AGE:
2790-
if (is_root) {
2791-
__flow_hw_action_template_destroy(dev, acts);
2804+
if (is_root && !mlx5dr_action_counter_root_is_supported()) {
27922805
rte_flow_error_set(&sub_error, ENOTSUP,
2793-
RTE_FLOW_ERROR_TYPE_ACTION,
2794-
NULL,
2795-
"Age action on root table is not supported in HW steering mode");
2806+
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
2807+
"Age action is not supported on group 0");
27962808
goto err;
27972809
}
27982810
if (__flow_hw_act_data_general_append(priv, acts,
@@ -2802,12 +2814,10 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
28022814
goto err;
28032815
break;
28042816
case RTE_FLOW_ACTION_TYPE_COUNT:
2805-
if (is_root) {
2806-
__flow_hw_action_template_destroy(dev, acts);
2817+
if (is_root && !mlx5dr_action_counter_root_is_supported()) {
28072818
rte_flow_error_set(&sub_error, ENOTSUP,
2808-
RTE_FLOW_ERROR_TYPE_ACTION,
2809-
NULL,
2810-
"Counter action on root table is not supported in HW steering mode");
2819+
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
2820+
"Count action is not supported on root table");
28112821
goto err;
28122822
}
28132823
if ((at->action_flags & MLX5_FLOW_ACTION_AGE) ||
@@ -2821,7 +2831,7 @@ __flow_hw_translate_actions_template(struct rte_eth_dev *dev,
28212831
if (masks->conf &&
28222832
((const struct rte_flow_action_count *)
28232833
masks->conf)->id) {
2824-
err = flow_hw_cnt_compile(dev, dr_pos, acts);
2834+
err = flow_hw_cnt_compile(dev, dr_pos, acts, is_root);
28252835
if (err)
28262836
goto err;
28272837
} else if (__flow_hw_act_data_general_append
@@ -3163,7 +3173,7 @@ flow_hw_construct_quota(struct mlx5_priv *priv,
31633173
static __rte_always_inline int
31643174
flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
31653175
const struct rte_flow_action *action,
3166-
struct rte_flow_template_table *table __rte_unused,
3176+
struct rte_flow_template_table *table,
31673177
const uint64_t item_flags, uint64_t action_flags,
31683178
struct rte_flow_hw *flow,
31693179
struct mlx5dr_rule_action *rule_act)
@@ -3182,6 +3192,7 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
31823192
((1u << MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1);
31833193
uint32_t *cnt_queue;
31843194
cnt_id_t age_cnt;
3195+
bool is_root = mlx5_group_id_is_root(table->grp->group_id);
31853196

31863197
memset(&act_data, 0, sizeof(act_data));
31873198
switch (type) {
@@ -3207,7 +3218,8 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
32073218
if (mlx5_hws_cnt_pool_get_action_offset(priv->hws_cpool,
32083219
act_idx,
32093220
&rule_act->action,
3210-
&rule_act->counter.offset))
3221+
&rule_act->counter.offset,
3222+
is_root))
32113223
return -1;
32123224
flow->flags |= MLX5_FLOW_HW_FLOW_FLAG_CNT_ID;
32133225
flow->cnt_id = act_idx;
@@ -3248,7 +3260,7 @@ flow_hw_shared_action_construct(struct rte_eth_dev *dev, uint32_t queue,
32483260
}
32493261
if (mlx5_hws_cnt_pool_get_action_offset(priv->hws_cpool,
32503262
age_cnt, &rule_act->action,
3251-
&rule_act->counter.offset))
3263+
&rule_act->counter.offset, is_root))
32523264
return -1;
32533265
break;
32543266
case MLX5_INDIRECT_ACTION_TYPE_CT:
@@ -3482,6 +3494,7 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
34823494
struct mlx5_aso_mtr *aso_mtr;
34833495
struct mlx5_multi_pattern_segment *mp_segment = NULL;
34843496
struct rte_flow_hw_aux *aux;
3497+
bool is_root = mlx5_group_id_is_root(table->grp->group_id);
34853498

34863499
attr.group = table->grp->group_id;
34873500
ft_flag = mlx5_hw_act_flag[!!table->grp->group_id][table->type];
@@ -3679,7 +3692,8 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
36793692
(priv->hws_cpool,
36803693
cnt_id,
36813694
&rule_acts[act_data->action_dst].action,
3682-
&rule_acts[act_data->action_dst].counter.offset
3695+
&rule_acts[act_data->action_dst].counter.offset,
3696+
is_root
36833697
);
36843698
if (ret != 0)
36853699
goto error;
@@ -3691,7 +3705,8 @@ flow_hw_actions_construct(struct rte_eth_dev *dev,
36913705
(priv->hws_cpool,
36923706
act_data->shared_counter.id,
36933707
&rule_acts[act_data->action_dst].action,
3694-
&rule_acts[act_data->action_dst].counter.offset
3708+
&rule_acts[act_data->action_dst].counter.offset,
3709+
is_root
36953710
);
36963711
if (ret != 0)
36973712
goto error;

drivers/net/mlx5/mlx5_hws_cnt.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
439439
}
440440

441441
cntp->cfg = *pcfg;
442+
DRV_LOG(DEBUG, "ibdev %s counter and age action %s supported on group 0",
443+
sh->ibdev_name,
444+
mlx5dr_action_counter_root_is_supported() ? "is" : "is not");
442445
if (cntp->cfg.host_cpool)
443446
return cntp;
444447
if (pcfg->request_num > sh->hws_max_nb_counters) {
@@ -659,9 +662,13 @@ mlx5_hws_cnt_pool_action_destroy(struct mlx5_hws_cnt_pool *cpool)
659662
for (idx = 0; idx < cpool->dcs_mng.batch_total; idx++) {
660663
struct mlx5_hws_cnt_dcs *dcs = &cpool->dcs_mng.dcs[idx];
661664

662-
if (dcs->dr_action != NULL) {
663-
mlx5dr_action_destroy(dcs->dr_action);
664-
dcs->dr_action = NULL;
665+
if (dcs->root_action != NULL) {
666+
mlx5dr_action_destroy(dcs->root_action);
667+
dcs->root_action = NULL;
668+
}
669+
if (dcs->hws_action != NULL) {
670+
mlx5dr_action_destroy(dcs->hws_action);
671+
dcs->hws_action = NULL;
665672
}
666673
}
667674
}
@@ -673,11 +680,14 @@ mlx5_hws_cnt_pool_action_create(struct mlx5_priv *priv,
673680
struct mlx5_hws_cnt_pool *hpool = mlx5_hws_cnt_host_pool(cpool);
674681
uint32_t idx;
675682
int ret = 0;
676-
uint32_t flags;
683+
uint32_t root_flags;
684+
uint32_t hws_flags;
677685

678-
flags = MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_HWS_TX;
686+
root_flags = MLX5DR_ACTION_FLAG_ROOT_RX | MLX5DR_ACTION_FLAG_ROOT_TX;
687+
hws_flags = MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_HWS_TX;
679688
if (priv->sh->config.dv_esw_en && priv->master) {
680-
flags |= (is_unified_fdb(priv) ?
689+
root_flags |= MLX5DR_ACTION_FLAG_ROOT_FDB;
690+
hws_flags |= (is_unified_fdb(priv) ?
681691
(MLX5DR_ACTION_FLAG_HWS_FDB_RX |
682692
MLX5DR_ACTION_FLAG_HWS_FDB_TX |
683693
MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED) :
@@ -687,10 +697,24 @@ mlx5_hws_cnt_pool_action_create(struct mlx5_priv *priv,
687697
struct mlx5_hws_cnt_dcs *hdcs = &hpool->dcs_mng.dcs[idx];
688698
struct mlx5_hws_cnt_dcs *dcs = &cpool->dcs_mng.dcs[idx];
689699

690-
dcs->dr_action = mlx5dr_action_create_counter(priv->dr_ctx,
700+
dcs->hws_action = mlx5dr_action_create_counter(priv->dr_ctx,
701+
(struct mlx5dr_devx_obj *)hdcs->obj,
702+
hws_flags);
703+
if (dcs->hws_action == NULL) {
704+
mlx5_hws_cnt_pool_action_destroy(cpool);
705+
ret = -ENOSYS;
706+
break;
707+
}
708+
709+
if (!mlx5dr_action_counter_root_is_supported()) {
710+
dcs->root_action = NULL;
711+
continue;
712+
}
713+
714+
dcs->root_action = mlx5dr_action_create_counter(priv->dr_ctx,
691715
(struct mlx5dr_devx_obj *)hdcs->obj,
692-
flags);
693-
if (dcs->dr_action == NULL) {
716+
root_flags);
717+
if (dcs->root_action == NULL) {
694718
mlx5_hws_cnt_pool_action_destroy(cpool);
695719
ret = -ENOSYS;
696720
break;

drivers/net/mlx5/mlx5_hws_cnt.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
#define MLX5_HWS_AGE_IDX_MASK (RTE_BIT32(MLX5_INDIRECT_ACTION_TYPE_OFFSET) - 1)
3232

3333
struct mlx5_hws_cnt_dcs {
34-
void *dr_action;
34+
struct mlx5dr_action *root_action; /* mlx5dr action used on root groups. */
35+
struct mlx5dr_action *hws_action; /* mlx5dr action used on non-root groups. */
3536
uint32_t batch_sz;
3637
uint32_t iidx; /* internal index of first counter in this bulk. */
3738
struct mlx5_devx_obj *obj;
@@ -632,12 +633,21 @@ mlx5_hws_cnt_pool_get_size(struct mlx5_hws_cnt_pool *cpool)
632633
static __rte_always_inline int
633634
mlx5_hws_cnt_pool_get_action_offset(struct mlx5_hws_cnt_pool *cpool,
634635
cnt_id_t cnt_id, struct mlx5dr_action **action,
635-
uint32_t *offset)
636+
uint32_t *offset, bool is_root)
636637
{
637638
uint8_t idx = cnt_id >> MLX5_HWS_CNT_DCS_IDX_OFFSET;
638639

639640
idx &= MLX5_HWS_CNT_DCS_IDX_MASK;
640-
*action = cpool->dcs_mng.dcs[idx].dr_action;
641+
if (likely(!is_root)) {
642+
*action = cpool->dcs_mng.dcs[idx].hws_action;
643+
} else {
644+
/*
645+
* Any table using counter on root group should be rejected on validation
646+
* when counter on root is not supported.
647+
*/
648+
MLX5_ASSERT(cpool->dcs_mng.dcs[idx].root_action != NULL);
649+
*action = cpool->dcs_mng.dcs[idx].root_action;
650+
}
641651
*offset = cnt_id & MLX5_HWS_CNT_IDX_MASK;
642652
return 0;
643653
}

0 commit comments

Comments
 (0)