IB/mlx5: Support flow counters offset for bulk counters
Subsystems (2)
PATCH 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:
v0 -> v1: https://lore.kernel.org/linux-rdma/[email protected]
* Change ffs to multiply bitfmap
* 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 | 30 +++++++++++++++++++++--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 5 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 =128 * bulk; + } + uobj->object = obj;INIT_LIST_HEAD (&obj->event_sub); obj->ib_dev = dev;
drivers/infiniband/hw/mlx5/flow.c +27 -3
@@ -85,6 +85,7 @@ 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;if (!capable (CAP_NET_RAW ))return -EPERM ;
@@ -151,8 +152,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)) -return -EINVAL ; +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 =uverbs_attr_get_alloced_ptr ( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET ); + +if (!mlx5_ib_devx_is_flow_counter (devx_obj, + *offset, + &counter_id)) +return -EINVAL ; + } + flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_COUNT ; }
@@ -598,7 +618,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 101 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:
v0 -> v1: https://lore.kernel.org/linux-rdma/[email protected]
* Change ffs to multiply bitfmap
* 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 | 30 +++++++++++++++++++++--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 5 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 =128 * bulk; + } + uobj->object = obj;INIT_LIST_HEAD (&obj->event_sub); obj->ib_dev = dev;drivers/infiniband/hw/mlx5/flow.c +11
-2@@ -85,6 +85,7 @@ 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;if (!capable (CAP_NET_RAW ))return -EPERM ;@@ -151,8 +152,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)) -return -EINVAL ; +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 ;
drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 174
Quoted 10 lines
drivers/infiniband/hw/mlx5/flow.c +10
-0+ + offset =uverbs_attr_get_alloced_ptr ( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET ); + +if (!mlx5_ib_devx_is_flow_counter (devx_obj, + *offset, + &counter_id)) +return -EINVAL ; + }
Have you tested this patch without passing offset? because now the mlx5_ib_devx_is_flow_counter() is done only if MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET is passed.
Mark
Quoted 45 lines
drivers/infiniband/hw/mlx5/flow.c +6
-1+ flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_COUNT ; }@@ -598,7 +618,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
Hi Mark,
Quoted 121 lines
From: Mark Bloch <[email protected]>
Sent: Tuesday, October 29, 2019 19:01drivers/infiniband/hw/mlx5/devx.c static int
Quoted 65 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:
v0 -> v1:
https://lore.kernel.org/linux-rdma/[email protected]
rg
* Change ffs to multiply bitfmap
* 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 | 30 +++++++++++++++++++++--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 + 4 files changed, 43 insertions(+), 5 deletions(-)drivers/infiniband/hw/mlx5/devx.c +1
-0@@ -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)drivers/infiniband/hw/mlx5/devx.c +2
-1} } -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);
drivers/infiniband/hw/mlx5/devx.c +5
-0if (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 intUVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
drivers/infiniband/hw/mlx5/flow.c static int
Quoted 19 lines
drivers/infiniband/hw/mlx5/devx.c +7
-0if (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 =128 * bulk; + } + uobj->object = obj;INIT_LIST_HEAD (&obj->event_sub); obj->ib_dev = dev;drivers/infiniband/hw/mlx5/flow.c +0
-0@@ -85,6 +85,7 @@ static intUVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
drivers/infiniband/hw/mlx5/flow.c static int
Quoted 8 lines
drivers/infiniband/hw/mlx5/flow.c +1
-0struct mlx5_ib_dev *dev =mlx5_udata_to_mdev (&attrs->driver_udata);int len, ret, i;u32 counter_id =0 ; +u32 *offset;if (!capable (CAP_NET_RAW ))return -EPERM ;@@ -151,8 +152,27 @@ static intUVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 162
Quoted 8 lines
drivers/infiniband/hw/mlx5/flow.c +3
-2if (len) { devx_obj = arr_flow_actions[0 ]->object; -if (!mlx5_ib_devx_is_flow_counter (devx_obj, &counter_id)) -return -EINVAL ; + if (uverbs_attr_is_valid( + attrs, +
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET)) {drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 162
Quoted 3 lines
drivers/infiniband/hw/mlx5/flow.c +3
-0+ int num_offsets = uverbs_attr_ptr_get_array_size( + attrs, +
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 169
Quoted 8 lines
drivers/infiniband/hw/mlx5/flow.c +8
-0+ sizeof(u32)); + +if (num_offsets !=1 ) +return -EINVAL ; + + offset = uverbs_attr_get_alloced_ptr( + attrs, +MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET);
Quoted 11 lines
drivers/infiniband/hw/mlx5/flow.c static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · line 174
Quoted 6 lines
drivers/infiniband/hw/mlx5/flow.c +6
-0+ +if (!mlx5_ib_devx_is_flow_counter (devx_obj, + *offset, + &counter_id)) +return -EINVAL ; + }Have you tested this patch without passing offset? because now the
mlx5_ib_devx_is_flow_counter()is done only ifMLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
is passed.
Indeed. Thanks, v2 is on its way...
-- YK
Quoted 2 lines
Mark