Skip to content

Commit

Permalink
net/mlx5: support flow meter mark indirect action with HWS
Browse files Browse the repository at this point in the history
Add the ability to create an indirect action handle for METER_MARK.
It allows sharing one Meter between several different actions.

Signed-off-by: Alexander Kozyrev <[email protected]>
Acked-by: Viacheslav Ovsiienko <[email protected]>
  • Loading branch information
aleks-kozyrev authored and raslandarawsheh committed Oct 26, 2022
1 parent 773ca0e commit 48fbb0e
Show file tree
Hide file tree
Showing 11 changed files with 777 additions and 105 deletions.
1 change: 1 addition & 0 deletions doc/guides/nics/features/default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ jump =
mac_swap =
mark =
meter =
meter_mark =
modify_field =
nvgre_decap =
nvgre_encap =
Expand Down
1 change: 1 addition & 0 deletions doc/guides/nics/features/mlx5.ini
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ inc_tcp_seq = Y
jump = Y
mark = Y
meter = Y
meter_mark = Y
modify_field = Y
nvgre_decap = Y
nvgre_encap = Y
Expand Down
3 changes: 3 additions & 0 deletions doc/guides/nics/mlx5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Features
flow group.
- Flow metering, including meter policy API.
- Flow meter hierarchy.
- Flow meter mark.
- Flow integrity offload API.
- Connection tracking.
- Sub-Function representors.
Expand Down Expand Up @@ -494,6 +495,8 @@ Limitations
if meter has drop count
or meter hierarchy contains any meter that uses drop count,
it cannot be used by flow rule matching all ports.
- When using HWS flow engine (``dv_flow_en`` = 2),
only meter mark action is supported.

