IB/mlx5: Support flow counters offset for bulk counters
Subsystems (2)
PATCH v2 1/1 IB/mlx5: Support flow counters offset for bulk counters
From: Yevgeny Kliteynik <[email protected]>
Add support for flow steering counters action with a non-base counter ID (offset) for bulk counters.
When creating a flow counter object, save the bulk value. This value is used when a flow action with a non-base counter ID is requested - to validate that the required offset is in the range of the allocated bulk.
---
Changelog
v1->v2: https://lore.kernel.org/linux-rdma/[email protected]
* Fixed mlx5_ib_devx_is_flow_counter() logic
v0 -> v1: https://lore.kernel.org/linux-rdma/[email protected]
* Change ffs to multiply bitmap
* Changed uint32_t to be u32
* Added offset to mlx5_ib_devx_is_flow_counter()
--- drivers/infiniband/hw/mlx5/devx.c | 15 +++++++++++- drivers/infiniband/hw/mlx5/flow.c | 29 ++++++++++++++++++++++-- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 4 deletions(-)
drivers/infiniband/hw/mlx5/devx.c +14 -1
@@ -100,6 +100,7 @@ struct devx_obj {struct mlx5_ib_devx_mr devx_mr;struct mlx5_core_dct core_dct;struct mlx5_core_cq core_cq; +u32 flow_counter_bulk_size; };struct list_head event_sub;/* holds devx_event_subscription entries */ };
@@ -192,15 +193,20 @@ bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type) } } -bool mlx5_ib_devx_is_flow_counter (void *obj,u32 *counter_id) +bool mlx5_ib_devx_is_flow_counter (void *obj,u32 offset,u32 *counter_id) {struct devx_obj *devx_obj = obj;u16 opcode =MLX5_GET (general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);if (opcode ==MLX5_CMD_OP_DEALLOC_FLOW_COUNTER ) { + +if (offset && offset >= devx_obj->flow_counter_bulk_size) +return false; + *counter_id =MLX5_GET (dealloc_flow_counter_in, devx_obj->dinbox, flow_counter_id); + *counter_id += offset;return true; }
@@ -1463,6 +1469,13 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(if (err) goto obj_free; +if (opcode ==MLX5_CMD_OP_ALLOC_FLOW_COUNTER ) { +u8 bulk =MLX5_GET (alloc_flow_counter_in, + cmd_in, + flow_counter_bulk); + obj->flow_counter_bulk_size =128UL * bulk; + } + uobj->object = obj;INIT_LIST_HEAD (&obj->event_sub); obj->ib_dev = dev;
drivers/infiniband/hw/mlx5/flow.c +27 -2
@@ -85,6 +85,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(struct mlx5_ib_dev *dev =mlx5_udata_to_mdev (&attrs->driver_udata);int len, ret, i;u32 counter_id =0 ; +u32 *offset_attr; +u32 offset =0 ;if (!capable (CAP_NET_RAW ))return -EPERM ;
@@ -151,8 +153,27 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(if (len) { devx_obj = arr_flow_actions[0 ]->object; -if (!mlx5_ib_devx_is_flow_counter (devx_obj, &counter_id)) +if (uverbs_attr_is_valid (attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET )) { + +int num_offsets =uverbs_attr_ptr_get_array_size ( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET , +sizeof (u32)); + +if (num_offsets !=1 ) +return -EINVAL ; + + offset_attr =uverbs_attr_get_alloced_ptr ( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET ); + offset = *offset_attr; + } + +if (!mlx5_ib_devx_is_flow_counter (devx_obj, offset, + &counter_id))return -EINVAL ; + flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_COUNT ; }
@@ -598,7 +619,11 @@ DECLARE_UVERBS_NAMED_METHOD(UVERBS_ATTR_IDRS_ARR (MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX ,MLX5_IB_OBJECT_DEVX_OBJ ,UVERBS_ACCESS_READ ,1 ,1 , - UA_OPTIONAL)); +UA_OPTIONAL ), +UVERBS_ATTR_PTR_IN (MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET , +UVERBS_ATTR_MIN_SIZE (sizeof (u32)), +UA_OPTIONAL , + UA_ALLOC_AND_COPY)); DECLARE_UVERBS_NAMED_METHOD_DESTROY( MLX5_IB_METHOD_DESTROY_FLOW,
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -1
@@ -1367,7 +1367,7 @@ struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add( struct mlx5_flow_act *flow_act, u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type);bool mlx5_ib_devx_is_flow_dest (void *obj,int *dest_id,int *dest_type); -bool mlx5_ib_devx_is_flow_counter (void *obj,u32 *counter_id); +bool mlx5_ib_devx_is_flow_counter (void *obj,u32 offset,u32 *counter_id);int mlx5_ib_get_flow_trees (const struct uverbs_object_tree_def **root);void mlx5_ib_destroy_flow_action_raw (struct mlx5_ib_flow_action *maction);#else
include/uapi/rdma/mlx5_user_ioctl_cmds.h +1 -0
@@ -198,6 +198,7 @@ enum mlx5_ib_create_flow_attrs {MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS ,MLX5_IB_ATTR_CREATE_FLOW_TAG ,MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX , + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, }; enum mlx5_ib_destoy_flow_attrs {
--
2.20.1
Quoted 98 lines · Leon Romanovsky
From: Yevgeny Kliteynik <[email protected]>
Add support for flow steering counters action with a non-base counter ID (offset) for bulk counters.
When creating a flow counter object, save the bulk value. This value is used when a flow action with a non-base counter ID is requested - to validate that the required offset is in the range of the allocated bulk.
Signed-off-by Yevgeny Kliteynik <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>---
Changelog
v1->v2: https://lore.kernel.org/linux-rdma/[email protected]
* Fixedmlx5_ib_devx_is_flow_counter()logic
v0 -> v1: https://lore.kernel.org/linux-rdma/[email protected]
* Change ffs to multiply bitmap
* Changeduint32_tto be u32
* Added offset tomlx5_ib_devx_is_flow_counter()--- drivers/infiniband/hw/mlx5/devx.c | 15 +++++++++++- drivers/infiniband/hw/mlx5/flow.c | 29 ++++++++++++++++++++++-- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 4 deletions(-)drivers/infiniband/hw/mlx5/devx.c +14
-1@@ -100,6 +100,7 @@ struct devx_obj {struct mlx5_ib_devx_mr devx_mr;struct mlx5_core_dct core_dct;struct mlx5_core_cq core_cq; +u32 flow_counter_bulk_size; };struct list_head event_sub;/* holds devx_event_subscription entries */ };@@ -192,15 +193,20 @@ bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type) } } -bool mlx5_ib_devx_is_flow_counter (void *obj,u32 *counter_id) +bool mlx5_ib_devx_is_flow_counter (void *obj,u32 offset,u32 *counter_id) {struct devx_obj *devx_obj = obj;u16 opcode =MLX5_GET (general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);if (opcode ==MLX5_CMD_OP_DEALLOC_FLOW_COUNTER ) { + +if (offset && offset >= devx_obj->flow_counter_bulk_size) +return false; + *counter_id =MLX5_GET (dealloc_flow_counter_in, devx_obj->dinbox, flow_counter_id); + *counter_id += offset;return true; }@@ -1463,6 +1469,13 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(if (err) goto obj_free; +if (opcode ==MLX5_CMD_OP_ALLOC_FLOW_COUNTER ) { +u8 bulk =MLX5_GET (alloc_flow_counter_in, + cmd_in, + flow_counter_bulk); + obj->flow_counter_bulk_size =128UL * bulk; + } + uobj->object = obj;INIT_LIST_HEAD (&obj->event_sub); obj->ib_dev = dev;drivers/infiniband/hw/mlx5/flow.c +7
-1@@ -85,6 +85,8 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(struct mlx5_ib_dev *dev =mlx5_udata_to_mdev (&attrs->driver_udata);int len, ret, i;u32 counter_id =0 ; +u32 *offset_attr; +u32 offset =0 ;if (!capable (CAP_NET_RAW ))return -EPERM ;@@ -151,8 +153,27 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(if (len) { devx_obj = arr_flow_actions[0 ]->object; -if (!mlx5_ib_devx_is_flow_counter (devx_obj, &counter_id)) +if (uverbs_attr_is_valid (attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET )) { + + int num_offsets = uverbs_attr_ptr_get_array_size( + attrs,
drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 170
Quoted 10 lines
drivers/infiniband/hw/mlx5/flow.c +10
-0+MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET , + sizeof(u32)); + +if (num_offsets !=1 ) +return -EINVAL ; + + offset_attr =uverbs_attr_get_alloced_ptr ( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET ); + offset = *offset_attr;
I would have used offset_arr and would have done:
offset = offset_attr[0] seems more appropriate but I don't mind either way.
Quoted 50 lines
drivers/infiniband/hw/mlx5/flow.c +10
-1+ } + +if (!mlx5_ib_devx_is_flow_counter (devx_obj, offset, + &counter_id))return -EINVAL ; + flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_COUNT ; }@@ -598,7 +619,11 @@ DECLARE_UVERBS_NAMED_METHOD(UVERBS_ATTR_IDRS_ARR (MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX ,MLX5_IB_OBJECT_DEVX_OBJ ,UVERBS_ACCESS_READ ,1 ,1 , - UA_OPTIONAL)); +UA_OPTIONAL ), +UVERBS_ATTR_PTR_IN (MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET , +UVERBS_ATTR_MIN_SIZE (sizeof (u32)), +UA_OPTIONAL , + UA_ALLOC_AND_COPY)); DECLARE_UVERBS_NAMED_METHOD_DESTROY( MLX5_IB_METHOD_DESTROY_FLOW,drivers/infiniband/hw/mlx5/mlx5_ib.h +1
-1@@ -1367,7 +1367,7 @@ struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add( struct mlx5_flow_act *flow_act, u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type);bool mlx5_ib_devx_is_flow_dest (void *obj,int *dest_id,int *dest_type); -bool mlx5_ib_devx_is_flow_counter (void *obj,u32 *counter_id); +bool mlx5_ib_devx_is_flow_counter (void *obj,u32 offset,u32 *counter_id);int mlx5_ib_get_flow_trees (const struct uverbs_object_tree_def **root);void mlx5_ib_destroy_flow_action_raw (struct mlx5_ib_flow_action *maction);#else include/uapi/rdma/mlx5_user_ioctl_cmds.h +1
-1@@ -198,6 +198,7 @@ enum mlx5_ib_create_flow_attrs {MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS ,MLX5_IB_ATTR_CREATE_FLOW_TAG ,MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX , + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, }; enum mlx5_ib_destoy_flow_attrs { --2.20.1
include/uapi/rdma/mlx5_user_ioctl_cmds.h enum mlx5_ib_create_flow_attrs { · line 202
Quoted 9 lines · Leon Romanovsky
include/uapi/rdma/mlx5_user_ioctl_cmds.h +2
-0+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h@@ -198,6 +198,7 @@ enum mlx5_ib_create_flow_attrs {MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS ,MLX5_IB_ATTR_CREATE_FLOW_TAG ,MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX , + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, };
Where is the rdma-core PR consuming this new uapi?
Jason
Quoted 12 lines · Jason Gunthorpe
include/uapi/rdma/mlx5_user_ioctl_cmds.h enum mlx5_ib_create_flow_attrs { · line 202
Quoted 9 lines · Leon Romanovsky
include/uapi/rdma/mlx5_user_ioctl_cmds.h +2
-0+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h@@ -198,6 +198,7 @@ enum mlx5_ib_create_flow_attrs {MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS ,MLX5_IB_ATTR_CREATE_FLOW_TAG ,MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX , + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, };Where is the rdma-core PR consuming this new uapi?
Below is the matching PR for this in rdma-core:
https://github.com/linux-rdma/rdma-core/pull/611
Yishai
Jason Gunthorpe
AppliedQuoted 21 lines · Leon Romanovsky
From: Yevgeny Kliteynik <[email protected]>
Add support for flow steering counters action with a non-base counter ID (offset) for bulk counters.
When creating a flow counter object, save the bulk value. This value is used when a flow action with a non-base counter ID is requested - to validate that the required offset is in the range of the allocated bulk.
Signed-off-by Yevgeny Kliteynik <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>Reviewed-by Mark Bloch <[email protected]>---
Changelog
v1->v2: https://lore.kernel.org/linux-rdma/[email protected]
* Fixedmlx5_ib_devx_is_flow_counter()logic
v0 -> v1: https://lore.kernel.org/linux-rdma/[email protected]
* Change ffs to multiply bitmap
* Changeduint32_tto be u32
* Added offset tomlx5_ib_devx_is_flow_counter()
Quoted 6 lines
--- drivers/infiniband/hw/mlx5/devx.c | 15 +++++++++++- drivers/infiniband/hw/mlx5/flow.c | 29 ++++++++++++++++++++++-- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 4 deletions(-)
Applied to for-next
Jason