- Integrity:

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/mlx5/mlx5.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh)
rte_errno = ENOMEM;
return -ENOMEM;
}
err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_FLOW_HIT);
err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_FLOW_HIT, 1);
if (err) {
mlx5_free(sh->aso_age_mng);
return -1;
Expand Down Expand Up @@ -763,7 +763,7 @@ mlx5_flow_aso_ct_mng_init(struct mlx5_dev_ctx_shared *sh)
rte_errno = ENOMEM;
return -rte_errno;
}
err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_CONNECTION_TRACKING);
err = mlx5_aso_queue_init(sh, ASO_OPC_MOD_CONNECTION_TRACKING, MLX5_ASO_CT_SQ_NUM);
if (err) {
mlx5_free(sh->ct_mng);
/* rte_errno should be extracted from the failure. */
Expand Down
33 changes: 26 additions & 7 deletions drivers/net/mlx5/mlx5.h
Original file line number Diff line number Diff line change
Expand Up @@ -976,12 +976,16 @@ enum mlx5_aso_mtr_type {

/* Generic aso_flow_meter information. */
struct mlx5_aso_mtr {
LIST_ENTRY(mlx5_aso_mtr) next;
union {
LIST_ENTRY(mlx5_aso_mtr) next;
struct mlx5_aso_mtr_pool *pool;
};
enum mlx5_aso_mtr_type type;
struct mlx5_flow_meter_info fm;
/**< Pointer to the next aso flow meter structure. */
uint8_t state; /**< ASO flow meter state. */
uint32_t offset;
enum rte_color init_color;
};

/* Generic aso_flow_meter pool structure. */
Expand All @@ -990,7 +994,11 @@ struct mlx5_aso_mtr_pool {
/*Must be the first in pool*/
struct mlx5_devx_obj *devx_obj;
/* The devx object of the minimum aso flow meter ID. */
struct mlx5dr_action *action; /* HWS action. */
struct mlx5_indexed_pool *idx_pool; /* HWS index pool. */
uint32_t index; /* Pool index in management structure. */
uint32_t nb_sq; /* Number of ASO SQ. */
struct mlx5_aso_sq *sq; /* ASO SQs. */
};

LIST_HEAD(aso_meter_list, mlx5_aso_mtr);
Expand Down Expand Up @@ -1691,6 +1699,7 @@ struct mlx5_priv {
struct mlx5_aso_ct_pools_mng *ct_mng;
/* Management data for ASO connection tracking. */
struct mlx5_aso_ct_pool *hws_ctpool; /* HW steering's CT pool. */
struct mlx5_aso_mtr_pool *hws_mpool; /* HW steering's Meter pool. */
#endif
};

Expand Down Expand Up @@ -2011,7 +2020,8 @@ void mlx5_pmd_socket_uninit(void);
int mlx5_flow_meter_init(struct rte_eth_dev *dev,
uint32_t nb_meters,
uint32_t nb_meter_profiles,
uint32_t nb_meter_policies);
uint32_t nb_meter_policies,
uint32_t nb_queues);
void mlx5_flow_meter_uninit(struct rte_eth_dev *dev);
int mlx5_flow_meter_ops_get(struct rte_eth_dev *dev, void *arg);
struct mlx5_flow_meter_info *mlx5_flow_meter_find(struct mlx5_priv *priv,
Expand Down Expand Up @@ -2080,15 +2090,24 @@ eth_tx_burst_t mlx5_select_tx_function(struct rte_eth_dev *dev);

/* mlx5_flow_aso.c */

int mlx5_aso_mtr_queue_init(struct mlx5_dev_ctx_shared *sh,
struct mlx5_aso_mtr_pool *hws_pool,
struct mlx5_aso_mtr_pools_mng *pool_mng,
uint32_t nb_queues);
void mlx5_aso_mtr_queue_uninit(struct mlx5_dev_ctx_shared *sh,
struct mlx5_aso_mtr_pool *hws_pool,
struct mlx5_aso_mtr_pools_mng *pool_mng);
int mlx5_aso_queue_init(struct mlx5_dev_ctx_shared *sh,
enum mlx5_access_aso_opc_mod aso_opc_mod);
enum mlx5_access_aso_opc_mod aso_opc_mode,
uint32_t nb_queues);
int mlx5_aso_flow_hit_queue_poll_start(struct mlx5_dev_ctx_shared *sh);
int mlx5_aso_flow_hit_queue_poll_stop(struct mlx5_dev_ctx_shared *sh);
void mlx5_aso_queue_uninit(struct mlx5_dev_ctx_shared *sh,
enum mlx5_access_aso_opc_mod aso_opc_mod);
int mlx5_aso_meter_update_by_wqe(struct mlx5_dev_ctx_shared *sh,
struct mlx5_aso_mtr *mtr, struct mlx5_mtr_bulk *bulk);
int mlx5_aso_mtr_wait(struct mlx5_dev_ctx_shared *sh,
enum mlx5_access_aso_opc_mod aso_opc_mod);
int mlx5_aso_meter_update_by_wqe(struct mlx5_dev_ctx_shared *sh, uint32_t queue,
struct mlx5_aso_mtr *mtr,
struct mlx5_mtr_bulk *bulk);
int mlx5_aso_mtr_wait(struct mlx5_dev_ctx_shared *sh, uint32_t queue,
struct mlx5_aso_mtr *mtr);
int mlx5_aso_ct_update_by_wqe(struct mlx5_dev_ctx_shared *sh, uint32_t queue,
struct mlx5_aso_ct_action *ct,
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/mlx5/mlx5_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -4219,6 +4219,12 @@ flow_action_handles_translate(struct rte_eth_dev *dev,
MLX5_RTE_FLOW_ACTION_TYPE_COUNT;
translated[handle->index].conf = (void *)(uintptr_t)idx;
break;
case MLX5_INDIRECT_ACTION_TYPE_METER_MARK:
translated[handle->index].type =
(enum rte_flow_action_type)
MLX5_RTE_FLOW_ACTION_TYPE_METER_MARK;
translated[handle->index].conf = (void *)(uintptr_t)idx;
break;
case MLX5_INDIRECT_ACTION_TYPE_AGE:
if (priv->sh->flow_hit_aso_en) {
translated[handle->index].type =
Expand Down
20 changes: 14 additions & 6 deletions drivers/net/mlx5/mlx5_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum mlx5_rte_flow_action_type {
MLX5_RTE_FLOW_ACTION_TYPE_COUNT,
MLX5_RTE_FLOW_ACTION_TYPE_JUMP,
MLX5_RTE_FLOW_ACTION_TYPE_RSS,
MLX5_RTE_FLOW_ACTION_TYPE_METER_MARK,
};

/* Private (internal) Field IDs for MODIFY_FIELD action. */
Expand All @@ -54,22 +55,23 @@ enum mlx5_rte_flow_field_id {
MLX5_RTE_FLOW_FIELD_META_REG,
};

#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 30
#define MLX5_INDIRECT_ACTION_TYPE_OFFSET 29

enum {
MLX5_INDIRECT_ACTION_TYPE_RSS,
MLX5_INDIRECT_ACTION_TYPE_AGE,
MLX5_INDIRECT_ACTION_TYPE_COUNT,
MLX5_INDIRECT_ACTION_TYPE_CT,
MLX5_INDIRECT_ACTION_TYPE_METER_MARK,
};

/* Now, the maximal ports will be supported is 256, action number is 4M. */
#define MLX5_INDIRECT_ACT_CT_MAX_PORT 0x100
/* Now, the maximal ports will be supported is 16, action number is 32M. */
#define MLX5_INDIRECT_ACT_CT_MAX_PORT 0x10

#define MLX5_INDIRECT_ACT_CT_OWNER_SHIFT 22
#define MLX5_INDIRECT_ACT_CT_OWNER_MASK (MLX5_INDIRECT_ACT_CT_MAX_PORT - 1)

/* 30-31: type, 22-29: owner port, 0-21: index. */
/* 29-31: type, 25-28: owner port, 0-24: index */
#define MLX5_INDIRECT_ACT_CT_GEN_IDX(owner, index) \
((MLX5_INDIRECT_ACTION_TYPE_CT << MLX5_INDIRECT_ACTION_TYPE_OFFSET) | \
(((owner) & MLX5_INDIRECT_ACT_CT_OWNER_MASK) << \
Expand Down Expand Up @@ -1117,6 +1119,7 @@ struct rte_flow_hw {
};
struct rte_flow_template_table *table; /* The table flow allcated from. */
uint32_t cnt_id;
uint32_t mtr_id;
uint8_t rule[0]; /* HWS layer data struct. */
} __rte_packed;

Expand Down Expand Up @@ -1168,6 +1171,9 @@ struct mlx5_action_construct_data {
struct {
uint32_t id;
} shared_counter;
struct {
uint32_t id;
} shared_meter;
};
};

Expand Down Expand Up @@ -1251,6 +1257,7 @@ struct mlx5_hw_actions {
uint16_t encap_decap_pos; /* Encap/Decap action position. */
uint32_t mark:1; /* Indicate the mark action. */
uint32_t cnt_id; /* Counter id. */
uint32_t mtr_id; /* Meter id. */
/* Translated DR action array from action template. */
struct mlx5dr_rule_action rule_acts[MLX5_HW_MAX_ACTS];
};
Expand Down Expand Up @@ -1540,6 +1547,7 @@ flow_hw_get_reg_id(enum rte_flow_item_type type, uint32_t id)
*/
return REG_A;
case RTE_FLOW_ITEM_TYPE_CONNTRACK:
case RTE_FLOW_ITEM_TYPE_METER_COLOR:
return mlx5_flow_hw_aso_tag;
case RTE_FLOW_ITEM_TYPE_TAG:
MLX5_ASSERT(id < MLX5_FLOW_HW_TAGS_MAX);
Expand Down Expand Up @@ -1927,10 +1935,10 @@ mlx5_aso_meter_by_idx(struct mlx5_priv *priv, uint32_t idx)
struct mlx5_aso_mtr_pools_mng *pools_mng =
&priv->sh->mtrmng->pools_mng;

/* Decrease to original index. */
idx--;
if (priv->mtr_bulk.aso)
return priv->mtr_bulk.aso + idx;
/* Decrease to original index. */
idx--;
MLX5_ASSERT(idx / MLX5_ASO_MTRS_PER_POOL < pools_mng->n);
rte_rwlock_read_lock(&pools_mng->resize_mtrwl);
pool = pools_mng->pools[idx / MLX5_ASO_MTRS_PER_POOL];
Expand Down
Loading

0 comments on commit 48fbb0e

Please sign in to comment.