Verbs flow counters support
Subsystems (6)
v3 cover Verbs flow counters support
From: Leon Romanovsky <[email protected]>
Changelog:v2->v3:
* Change function mlx5_fc_query signature to hide the details of internal core driver struct mlx5_fc
* Add commen to data[] field at struct mlx5_ib_flow_counters_data (mlx5-abi.h)
* Use array of struct mlx5_ib_flow_counters_desc to clarify the outputv1->v2:
* Removed conversion from struct mlx5_fc* to void*
* Fixed one place with double space in it
* Balanced release of hardware handler in case of counters allocation failure
* Added Tested-by
* Minimize time spent holding mutex lock
* Fixed deadlock caused by nested lock in error path
* Protect from handler pointer derefence in the error paths
Not changed: mlx5-abi.h
v0->v1:
* Decouple from DevX submission
* Use uverbs_attr_get_obj at counters read method
* Added define for max read buffer size (MAX_COUNTERS_BUFF_SIZE)
* Removed the struct mlx5_ib_flow_counter basic_flow_cnts and the related structs used, used define instead
* Took Matan's patch from DevX
* uverbs_free_counters removed void* casting
* Added check to bound ncounters value (added define
* Changed user supplied data buffer structure to be array of struct <desc,index> pair (applied this change to user space also)
Not changed:
* UAPI files
* Addition of uhw to flow
Thanks
----------------------------------------------------------------------
Quoted 1 line
From Raed:
This series comes to allow user space applications to monitor real time traffic activity and events of the verbs objects it manages, e.g.:ibv_qp, ibv_wq, ibv_flow.
This API enables generic counters creation and define mapping to association with a verbs object, current mlx5 driver using this API for flow counters.
With this API, an application can monitor the entire life cycle of object activity, defined here as a static counters attachment. This API also allows dynamic counters monitoring of measurement points for a partial period in the verbs object life cycle.
In addition it presents the implementation of the generic counters interface.
This will be achieved by extending flow creation by adding a new flow count specification type which allows the user to associate a previously created flow counters using the generic verbs counters interface to the created flow, once associated the user could read statistics by using the read function of the generic counters interface.
The API includes:
1. create and destroyed API of a new counters objects
2. read the counters values from HW
Note:
Attaching API to allow application to define the measurement points per objects is a user space only API and this data is passed to kernel when the counted object (e.g. flow) is created with the counters object.
Thanks
Matan Barak (2):
IB/uverbs: Add an ib_uobject getter to ioctl() infrastructure IB/core: Support passing uhw for create_flow
Or Gerlitz (1):
net/mlx5: Use flow counter pointer as input to the query function
Raed Salem (11):
net/mlx5: Export flow counter related API IB/core: Introduce counters object and its create/destroy IB/uverbs: Add create/destroy counters support IB/core: Introduce counters read verb
IB/uverbs: Add read counters support
IB/core: Add support for flow counters IB/uverbs: Add support for flow counters IB/mlx5: Add counters create and destroy support IB/mlx5: Add flow counters binding support IB/mlx5: Add flow counters read support
IB/mlx5: Add counters read support
drivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/uverbs.h | 2 + drivers/infiniband/core/uverbs_cmd.c | 88 +++++- drivers/infiniband/core/uverbs_std_types.c | 3 +- .../infiniband/core/uverbs_std_types_counters.c | 157 +++++++++++ drivers/infiniband/core/uverbs_std_types_cq.c | 23 +- .../infiniband/core/uverbs_std_types_flow_action.c | 4 +- drivers/infiniband/core/verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 6 +- drivers/infiniband/hw/mlx5/main.c | 305 ++++++++++++++++++++- drivers/infiniband/hw/mlx5/mlx5_ib.h | 36 +++ drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 15 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 2 - .../net/ethernet/mellanox/mlx5/core/fs_counters.c | 7 +- include/linux/mlx5/fs.h | 4 + include/rdma/ib_verbs.h | 43 ++- include/rdma/uverbs_ioctl.h | 11 + include/uapi/rdma/ib_user_ioctl_cmds.h | 21 ++ include/uapi/rdma/ib_user_verbs.h | 13 + include/uapi/rdma/mlx5-abi.h | 24 ++ 20 files changed, 712 insertions(+), 56 deletions(-) create mode 100644 drivers/infiniband/core/uverbs_std_types_counters.c
PATCH v3 1/14 IB/uverbs: Add an ib_uobject getter to ioctl() infrastructure
From: Matan Barak <[email protected]>
Previously, the user had to dig inside the attribute to get the uobject. Add a helper function that correctly extract it (and do the required checks) for him/her.
--- drivers/infiniband/core/uverbs_std_types_cq.c | 23 +++++++++++----------- .../infiniband/core/uverbs_std_types_flow_action.c | 4 ++-- include/rdma/uverbs_ioctl.h | 11 +++++++++++ 3 files changed, 25 insertions(+), 13 deletions(-)
drivers/infiniband/core/uverbs_std_types_cq.c +12 -11
@@ -65,7 +65,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(struct ib_device *ib_dev,struct ib_cq_init_attr attr = {};struct ib_cq *cq;struct ib_uverbs_completion_event_file *ev_file =NULL ; -const struct uverbs_attr *ev_file_attr;struct ib_uobject *ev_file_uobj;if (!(ib_dev->uverbs_cmd_mask &1ULL <<IB_USER_VERBS_CMD_CREATE_CQ ))
@@ -87,10 +86,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(struct ib_device *ib_dev, UVERBS_ATTR_CREATE_CQ_FLAGS)))return -EFAULT ; - ev_file_attr =uverbs_attr_get (attrs,UVERBS_ATTR_CREATE_CQ_COMP_CHANNEL ); -if (!IS_ERR (ev_file_attr)) { - ev_file_uobj = ev_file_attr->obj_attr.uobject; - + ev_file_uobj =uverbs_attr_get_uobject (attrs,UVERBS_ATTR_CREATE_CQ_COMP_CHANNEL ); +if (!IS_ERR (ev_file_uobj)) { ev_file =container_of (ev_file_uobj, struct ib_uverbs_completion_event_file, uobj_file.uobj);
@@ -102,8 +99,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(struct ib_device *ib_dev, goto err_event_file; } - obj =container_of (uverbs_attr_get (attrs, -UVERBS_ATTR_CREATE_CQ_HANDLE )->obj_attr.uobject, + obj =container_of (uverbs_attr_get_uobject (attrs, +UVERBS_ATTR_CREATE_CQ_HANDLE ),typeof (*obj), uobject); obj->uverbs_file = ucontext->ufile; obj->comp_events_reported =0 ;
@@ -170,13 +167,17 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_DESTROY)(struct ib_device *ib_dev,struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) { - struct ib_uverbs_destroy_cq_resp resp; struct ib_uobject *uobj = -uverbs_attr_get (attrs,UVERBS_ATTR_DESTROY_CQ_HANDLE )->obj_attr.uobject; - struct ib_ucq_object *obj = container_of(uobj, struct ib_ucq_object, - uobject); +uverbs_attr_get_uobject (attrs,UVERBS_ATTR_DESTROY_CQ_HANDLE ); +struct ib_uverbs_destroy_cq_resp resp; +struct ib_ucq_object *obj;int ret; +if (IS_ERR (uobj)) +return PTR_ERR (uobj); + + obj = container_of(uobj, struct ib_ucq_object, uobject); +if (!(ib_dev->uverbs_cmd_mask &1ULL <<IB_USER_VERBS_CMD_DESTROY_CQ ))return -EOPNOTSUPP ;
drivers/infiniband/core/uverbs_std_types_flow_action.c +2 -2
@@ -320,7 +320,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE)(struct ib_devicereturn ret;/* No need to check as this attribute is marked as MANDATORY */ - uobj =uverbs_attr_get (attrs,UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE )->obj_attr.uobject; + uobj =uverbs_attr_get_uobject (attrs,UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE ); action = ib_dev->create_flow_action_esp (ib_dev, &esp_attr.hdr, attrs);if (IS_ERR (action))return PTR_ERR (action);
@@ -350,7 +350,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY)(struct ib_deviceif (ret)return ret; - uobj =uverbs_attr_get (attrs,UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE )->obj_attr.uobject; + uobj =uverbs_attr_get_uobject (attrs,UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE ); action = uobj->object;if (action->type !=IB_FLOW_ACTION_ESP )
include/rdma/uverbs_ioctl.h +11 -0
@@ -420,6 +420,17 @@ static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_breturn attr->obj_attr.uobject->object; } +static inline struct ib_uobject *uverbs_attr_get_uobject (const struct uverbs_attr_bundle *attrs_bundle, +u16 idx) +{ +const struct uverbs_attr *attr =uverbs_attr_get (attrs_bundle, idx); + +if (IS_ERR (attr)) +return ERR_CAST (attr); + +return attr->obj_attr.uobject; +} +static inline int uverbs_copy_to (const struct uverbs_attr_bundle *attrs_bundle,size_t idx,const void *from,size_t size) {
Signature · 1 line
2.14.3
PATCH v3 2/14 net/mlx5: Use flow counter pointer as input to the query function
In reply to Leon RomanovskyFrom: Or Gerlitz <[email protected]>
This allows to un-expose the details of struct mlx5_fc and keep it internal to the core driver as it used to be.
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 15 ++++++--------- drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 2 +- drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +6 -9
@@ -2104,21 +2104,18 @@ static int mlx5_eswitch_query_vport_drop_stats(struct mlx5_core_dev *dev,struct mlx5_vport *vport = &esw->vports[vport_idx];u64 rx_discard_vport_down, tx_discard_vport_down;u64 bytes =0 ; -u16 idx =0 ;int err =0 ;if (!vport->enabled || esw->mode !=SRIOV_LEGACY )return 0 ; -if (vport->egress.drop_counter) { - idx = vport->egress.drop_counter->id; -mlx5_fc_query (dev, idx, &stats->rx_dropped, &bytes); - } +if (vport->egress.drop_counter) +mlx5_fc_query (dev, vport->egress.drop_counter, + &stats->rx_dropped, &bytes); -if (vport->ingress.drop_counter) { - idx = vport->ingress.drop_counter->id; -mlx5_fc_query (dev, idx, &stats->tx_dropped, &bytes); - } +if (vport->ingress.drop_counter) +mlx5_fc_query (dev, vport->ingress.drop_counter, + &stats->tx_dropped, &bytes);if (!MLX5_CAP_GEN (dev, receive_discard_vport_down) && !MLX5_CAP_GEN (dev, transmit_discard_vport_down))
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +1 -1
@@ -233,7 +233,7 @@ void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev, unsigned long delay);void mlx5_fc_update_sampling_interval (struct mlx5_core_dev *dev,unsigned long interval); -int mlx5_fc_query (struct mlx5_core_dev *dev,u16 id, +int mlx5_fc_query (struct mlx5_core_dev *dev,struct mlx5_fc *counter,u64 *packets,u64 *bytes);int mlx5_init_fs (struct mlx5_core_dev *dev);
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +2 -2
@@ -312,10 +312,10 @@ void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev) } } -int mlx5_fc_query (struct mlx5_core_dev *dev,u16 id, +int mlx5_fc_query (struct mlx5_core_dev *dev,struct mlx5_fc *counter,u64 *packets,u64 *bytes) { -return mlx5_cmd_fc_query (dev, id, packets, bytes); +return mlx5_cmd_fc_query (dev, counter->id, packets, bytes); } void mlx5_fc_query_cached(struct mlx5_fc *counter,
Signature · 1 line
2.14.3
PATCH v3 3/14 net/mlx5: Export flow counter related API
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Exports counters API to be used in both IB and EN.
--- drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 2 -- drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c | 3 +++ include/linux/mlx5/fs.h | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +0 -2
@@ -233,8 +233,6 @@ void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev, unsigned long delay);void mlx5_fc_update_sampling_interval (struct mlx5_core_dev *dev,unsigned long interval); -int mlx5_fc_query (struct mlx5_core_dev *dev,struct mlx5_fc *counter, -u64 *packets,u64 *bytes);int mlx5_init_fs (struct mlx5_core_dev *dev);void mlx5_cleanup_fs (struct mlx5_core_dev *dev);
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +3 -0
@@ -243,6 +243,7 @@ struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging)return ERR_PTR (err); } +EXPORT_SYMBOL (mlx5_fc_create);void mlx5_fc_destroy (struct mlx5_core_dev *dev,struct mlx5_fc *counter) {
@@ -260,6 +261,7 @@ void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter)mlx5_cmd_fc_free (dev, counter->id);kfree (counter); } +EXPORT_SYMBOL (mlx5_fc_destroy);int mlx5_init_fc_stats (struct mlx5_core_dev *dev) {
@@ -317,6 +319,7 @@ int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, {return mlx5_cmd_fc_query (dev, counter->id, packets, bytes); } +EXPORT_SYMBOL (mlx5_fc_query);void mlx5_fc_query_cached (struct mlx5_fc *counter,u64 *bytes,u64 *packets,u64 *lastuse)
include/linux/mlx5/fs.h +3 -0
@@ -186,6 +186,9 @@ struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);void mlx5_fc_destroy (struct mlx5_core_dev *dev,struct mlx5_fc *counter);void mlx5_fc_query_cached (struct mlx5_fc *counter,u64 *bytes,u64 *packets,u64 *lastuse); +int mlx5_fc_query (struct mlx5_core_dev *dev,struct mlx5_fc *counter, +u64 *packets,u64 *bytes); +int mlx5_fs_add_rx_underlay_qpn (struct mlx5_core_dev *dev,u32 underlay_qpn);int mlx5_fs_remove_rx_underlay_qpn (struct mlx5_core_dev *dev,u32 underlay_qpn);
Signature · 1 line
2.14.3
PATCH v3 4/14 IB/core: Introduce counters object and its create/destroy
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
A verbs application may need to get statistics and info on various aspects of a verb object (e.g. Flow, QP, ...), in general case the application will state which object's counters its interested in (we refer to this action as attach), bind this new counters object to the appropriate verb object and on later stage read their values using the counters object.
This series introduces a general API for counters object that may accumulate any ib object counters type, bound and read on demand.
Counters instance is allocated on an IB context and belongs to that context.
Upon successful creation the counters can be bound to a verbs object so that hardware counter instances can be created and read.
Downstream patches in this series will introduce the attach, bind and the read functionality.
Counters instance can be de-allocated, upon successful destruction the related hardware resources are released.
Prior to destroy call the user must first make sure that the counters is not being used by any IB object, e.g. not attached to any of its counted type otherwise an EBUSY error is invoked.
--- include/rdma/ib_verbs.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
include/rdma/ib_verbs.h +11 -0
@@ -2212,6 +2212,13 @@ struct ib_port_pkey_list {struct list_head pkey_list; }; +struct ib_counters { +struct ib_device *device; +struct ib_uobject *uobject; +/* num of objects attached */ +atomic_t usecnt; +}; +struct uverbs_attr_bundle ;struct ib_device {
@@ -2483,6 +2490,10 @@ struct ib_device {struct ib_mr * (*reg_dm_mr)(struct ib_pd *pd,struct ib_dm *dm,struct ib_dm_mr_attr *attr,struct uverbs_attr_bundle *attrs); +struct ib_counters * (*create_counters)(struct ib_device *device, +struct uverbs_attr_bundle *attrs); +int (*destroy_counters)(struct ib_counters *counters); +/** * rdma netdev operation *
Signature · 1 line
2.14.3
PATCH v3 5/14 IB/uverbs: Add create/destroy counters support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
User space application which uses counters functionality, is expected to allocate/release the counters resources by calling create/destroy verbs and in turn get a unique handle that can be used to attach the counters to its counted type.
--- drivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/uverbs.h | 1 + drivers/infiniband/core/uverbs_std_types.c | 3 +- .../infiniband/core/uverbs_std_types_counters.c | 100 +++++++++++++++++++++ include/uapi/rdma/ib_user_ioctl_cmds.h | 14 +++ 5 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 drivers/infiniband/core/uverbs_std_types_counters.c
drivers/infiniband/core/Makefile +1 -1
@@ -37,4 +37,4 @@ ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \ rdma_core.o uverbs_std_types.o uverbs_ioctl.o \ uverbs_ioctl_merge.o uverbs_std_types_cq.o \ uverbs_std_types_flow_action.o uverbs_std_types_dm.o \ - uverbs_std_types_mr.o + uverbs_std_types_mr.o uverbs_std_types_counters.o
drivers/infiniband/core/uverbs.h +1 -0
@@ -287,6 +287,7 @@ extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_RWQ_IND_TBL);extern const struct uverbs_object_def UVERBS_OBJECT (UVERBS_OBJECT_XRCD );extern const struct uverbs_object_def UVERBS_OBJECT (UVERBS_OBJECT_FLOW_ACTION );extern const struct uverbs_object_def UVERBS_OBJECT (UVERBS_OBJECT_DM ); +extern const struct uverbs_object_def UVERBS_OBJECT (UVERBS_OBJECT_COUNTERS );#define IB_UVERBS_DECLARE_CMD (name) \ ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \
drivers/infiniband/core/uverbs_std_types.c +2 -1
@@ -302,7 +302,8 @@ static DECLARE_UVERBS_OBJECT_TREE(uverbs_default_objects, &UVERBS_OBJECT (UVERBS_OBJECT_RWQ_IND_TBL ), &UVERBS_OBJECT (UVERBS_OBJECT_XRCD ), &UVERBS_OBJECT (UVERBS_OBJECT_FLOW_ACTION ), - &UVERBS_OBJECT(UVERBS_OBJECT_DM)); + &UVERBS_OBJECT (UVERBS_OBJECT_DM ), + &UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS));const struct uverbs_object_tree_def *uverbs_default_get_objects (void ) {
drivers/infiniband/core/uverbs_std_types_counters.c new file +100 -0
100 lines not on this page · raw message
include/uapi/rdma/ib_user_ioctl_cmds.h +14 -0
@@ -55,6 +55,7 @@ enum uverbs_default_objects {UVERBS_OBJECT_WQ ,UVERBS_OBJECT_FLOW_ACTION ,UVERBS_OBJECT_DM , + UVERBS_OBJECT_COUNTERS, }; enum {
@@ -131,4 +132,17 @@ enum uverbs_methods_mr { UVERBS_METHOD_DM_MR_REG, }; +enum uverbs_attrs_create_counters_cmd_attr_ids { +UVERBS_ATTR_CREATE_COUNTERS_HANDLE , +}; + +enum uverbs_attrs_destroy_counters_cmd_attr_ids { +UVERBS_ATTR_DESTROY_COUNTERS_HANDLE , +}; + +enum uverbs_methods_actions_counters_ops { +UVERBS_METHOD_COUNTERS_CREATE , +UVERBS_METHOD_COUNTERS_DESTROY , +}; +#endif
Signature · 1 line
2.14.3
Re: [PATCH rdma-next v3 05/14] IB/uverbs: Add create/destroy counters support
drivers/infiniband/core/uverbs_std_types_counters.c line 1
Quoted 6 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +2
-0+++ b/drivers/infiniband/core/uverbs_std_types_counters.c@@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
Check patch tells me this is malformed should be:
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
Apparently the WITH Linux-syscall-note is only used in uapi header files.
Quoted 21 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +21
-0+/* +* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. +* +* This software is available to you under a choice of one of two +* licenses. You may choose to be licensed under the terms of the GNU +* General Public License (GPL) Version 2, available from the file +* COPYING in the main directory of this source tree, or the +* OpenIB.org BSD license below: +* +* Redistribution and use in source and binary forms, with or +* without modification, are permitted provided that the following +* conditions are met: +* +* - Redistributions of source code must retain the above +* copyright notice, this list of conditions and the following +* disclaimer. +* +* - Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials +* provided with the distribution.
drivers/infiniband/core/uverbs_std_types_counters.c line 32
Quoted 10 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +10
-0+* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/
And this is not a SPDX BSD-2-Clause license, this is the SPDX Linux-OpenIB license.
Please be careful to use the correct tag with SPDX..
Also can you check if these SPDX tags are what are intended:
include/rdma/restrack.h:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/core/restrack.c:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/hw/mlx5/ib_rep.c:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/hw/mlx5/ib_rep.h:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
I'm not super excited about the license proliferation, so if they should have been OR Linux-OpenIB as well then please send a patch.
Jason
Re: [PATCH rdma-next v3 05/14] IB/uverbs: Add create/destroy counters support
Quoted 53 lines · Jason Gunthorpe
drivers/infiniband/core/uverbs_std_types_counters.c line 1
Quoted 6 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +2
-0+++ b/drivers/infiniband/core/uverbs_std_types_counters.c@@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */ Check patch tells me this is malformed should be:
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
Apparently the WITH Linux-syscall-note is only used in uapi header files.
Quoted 21 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +21
-0+/* +* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. +* +* This software is available to you under a choice of one of two +* licenses. You may choose to be licensed under the terms of the GNU +* General Public License (GPL) Version 2, available from the file +* COPYING in the main directory of this source tree, or the +* OpenIB.org BSD license below: +* +* Redistribution and use in source and binary forms, with or +* without modification, are permitted provided that the following +* conditions are met: +* +* - Redistributions of source code must retain the above +* copyright notice, this list of conditions and the following +* disclaimer. +* +* - Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials +* provided with the distribution. drivers/infiniband/core/uverbs_std_types_counters.c line 32
Quoted 10 lines
drivers/infiniband/core/uverbs_std_types_counters.c new file +10
-0+* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ And this is not a SPDX BSD-2-Clause license, this is the SPDX Linux-OpenIB license.
Please be careful to use the correct tag with SPDX..
Also can you check if these SPDX tags are what are intended:
Quoted 7 lines
include/rdma/restrack.h:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/core/restrack.c:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/hw/mlx5/ib_rep.c:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ drivers/infiniband/hw/mlx5/ib_rep.h:/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
I'm not super excited about the license proliferation, so if they should have been OR Linux-OpenIB as well then please send a patch.
They are supposed to be OpenIB.
Thanks
Quoted 2 lines
Jason
PATCH v3 6/14 IB/core: Introduce counters read verb
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
The user supplies counters instance and a reference to an output array of uint64_t.
The driver reads the hardware counters values and writes them to the output index location in the user supplied array. All counters values are represented as uint64_t types.
To be able to successfully read the data the counters must be first bound to an IB object.
Downstream patches will present binding method for flow counters.
--- include/rdma/ib_verbs.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
include/rdma/ib_verbs.h +14 -0
@@ -2219,6 +2219,17 @@ struct ib_counters {atomic_t usecnt; }; +enum ib_read_counters_flags { +/* prefer read values from driver cache */ +IB_READ_COUNTERS_ATTR_PREFER_CACHED =1 <<0 , +}; + +struct ib_counters_read_attr { +u64 *counters_buff; +u32 ncounters; +u32 flags;/* use enum ib_read_counters_flags */ +}; +struct uverbs_attr_bundle ;struct ib_device {
@@ -2493,6 +2504,9 @@ struct ib_device {struct ib_counters * (*create_counters)(struct ib_device *device,struct uverbs_attr_bundle *attrs);int (*destroy_counters)(struct ib_counters *counters); +int (*read_counters)(struct ib_counters *counters, +struct ib_counters_read_attr *counters_read_attr, +struct uverbs_attr_bundle *attrs);/** * rdma netdev operation
Signature · 1 line
2.14.3
PATCH v3 7/14 IB/uverbs: Add read counters support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
This patch exposes the read counters verb to user space applications.
By that verb the user can read the hardware counters which are associated with the counters object.
The application needs to provide a sufficient memory to hold the statistics.
--- .../infiniband/core/uverbs_std_types_counters.c | 59 +++++++++++++++++++++- include/uapi/rdma/ib_user_ioctl_cmds.h | 7 +++ 2 files changed, 65 insertions(+), 1 deletion(-)
drivers/infiniband/core/uverbs_std_types_counters.c +58 -1
@@ -80,6 +80,49 @@ static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_CREATE)(struct ib_device *ib_dereturn ret; } +static int UVERBS_HANDLER (UVERBS_METHOD_COUNTERS_READ )(struct ib_device *ib_dev, +struct ib_uverbs_file *file, +struct uverbs_attr_bundle *attrs) +{ +struct ib_counters_read_attr read_attr = {}; +const struct uverbs_attr *uattr; +struct ib_counters *counters = +uverbs_attr_get_obj (attrs,UVERBS_ATTR_READ_COUNTERS_HANDLE ); +int ret; + +if (!ib_dev->read_counters) +return -EOPNOTSUPP ; + +if (!atomic_read (&counters->usecnt)) +return -EINVAL ; + + ret =uverbs_copy_from (&read_attr.flags, attrs, +UVERBS_ATTR_READ_COUNTERS_FLAGS ); +if (ret) +return ret; + + uattr =uverbs_attr_get (attrs,UVERBS_ATTR_READ_COUNTERS_BUFF ); + read_attr.ncounters = uattr->ptr_attr.len /sizeof (u64); + read_attr.counters_buff =kcalloc (read_attr.ncounters, +sizeof (u64),GFP_KERNEL ); +if (!read_attr.counters_buff) +return -ENOMEM ; + + ret = ib_dev->read_counters (counters, + &read_attr, + attrs); +if (ret) + goto err_read; + + ret =uverbs_copy_to (attrs,UVERBS_ATTR_READ_COUNTERS_BUFF , + read_attr.counters_buff, + read_attr.ncounters *sizeof (u64)); + +err_read: +kfree (read_attr.counters_buff); +return ret; +} + static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_COUNTERS_CREATE, &UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_COUNTERS_HANDLE, UVERBS_OBJECT_COUNTERS,
@@ -93,8 +136,22 @@ static DECLARE_UVERBS_NAMED_METHOD_WITH_HANDLER(UVERBS_METHOD_COUNTERS_DESTROY,UVERBS_ACCESS_DESTROY , UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY))); +#define MAX_COUNTERS_BUFF_SIZE USHRT_MAX +static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_COUNTERS_READ, + &UVERBS_ATTR_IDR(UVERBS_ATTR_READ_COUNTERS_HANDLE, + UVERBS_OBJECT_COUNTERS, + UVERBS_ACCESS_READ, + UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), + &UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_READ_COUNTERS_BUFF, + UVERBS_ATTR_SIZE(0, MAX_COUNTERS_BUFF_SIZE), + UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)), + &UVERBS_ATTR_PTR_IN(UVERBS_ATTR_READ_COUNTERS_FLAGS, +UVERBS_ATTR_TYPE (__u32 ), + UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY))); +DECLARE_UVERBS_NAMED_OBJECT (UVERBS_OBJECT_COUNTERS , &UVERBS_TYPE_ALLOC_IDR (0 , uverbs_free_counters), &UVERBS_METHOD (UVERBS_METHOD_COUNTERS_CREATE ), - &UVERBS_METHOD (UVERBS_METHOD_COUNTERS_DESTROY )); + &UVERBS_METHOD (UVERBS_METHOD_COUNTERS_DESTROY ), + &UVERBS_METHOD (UVERBS_METHOD_COUNTERS_READ ));
include/uapi/rdma/ib_user_ioctl_cmds.h +7 -0
@@ -140,9 +140,16 @@ enum uverbs_attrs_destroy_counters_cmd_attr_ids { UVERBS_ATTR_DESTROY_COUNTERS_HANDLE, }; +enum uverbs_attrs_read_counters_cmd_attr_ids { +UVERBS_ATTR_READ_COUNTERS_HANDLE , +UVERBS_ATTR_READ_COUNTERS_BUFF , +UVERBS_ATTR_READ_COUNTERS_FLAGS , +}; +enum uverbs_methods_actions_counters_ops {UVERBS_METHOD_COUNTERS_CREATE ,UVERBS_METHOD_COUNTERS_DESTROY , +UVERBS_METHOD_COUNTERS_READ , };#endif
Signature · 1 line
2.14.3
PATCH v3 8/14 IB/core: Support passing uhw for create_flow
In reply to Leon RomanovskyFrom: Matan Barak <[email protected]>
This is required when user-space drivers need to pass extra information regarding how to handle this flow steering specification.
--- drivers/infiniband/core/uverbs_cmd.c | 7 ++++++- drivers/infiniband/core/verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 6 +++++- drivers/infiniband/hw/mlx5/main.c | 7 ++++++- include/rdma/ib_verbs.h | 3 ++- 5 files changed, 20 insertions(+), 5 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +6 -1
@@ -3542,11 +3542,16 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, err = -EINVAL ; goto err_free; } - flow_id =ib_create_flow (qp, flow_attr,IB_FLOW_DOMAIN_USER ); + + flow_id = qp->device->create_flow (qp, flow_attr, +IB_FLOW_DOMAIN_USER , uhw); +if (IS_ERR (flow_id)) { err =PTR_ERR (flow_id); goto err_free; } +atomic_inc (&qp->usecnt); + flow_id->qp = qp; flow_id->uobject = uobj; uobj->object = flow_id; uflow =container_of (uobj,typeof (*uflow), uobject);
drivers/infiniband/core/verbs.c +1 -1
@@ -1983,7 +1983,7 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,if (!qp->device->create_flow)return ERR_PTR (-EOPNOTSUPP ); - flow_id = qp->device->create_flow (qp, flow_attr, domain); + flow_id = qp->device->create_flow (qp, flow_attr, domain,NULL );if (!IS_ERR (flow_id)) {atomic_inc (&qp->usecnt); flow_id->qp = qp;
drivers/infiniband/hw/mlx4/main.c +5 -1
@@ -1848,7 +1848,7 @@ static int mlx4_ib_add_dont_trap_rule(struct mlx4_dev *dev,static struct ib_flow *mlx4_ib_create_flow (struct ib_qp *qp,struct ib_flow_attr *flow_attr, -int domain) +int domain,struct ib_udata *udata) {int err =0 , i =0 , j =0 ;struct mlx4_ib_flow *mflow;
@@ -1866,6 +1866,10 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, (flow_attr->type != IB_FLOW_ATTR_NORMAL))return ERR_PTR (-EOPNOTSUPP ); +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +memset (type,0 ,sizeof (type)); mflow =kzalloc (sizeof (*mflow),GFP_KERNEL );
drivers/infiniband/hw/mlx5/main.c +6 -1
@@ -3371,7 +3371,8 @@ static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev,static struct ib_flow *mlx5_ib_create_flow (struct ib_qp *qp,struct ib_flow_attr *flow_attr, -int domain) +int domain, +struct ib_udata *udata) {struct mlx5_ib_dev *dev =to_mdev (qp->device);struct mlx5_ib_qp *mqp =to_mqp (qp);
@@ -3383,6 +3384,10 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,int err;int underlay_qpn; +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +if (flow_attr->priority >MLX5_IB_FLOW_LAST_PRIO )return ERR_PTR (-ENOMEM );
include/rdma/ib_verbs.h +2 -1
@@ -2459,7 +2459,8 @@ struct ib_device {struct ib_flow * (*create_flow)(struct ib_qp *qp,struct ib_flow_attr *flow_attr, -int domain); +int domain, +struct ib_udata *udata);int (*destroy_flow)(struct ib_flow *flow_id);int (*check_mr_status)(struct ib_mr *mr,u32 check_mask,struct ib_mr_status *mr_status);
Signature · 1 line
2.14.3
RE: [PATCH rdma-next v3 08/14] IB/core: Support passing uhw for create_flow
Quoted 37 lines
-----Original Message-----
From: Leon Romanovsky [mailto:[email protected]]
Sent: Thursday, May 31, 2018 9:44 AM
To: Doug Ledford <[email protected]>; Jason Gunthorpe <[email protected]>
Cc: Leon Romanovsky <[email protected]>; RDMA mailing list <linux- [email protected]>; Boris Pismenny <[email protected]>; Matan Barak <[email protected]>; Ruhl, Michael J <[email protected]>; Or Gerlitz <[email protected]>; Raed Salem <[email protected]>; Yishai Hadas <[email protected]>; Saeed Mahameed <[email protected]>; linux-netdev <[email protected]>
Subject: [PATCH rdma-next v3 08/14] IB/core: Support passing uhw forcreate_flowFrom: Matan Barak <[email protected]>
This is required when user-space drivers need to pass extra information regarding how to handle this flow steering specification.
Reviewed-by Yishai Hadas <[email protected]>Signed-off-by Matan Barak <[email protected]>Signed-off-by Boris Pismenny <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>---
drivers/infiniband/core/uverbs_cmd.c | 7 ++++++- drivers/infiniband/core/verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 6 +++++- drivers/infiniband/hw/mlx5/main.c | 7 ++++++- include/rdma/ib_verbs.h | 3 ++- 5 files changed, 20 insertions(+), 5 deletions(-)drivers/infiniband/core/uverbs_cmd.c +0
-0
drivers/infiniband/core/uverbs_cmd.c int ib_uverbs_ex_create_flow(struct · line 3549
Quoted 9 lines
drivers/infiniband/core/uverbs_cmd.c +4
-1@@ -3542,11 +3542,16 @@ int ib_uverbs_ex_create_flow(structib_uverbs_file *file, err = -EINVAL ; goto err_free; } - flow_id =ib_create_flow (qp, flow_attr,IB_FLOW_DOMAIN_USER ); + + flow_id = qp->device->create_flow (qp, flow_attr, +IB_FLOW_DOMAIN_USER , uhw); +
If the create_flow() callback is not defined, won't this cause a problem?
ib_flow_create() checks for the NULL.
Mike
Quoted 95 lines
drivers/infiniband/core/uverbs_cmd.c +2
-0if (IS_ERR (flow_id)) { err =PTR_ERR (flow_id); goto err_free; } +atomic_inc (&qp->usecnt); + flow_id->qp = qp; flow_id->uobject = uobj; uobj->object = flow_id;uflow = container_of(uobj, typeof(*uflow), uobject);drivers/infiniband/core/verbs.c +1
-1@@ -1983,7 +1983,7 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,if (!qp->device->create_flow)return ERR_PTR (-EOPNOTSUPP ); - flow_id = qp->device->create_flow (qp, flow_attr, domain); + flow_id = qp->device->create_flow (qp, flow_attr, domain,NULL );if (!IS_ERR (flow_id)) {atomic_inc (&qp->usecnt); flow_id->qp = qp;drivers/infiniband/hw/mlx4/main.c +1
-1@@ -1848,7 +1848,7 @@ static int mlx4_ib_add_dont_trap_rule(structmlx4_dev *dev, static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr, - int domain) + int domain, struct ib_udata *udata) { int err = 0, i = 0, j = 0;struct mlx4_ib_flow *mflow;drivers/infiniband/hw/mlx4/main.c +4
-0@@ -1866,6 +1866,10 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, (flow_attr->type != IB_FLOW_ATTR_NORMAL))return ERR_PTR (-EOPNOTSUPP ); +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +memset (type,0 ,sizeof (type));mflow = kzalloc(sizeof(*mflow), GFP_KERNEL);drivers/infiniband/hw/mlx5/main.c +2
-1@@ -3371,7 +3371,8 @@ static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev, static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr, - int domain) + int domain, + struct ib_udata *udata) { struct mlx5_ib_dev *dev = to_mdev(qp->device);struct mlx5_ib_qp *mqp = to_mqp(qp);drivers/infiniband/hw/mlx5/main.c +4
-0@@ -3383,6 +3384,10 @@ static struct ib_flow *mlx5_ib_create_flow(structib_qp *qp, int err;int underlay_qpn; +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +if (flow_attr->priority >MLX5_IB_FLOW_LAST_PRIO )return ERR_PTR (-ENOMEM );include/rdma/ib_verbs.h +2
-1@@ -2459,7 +2459,8 @@ struct ib_device {struct ib_flow * (*create_flow)(struct ib_qp *qp,struct ib_flow_attr *flow_attr, -int domain); +int domain, +struct ib_udata *udata);int (*destroy_flow)(struct ib_flow *flow_id); int (*check_mr_status)(struct ib_mr *mr, u32 check_mask,struct
ib_mr_status*mr_status);
--
2.14.3
Re: [PATCH rdma-next v3 08/14] IB/core: Support passing uhw for create_flow
Quoted 49 lines · Michael J
Quoted 37 lines
-----Original Message-----
From: Leon Romanovsky [mailto:[email protected]]
Sent: Thursday, May 31, 2018 9:44 AM
To: Doug Ledford <[email protected]>; Jason Gunthorpe <[email protected]>
Cc: Leon Romanovsky <[email protected]>; RDMA mailing list <linux- [email protected]>; Boris Pismenny <[email protected]>; Matan Barak <[email protected]>; Ruhl, Michael J <[email protected]>; Or Gerlitz <[email protected]>; Raed Salem <[email protected]>; Yishai Hadas <[email protected]>; Saeed Mahameed <[email protected]>; linux-netdev <[email protected]>
Subject: [PATCH rdma-next v3 08/14] IB/core: Support passing uhw forcreate_flowFrom: Matan Barak <[email protected]>
This is required when user-space drivers need to pass extra information regarding how to handle this flow steering specification.
Reviewed-by Yishai Hadas <[email protected]>Signed-off-by Matan Barak <[email protected]>Signed-off-by Boris Pismenny <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>---
drivers/infiniband/core/uverbs_cmd.c | 7 ++++++- drivers/infiniband/core/verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 6 +++++- drivers/infiniband/hw/mlx5/main.c | 7 ++++++- include/rdma/ib_verbs.h | 3 ++- 5 files changed, 20 insertions(+), 5 deletions(-)drivers/infiniband/core/uverbs_cmd.c +0
-0drivers/infiniband/core/uverbs_cmd.c int ib_uverbs_ex_create_flow(struct · line 3549
Quoted 9 lines
drivers/infiniband/core/uverbs_cmd.c +4
-1@@ -3542,11 +3542,16 @@ int ib_uverbs_ex_create_flow(structib_uverbs_file *file, err = -EINVAL ; goto err_free; } - flow_id =ib_create_flow (qp, flow_attr,IB_FLOW_DOMAIN_USER ); + + flow_id = qp->device->create_flow (qp, flow_attr, +IB_FLOW_DOMAIN_USER , uhw); +If the
create_flow()callback is not defined, won't this cause a problem?
Quoted 2 lines
ib_flow_create()checks for the NULL.
We are fine here.
This function is called only if the device turned on the command mask (i.e. IB_USER_VERBS_EX_CMD_CREATE_FLOW) which comes together with its callback.
see:
https://elixir.bootlin.com/linux/latest/source/drivers/infiniband/core/uverbs_main.c#L709
Quoted 103 lines
Quoted 93 lines
drivers/infiniband/core/uverbs_cmd.c +2
-0if (IS_ERR (flow_id)) { err =PTR_ERR (flow_id); goto err_free; } +atomic_inc (&qp->usecnt); + flow_id->qp = qp; flow_id->uobject = uobj; uobj->object = flow_id;uflow = container_of(uobj, typeof(*uflow), uobject);drivers/infiniband/core/verbs.c +1
-1@@ -1983,7 +1983,7 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,if (!qp->device->create_flow)return ERR_PTR (-EOPNOTSUPP ); - flow_id = qp->device->create_flow (qp, flow_attr, domain); + flow_id = qp->device->create_flow (qp, flow_attr, domain,NULL );if (!IS_ERR (flow_id)) {atomic_inc (&qp->usecnt); flow_id->qp = qp;drivers/infiniband/hw/mlx4/main.c +1
-1@@ -1848,7 +1848,7 @@ static int mlx4_ib_add_dont_trap_rule(structmlx4_dev *dev, static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr, - int domain) + int domain, struct ib_udata *udata) { int err = 0, i = 0, j = 0;struct mlx4_ib_flow *mflow;drivers/infiniband/hw/mlx4/main.c +4
-0@@ -1866,6 +1866,10 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, (flow_attr->type != IB_FLOW_ATTR_NORMAL))return ERR_PTR (-EOPNOTSUPP ); +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +memset (type,0 ,sizeof (type));mflow = kzalloc(sizeof(*mflow), GFP_KERNEL);drivers/infiniband/hw/mlx5/main.c +2
-1@@ -3371,7 +3371,8 @@ static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev, static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_attr, - int domain) + int domain, + struct ib_udata *udata) { struct mlx5_ib_dev *dev = to_mdev(qp->device);struct mlx5_ib_qp *mqp = to_mqp(qp);drivers/infiniband/hw/mlx5/main.c +4
-0@@ -3383,6 +3384,10 @@ static struct ib_flow *mlx5_ib_create_flow(structib_qp *qp, int err;int underlay_qpn; +if (udata && + udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) +return ERR_PTR (-EOPNOTSUPP ); +if (flow_attr->priority >MLX5_IB_FLOW_LAST_PRIO )return ERR_PTR (-ENOMEM );include/rdma/ib_verbs.h +2
-1@@ -2459,7 +2459,8 @@ struct ib_device {struct ib_flow * (*create_flow)(struct ib_qp *qp,struct ib_flow_attr *flow_attr, -int domain); +int domain, +struct ib_udata *udata);int (*destroy_flow)(struct ib_flow *flow_id); int (*check_mr_status)(struct ib_mr *mr, u32 check_mask,Quoted 4 lines
struct
ib_mr_status*mr_status);
--
2.14.3--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v3 9/14 IB/core: Add support for flow counters
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
A counters object could be attached to flow on creation by providing the counter specification action.
General counters description which count packets and bytes are introduced, downstream patches from this series will use them as part of flow counters binding.
In addition, increase number of flow specifications supported layers to 10 upon adding count specification and for the previously added drop specification.
--- include/rdma/ib_verbs.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
include/rdma/ib_verbs.h +14 -1
@@ -1859,9 +1859,10 @@ enum ib_flow_spec_type {IB_FLOW_SPEC_ACTION_TAG =0x1000 ,IB_FLOW_SPEC_ACTION_DROP =0x1001 ,IB_FLOW_SPEC_ACTION_HANDLE =0x1002 , + IB_FLOW_SPEC_ACTION_COUNT = 0x1003, };#define IB_FLOW_SPEC_LAYER_MASK 0xF0 -#define IB_FLOW_SPEC_SUPPORT_LAYERS 8 +#define IB_FLOW_SPEC_SUPPORT_LAYERS 10/* Flow steering rule priority is set according to it's domain. * Lower domain value means higher priority.
@@ -2041,6 +2042,17 @@ struct ib_flow_spec_action_handle {struct ib_flow_action *act; }; +enum ib_counters_description { +IB_COUNTER_PACKETS , +IB_COUNTER_BYTES , +}; + +struct ib_flow_spec_action_count { +enum ib_flow_spec_type type; +u16 size; +struct ib_counters *counters; +}; + union ib_flow_spec { struct { u32 type;
@@ -2058,6 +2070,7 @@ union ib_flow_spec {struct ib_flow_spec_action_tag flow_tag;struct ib_flow_spec_action_drop drop;struct ib_flow_spec_action_handle action; +struct ib_flow_spec_action_count flow_count; };struct ib_flow_attr {
Signature · 1 line
2.14.3
PATCH v3 10/14 IB/uverbs: Add support for flow counters
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
The struct ib_uverbs_flow_spec_action_count associates a counters object with the flow.
Post this association the flow counters can be read via the counters object.
--- drivers/infiniband/core/uverbs.h | 1 + drivers/infiniband/core/uverbs_cmd.c | 81 +++++++++++++++++++++++++++++++----- include/uapi/rdma/ib_user_verbs.h | 13 ++++++ 3 files changed, 84 insertions(+), 11 deletions(-)
drivers/infiniband/core/uverbs.h +1 -0
@@ -263,6 +263,7 @@ struct ib_uverbs_flow_spec {struct ib_uverbs_flow_spec_action_tag flow_tag;struct ib_uverbs_flow_spec_action_drop drop;struct ib_uverbs_flow_spec_action_handle action; +struct ib_uverbs_flow_spec_action_count flow_count; }; };
drivers/infiniband/core/uverbs_cmd.c +70 -11
122 lines not on this page · raw message
include/uapi/rdma/ib_user_verbs.h +13 -0
@@ -998,6 +998,19 @@ struct ib_uverbs_flow_spec_action_handle {__u32 reserved1; }; +struct ib_uverbs_flow_spec_action_count { +union { +struct ib_uverbs_flow_spec_hdr hdr; +struct { +__u32 type; +__u16 size; +__u16 reserved; + }; + }; +__u32 handle; +__u32 reserved1; +}; +struct ib_uverbs_flow_tunnel_filter {__be32 tunnel_id; };
Signature · 1 line
2.14.3
RE: [PATCH rdma-next v3 10/14] IB/uverbs: Add support for flow counters
Quoted 65 lines
-----Original Message-----
From: Leon Romanovsky [mailto:[email protected]]
Sent: Thursday, May 31, 2018 9:44 AM
To: Doug Ledford <[email protected]>; Jason Gunthorpe <[email protected]>
Cc: Leon Romanovsky <[email protected]>; RDMA mailing list <linux- [email protected]>; Boris Pismenny <[email protected]>; Matan Barak <[email protected]>; Ruhl, Michael J <[email protected]>; Or Gerlitz <[email protected]>; Raed Salem <[email protected]>; Yishai Hadas <[email protected]>; Saeed Mahameed <[email protected]>; linux-netdev <[email protected]>
Subject: [PATCH rdma-next v3 10/14] IB/uverbs: Add support for flow countersFrom: Raed Salem <[email protected]>
The struct
ib_uverbs_flow_spec_action_countassociates a counters object with the flow.Post this association the flow counters can be read via the counters object.
Reviewed-by Yishai Hadas <[email protected]>Signed-off-by Raed Salem <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>---
drivers/infiniband/core/uverbs.h| 1 +drivers/infiniband/core/uverbs_cmd.c| 81
+++++++++++++++++++++++++++++++-----include/uapi/rdma/ib_user_verbs.h| 13 ++++++3 files changed, 84 insertions(+), 11 deletions(-)drivers/infiniband/core/uverbs.h +1
-0@@ -263,6 +263,7 @@ struct ib_uverbs_flow_spec {struct ib_uverbs_flow_spec_action_tag flow_tag;struct ib_uverbs_flow_spec_action_drop drop;struct ib_uverbs_flow_spec_action_handle action; +struct ib_uverbs_flow_spec_action_count flow_count; }; };drivers/infiniband/core/uverbs_cmd.c +4
-1@@ -2748,43 +2748,82 @@ ssize_t ib_uverbs_detach_mcast(structib_uverbs_file *file, struct ib_uflow_resources { size_t max;size_t num; -struct ib_flow_action *collection[0 ]; +size_t collection_num; +size_t counters_num; +struct ib_counters **counters; +struct ib_flow_action **collection; };static struct ib_uflow_resources *flow_resources_alloc (size_t num_specs) {struct ib_uflow_resources *resources;
drivers/infiniband/core/uverbs_cmd.c ssize_t ib_uverbs_detach_mcast(struct · line 2766
Quoted 10 lines
drivers/infiniband/core/uverbs_cmd.c +2
-4- resources = -kmalloc (sizeof (*resources) + - num_specs *sizeof (*resources->collection), GFP_KERNEL); + resources =kzalloc (sizeof (*resources),GFP_KERNEL );if (!resources) -return NULL ; + goto err_res;
Why the new goto?
drivers/infiniband/core/uverbs_cmd.c ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, · line 2770
Quoted 7 lines
drivers/infiniband/core/uverbs_cmd.c +6
-0+ + resources->counters = +kcalloc (num_specs,sizeof (*resources->counters),GFP_KERNEL ); + +if (!resources->counters) + goto err_cnt;
kcalloc() zeros stuff. Could you just have a single common goto for the cleanup?
Mike
Quoted 124 lines
drivers/infiniband/core/uverbs_cmd.c +37
-5+ + resources->collection = +kcalloc (num_specs,sizeof (*resources->collection),GFP_KERNEL ); + +if (!resources->collection) + goto err_collection; - resources->num =0 ; resources->max = num_specs;return resources; + +err_collection: +kfree (resources->counters); +err_cnt: +kfree (resources); +err_res: +return NULL ; }void ib_uverbs_flow_resources_free (struct ib_uflow_resources *uflow_res) {unsigned int i; -for (i =0 ; i < uflow_res->num; i++) +for (i =0 ; i < uflow_res->collection_num; i++)atomic_dec (&uflow_res->collection[i]->usecnt); +for (i =0 ; i < uflow_res->counters_num; i++) +atomic_dec (&uflow_res->counters[i]->usecnt); + +kfree (uflow_res->collection); +kfree (uflow_res->counters);kfree (uflow_res); }static void flow_resources_add (struct ib_uflow_resources *uflow_res, -struct ib_flow_action *action) +enum ib_flow_spec_type type, +void *ibobj) {WARN_ON (uflow_res->num >= uflow_res->max); -atomic_inc (&action->usecnt); - uflow_res->collection[uflow_res->num++] = action; +switch (type) { +case IB_FLOW_SPEC_ACTION_HANDLE : +atomic_inc (&((struct ib_flow_action *)ibobj)->usecnt); + uflow_res->collection[uflow_res->collection_num++] = + (struct ib_flow_action *)ibobj; +break ; +case IB_FLOW_SPEC_ACTION_COUNT : +atomic_inc (&((struct ib_counters *)ibobj)->usecnt); + uflow_res->counters[uflow_res->counters_num++] = + (struct ib_counters *)ibobj; +break ; +default : +WARN_ON (1 ); + } + + uflow_res->num++;}
static int kern_spec_to_ib_spec_action(struct
ib_ucontext*ucontext,drivers/infiniband/core/uverbs_cmd.c +21
-1@@ -2821,9 +2860,29 @@ static int kern_spec_to_ib_spec_action(struct ib_ucontext *ucontext, return -EINVAL ; ib_spec->action.size =sizeof (struct ib_flow_spec_action_handle ); -flow_resources_add (uflow_res, ib_spec->action.act); +flow_resources_add (uflow_res, +IB_FLOW_SPEC_ACTION_HANDLE , + ib_spec->action.act);uobj_put_obj_read (ib_spec->action.act);break ; +case IB_FLOW_SPEC_ACTION_COUNT : +if (kern_spec->flow_count.size != +sizeof (struct ib_uverbs_flow_spec_action_count )) +return -EINVAL ; + ib_spec->flow_count.counters = +uobj_get_obj_read (counters, +UVERBS_OBJECT_COUNTERS , + kern_spec->flow_count.handle, + ucontext); +if (!ib_spec->flow_count.counters) +return -EINVAL ; + ib_spec->flow_count.size = +sizeof (struct ib_flow_spec_action_count ); +flow_resources_add (uflow_res, +IB_FLOW_SPEC_ACTION_COUNT , + ib_spec->flow_count.counters); +uobj_put_obj_read (ib_spec->flow_count.counters); +break ;default :return -EINVAL ;}include/uapi/rdma/ib_user_verbs.h +13
-1@@ -998,6 +998,19 @@ struct ib_uverbs_flow_spec_action_handle {__u32 reserved1; }; +struct ib_uverbs_flow_spec_action_count { +union { +struct ib_uverbs_flow_spec_hdr hdr; +struct { +__u32 type; +__u16 size; +__u16 reserved; + }; + }; +__u32 handle; +__u32 reserved1; +}; +struct ib_uverbs_flow_tunnel_filter {__be32 tunnel_id; }; --2.14.3
Re: [PATCH rdma-next v3 10/14] IB/uverbs: Add support for flow counters
Quoted 72 lines · Michael J
Quoted 72 lines
-----Original Message-----
From: Leon Romanovsky [mailto:[email protected]]
Sent: Thursday, May 31, 2018 9:44 AM
To: Doug Ledford <[email protected]>; Jason Gunthorpe <[email protected]>
Cc: Leon Romanovsky <[email protected]>; RDMA mailing list <linux- [email protected]>; Boris Pismenny <[email protected]>; Matan Barak <[email protected]>; Ruhl, Michael J <[email protected]>; Or Gerlitz <[email protected]>; Raed Salem <[email protected]>; Yishai Hadas <[email protected]>; Saeed Mahameed <[email protected]>; linux-netdev <[email protected]>
Subject: [PATCH rdma-next v3 10/14] IB/uverbs: Add support for flow countersFrom: Raed Salem <[email protected]>
The struct
ib_uverbs_flow_spec_action_countassociates a counters object with the flow.Post this association the flow counters can be read via the counters object.
Reviewed-by Yishai Hadas <[email protected]>Signed-off-by Raed Salem <[email protected]>Signed-off-by Leon Romanovsky <[email protected]>---
drivers/infiniband/core/uverbs.h| 1 +drivers/infiniband/core/uverbs_cmd.c| 81
+++++++++++++++++++++++++++++++-----include/uapi/rdma/ib_user_verbs.h| 13 ++++++3 files changed, 84 insertions(+), 11 deletions(-)drivers/infiniband/core/uverbs.h +1
-0@@ -263,6 +263,7 @@ struct ib_uverbs_flow_spec {struct ib_uverbs_flow_spec_action_tag flow_tag;struct ib_uverbs_flow_spec_action_drop drop;struct ib_uverbs_flow_spec_action_handle action; +struct ib_uverbs_flow_spec_action_count flow_count; }; };drivers/infiniband/core/uverbs_cmd.c +5
-4@@ -2748,43 +2748,82 @@ ssize_t ib_uverbs_detach_mcast(structib_uverbs_file *file, struct ib_uflow_resources { size_t max;size_t num; -struct ib_flow_action *collection[0 ]; +size_t collection_num; +size_t counters_num; +struct ib_counters **counters; +struct ib_flow_action **collection; };static struct ib_uflow_resources *flow_resources_alloc (size_t num_specs) {struct ib_uflow_resources *resources; - resources = -kmalloc (sizeof (*resources) + - num_specs *sizeof (*resources->collection), GFP_KERNEL); + resources =kzalloc (sizeof (*resources),GFP_KERNEL );
Quoted 5 lines
drivers/infiniband/core/uverbs_cmd.c ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, · line 2764
Quoted 3 lines
drivers/infiniband/core/uverbs_cmd.c +1
-1if (!resources) -return NULL ; + goto err_res;Why the new goto?
No real reason :)
Quoted 11 lines
drivers/infiniband/core/uverbs_cmd.c ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, · line 2770
Quoted 8 lines
drivers/infiniband/core/uverbs_cmd.c +6
-0+ + resources->counters = +kcalloc (num_specs,sizeof (*resources->counters),GFP_KERNEL ); + +if (!resources->counters) + goto err_cnt;
kcalloc()zeros stuff. Could you just have a single common goto for the cleanup?
I have mixed feelings regarding such approach, technically you are right, but I think that it will hurt readability.
I can send followup patch, will it work for you?
Thanks for review.
Quoted 128 lines
Mike
Quoted 124 lines
drivers/infiniband/core/uverbs_cmd.c +37
-5+ + resources->collection = +kcalloc (num_specs,sizeof (*resources->collection),GFP_KERNEL ); + +if (!resources->collection) + goto err_collection; - resources->num =0 ; resources->max = num_specs;return resources; + +err_collection: +kfree (resources->counters); +err_cnt: +kfree (resources); +err_res: +return NULL ; }void ib_uverbs_flow_resources_free (struct ib_uflow_resources *uflow_res) {unsigned int i; -for (i =0 ; i < uflow_res->num; i++) +for (i =0 ; i < uflow_res->collection_num; i++)atomic_dec (&uflow_res->collection[i]->usecnt); +for (i =0 ; i < uflow_res->counters_num; i++) +atomic_dec (&uflow_res->counters[i]->usecnt); + +kfree (uflow_res->collection); +kfree (uflow_res->counters);kfree (uflow_res); }static void flow_resources_add (struct ib_uflow_resources *uflow_res, -struct ib_flow_action *action) +enum ib_flow_spec_type type, +void *ibobj) {WARN_ON (uflow_res->num >= uflow_res->max); -atomic_inc (&action->usecnt); - uflow_res->collection[uflow_res->num++] = action; +switch (type) { +case IB_FLOW_SPEC_ACTION_HANDLE : +atomic_inc (&((struct ib_flow_action *)ibobj)->usecnt); + uflow_res->collection[uflow_res->collection_num++] = + (struct ib_flow_action *)ibobj; +break ; +case IB_FLOW_SPEC_ACTION_COUNT : +atomic_inc (&((struct ib_counters *)ibobj)->usecnt); + uflow_res->counters[uflow_res->counters_num++] = + (struct ib_counters *)ibobj; +break ; +default : +WARN_ON (1 ); + } + + uflow_res->num++;}
static int kern_spec_to_ib_spec_action(struct
ib_ucontext*ucontext,drivers/infiniband/core/uverbs_cmd.c +21
-1@@ -2821,9 +2860,29 @@ static int kern_spec_to_ib_spec_action(struct ib_ucontext *ucontext, return -EINVAL ; ib_spec->action.size =sizeof (struct ib_flow_spec_action_handle ); -flow_resources_add (uflow_res, ib_spec->action.act); +flow_resources_add (uflow_res, +IB_FLOW_SPEC_ACTION_HANDLE , + ib_spec->action.act);uobj_put_obj_read (ib_spec->action.act);break ; +case IB_FLOW_SPEC_ACTION_COUNT : +if (kern_spec->flow_count.size != +sizeof (struct ib_uverbs_flow_spec_action_count )) +return -EINVAL ; + ib_spec->flow_count.counters = +uobj_get_obj_read (counters, +UVERBS_OBJECT_COUNTERS , + kern_spec->flow_count.handle, + ucontext); +if (!ib_spec->flow_count.counters) +return -EINVAL ; + ib_spec->flow_count.size = +sizeof (struct ib_flow_spec_action_count ); +flow_resources_add (uflow_res, +IB_FLOW_SPEC_ACTION_COUNT , + ib_spec->flow_count.counters); +uobj_put_obj_read (ib_spec->flow_count.counters); +break ;default :return -EINVAL ;}include/uapi/rdma/ib_user_verbs.h +13
-1@@ -998,6 +998,19 @@ struct ib_uverbs_flow_spec_action_handle {__u32 reserved1; }; +struct ib_uverbs_flow_spec_action_count { +union { +struct ib_uverbs_flow_spec_hdr hdr; +struct { +__u32 type; +__u16 size; +__u16 reserved; + }; + }; +__u32 handle; +__u32 reserved1; +}; +struct ib_uverbs_flow_tunnel_filter {__be32 tunnel_id; }; --2.14.3
PATCH v3 11/14 IB/mlx5: Add counters create and destroy support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
This patch implements the device counters create and destroy APIs and introducing some internal management structures.
Downstream patches in this series will add the functionality to support flow counters binding and reading.
--- drivers/infiniband/hw/mlx5/main.c | 23 +++++++++++++++++++++++ drivers/infiniband/hw/mlx5/mlx5_ib.h | 10 ++++++++++ 2 files changed, 33 insertions(+)
drivers/infiniband/hw/mlx5/main.c +23 -0
@@ -5132,6 +5132,27 @@ static void depopulate_specs_root(struct mlx5_ib_dev *dev)uverbs_free_spec_tree (dev->ib_dev.specs_root); } +static int mlx5_ib_destroy_counters (struct ib_counters *counters) +{ +struct mlx5_ib_mcounters *mcounters =to_mcounters (counters); + +kfree (mcounters); + +return 0 ; +} + +static struct ib_counters *mlx5_ib_create_counters (struct ib_device *device, +struct uverbs_attr_bundle *attrs) +{ +struct mlx5_ib_mcounters *mcounters; + + mcounters =kzalloc (sizeof (*mcounters),GFP_KERNEL ); +if (!mcounters) +return ERR_PTR (-ENOMEM ); + +return &mcounters->ibcntrs; +} +void mlx5_ib_stage_init_cleanup (struct mlx5_ib_dev *dev) {mlx5_ib_cleanup_multiport_master (dev);
@@ -5375,6 +5396,8 @@ int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev) dev->ib_dev.destroy_flow_action = mlx5_ib_destroy_flow_action; dev->ib_dev.modify_flow_action_esp = mlx5_ib_modify_flow_action_esp; dev->ib_dev.driver_id =RDMA_DRIVER_MLX5 ; + dev->ib_dev.create_counters = mlx5_ib_create_counters; + dev->ib_dev.destroy_counters = mlx5_ib_destroy_counters; err =init_node_data (dev);if (err)
drivers/infiniband/hw/mlx5/mlx5_ib.h +10 -0
@@ -813,6 +813,16 @@ struct mlx5_memic {DECLARE_BITMAP (memic_alloc_pages,MLX5_MAX_MEMIC_PAGES ); }; +struct mlx5_ib_mcounters { +struct ib_counters ibcntrs; +}; + +static inline struct mlx5_ib_mcounters * +to_mcounters (struct ib_counters *ibcntrs) +{ + return container_of(ibcntrs, struct mlx5_ib_mcounters, ibcntrs); +} +struct mlx5_ib_dev {struct ib_device ib_dev;struct mlx5_core_dev *mdev;
Signature · 1 line
2.14.3
PATCH v3 12/14 IB/mlx5: Add flow counters binding support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Associates a counters with a flow when IB_FLOW_SPEC_ACTION_COUNT is part of the flow specifications.
The counters user space placements of location and description (index, description) pairs are passed as private data of the counters flow specification.
--- drivers/infiniband/hw/mlx5/main.c | 223 ++++++++++++++++++++++++++++++++--- drivers/infiniband/hw/mlx5/mlx5_ib.h | 15 +++ include/linux/mlx5/fs.h | 1 + include/uapi/rdma/mlx5-abi.h | 24 ++++ 4 files changed, 249 insertions(+), 14 deletions(-)
drivers/infiniband/hw/mlx5/main.c +209 -14
@@ -2480,7 +2480,7 @@ static int check_mpls_supp_fields(u32 field_support, const __be32 *set_mask)#define LAST_TUNNEL_FIELD tunnel_id#define LAST_FLOW_TAG_FIELD tag_id#define LAST_DROP_FIELD size -#define LAST_DROP_FIELD size +#define LAST_COUNTERS_FIELD counters/* Field is the last supported field */ #define FIELDS_NOT_SUPPORTED (filter, field)\
@@ -2844,6 +2844,18 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,if (ret)return ret;break ; +case IB_FLOW_SPEC_ACTION_COUNT : +if (FIELDS_NOT_SUPPORTED (ib_spec->flow_count, +LAST_COUNTERS_FIELD )) +return -EOPNOTSUPP ; + +/* for now support only one counters spec per flow */ +if (action->action &MLX5_FLOW_CONTEXT_ACTION_COUNT ) +return -EINVAL ; + + action->counters = ib_spec->flow_count.counters; + action->action |=MLX5_FLOW_CONTEXT_ACTION_COUNT ; +break ;default :return -EINVAL ; }
@@ -2991,6 +3003,17 @@ static void put_flow_table(struct mlx5_ib_dev *dev, } } +static void counters_clear_description (struct ib_counters *counters) +{ +struct mlx5_ib_mcounters *mcounters =to_mcounters (counters); + +mutex_lock (&mcounters->mcntrs_mutex); +kfree (mcounters->counters_data); + mcounters->counters_data =NULL ; + mcounters->cntrs_max_index =0 ; +mutex_unlock (&mcounters->mcntrs_mutex); +} +static int mlx5_ib_destroy_flow (struct ib_flow *flow_id) {struct mlx5_ib_dev *dev =to_mdev (flow_id->qp->device);
@@ -3010,8 +3033,11 @@ static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)mlx5_del_flow_rules (handler->rule);put_flow_table (dev, handler->prio, true); -mutex_unlock (&dev->flow_db->lock); +if (handler->ibcounters && +atomic_read (&handler->ibcounters->usecnt) ==1 ) +counters_clear_description (handler->ibcounters); +mutex_unlock (&dev->flow_db->lock);kfree (handler);return 0 ;
@@ -3131,22 +3157,128 @@ static void set_underlay_qp(struct mlx5_ib_dev *dev, } } +static int counters_set_description (struct ib_counters *counters, +enum mlx5_ib_counters_type counters_type, +struct mlx5_ib_flow_counters_desc *desc_data, +u32 ncounters) +{ +struct mlx5_ib_mcounters *mcounters =to_mcounters (counters); +u32 cntrs_max_index =0 ; +int i; + +if (counters_type !=MLX5_IB_COUNTERS_FLOW ) +return -EINVAL ; + +/* init the fields for the object */ + mcounters->type = counters_type; + mcounters->ncounters = ncounters; +/* each counter entry have both description and index pair */ +for (i =0 ; i < ncounters; i++) { +if (desc_data[i].description >IB_COUNTER_BYTES ) +return -EINVAL ; + +if (cntrs_max_index <= desc_data[i].index) + cntrs_max_index = desc_data[i].index +1 ; + } + +mutex_lock (&mcounters->mcntrs_mutex); + mcounters->counters_data = desc_data; + mcounters->cntrs_max_index = cntrs_max_index; +mutex_unlock (&mcounters->mcntrs_mutex); + +return 0 ; +} + +#define MAX_COUNTERS_NUM (USHRT_MAX / (sizeof(u32) * 2)) +static int flow_counters_set_data (struct ib_counters *ibcounters, +struct mlx5_ib_create_flow *ucmd) +{ +struct mlx5_ib_mcounters *mcounters =to_mcounters (ibcounters); +struct mlx5_ib_flow_counters_data *cntrs_data =NULL ; +struct mlx5_ib_flow_counters_desc *desc_data =NULL ; +bool hw_hndl = false; +int ret =0 ; + +if (ucmd && ucmd->ncounters_data !=0 ) { + cntrs_data = ucmd->data; +if (cntrs_data->ncounters >MAX_COUNTERS_NUM ) +return -EINVAL ; + + desc_data =kcalloc (cntrs_data->ncounters, +sizeof (*desc_data), +GFP_KERNEL ); +if (!desc_data) +return -ENOMEM ; + +if (copy_from_user (desc_data, +u64_to_user_ptr (cntrs_data->counters_data), +sizeof (*desc_data) * cntrs_data->ncounters)) { + ret = -EFAULT ; + goto free; + } + } + +if (!mcounters->hw_cntrs_hndl) { + mcounters->hw_cntrs_hndl =mlx5_fc_create ( +to_mdev (ibcounters->device)->mdev, false); +if (!mcounters->hw_cntrs_hndl) { + ret = -ENOMEM ; + goto free; + } + hw_hndl = true; + } + +if (desc_data) { +/* counters already bound to at least one flow */ +if (mcounters->cntrs_max_index) { + ret = -EINVAL ; + goto free_hndl; + } + + ret =counters_set_description (ibcounters, +MLX5_IB_COUNTERS_FLOW , + desc_data, + cntrs_data->ncounters); +if (ret) + goto free_hndl; + + }else if (!mcounters->cntrs_max_index) { +/* counters not bound yet, must have udata passed */ + ret = -EINVAL ; + goto free_hndl; + } + +return 0 ; + +free_hndl: +if (hw_hndl) { +mlx5_fc_destroy (to_mdev (ibcounters->device)->mdev, + mcounters->hw_cntrs_hndl); + mcounters->hw_cntrs_hndl =NULL ; + } +free: +kfree (desc_data); +return ret; +} +static struct mlx5_ib_flow_handler *_create_flow_rule (struct mlx5_ib_dev *dev,struct mlx5_ib_flow_prio *ft_prio,const struct ib_flow_attr *flow_attr,struct mlx5_flow_destination *dst, -u32 underlay_qpn) +u32 underlay_qpn, +struct mlx5_ib_create_flow *ucmd) {struct mlx5_flow_table *ft = ft_prio->flow_table;struct mlx5_ib_flow_handler *handler;struct mlx5_flow_act flow_act = {.flow_tag =MLX5_FS_DEFAULT_FLOW_TAG };struct mlx5_flow_spec *spec; -struct mlx5_flow_destination *rule_dst = dst; +struct mlx5_flow_destination dest_arr[2 ] = {}; +struct mlx5_flow_destination *rule_dst = dest_arr;const void *ib_flow = (const void *)flow_attr +sizeof (*flow_attr);unsigned int spec_index;u32 prev_type =0 ;int err =0 ; -int dest_num =1 ; +int dest_num =0 ;bool is_egress = flow_attr->flags &IB_FLOW_ATTR_FLAGS_EGRESS ;if (!is_valid_attr (dev->mdev, flow_attr))
@@ -3160,6 +3292,10 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, }INIT_LIST_HEAD (&handler->list); +if (dst) { +memcpy (&dest_arr[0 ], dst,sizeof (*dst)); + dest_num++; + }for (spec_index =0 ; spec_index < flow_attr->num_of_specs; spec_index++) { err = parse_flow_attr(dev->mdev, spec->match_criteria,
@@ -3196,15 +3332,30 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, goto free; } +if (flow_act.action &MLX5_FLOW_CONTEXT_ACTION_COUNT ) { + err =flow_counters_set_data (flow_act.counters, ucmd); +if (err) + goto free; + + handler->ibcounters = flow_act.counters; + dest_arr[dest_num].type = +MLX5_FLOW_DESTINATION_TYPE_COUNTER ; + dest_arr[dest_num].counter = +to_mcounters (flow_act.counters)->hw_cntrs_hndl; + dest_num++; + } +if (flow_act.action &MLX5_FLOW_CONTEXT_ACTION_DROP ) { - rule_dst =NULL ; - dest_num =0 ; +if (!(flow_act.action &MLX5_FLOW_CONTEXT_ACTION_COUNT )) { + rule_dst =NULL ; + dest_num =0 ; + } }else {if (is_egress) flow_act.action |=MLX5_FLOW_CONTEXT_ACTION_ALLOW ;else flow_act.action |= - dst ?MLX5_FLOW_CONTEXT_ACTION_FWD_DEST : + dest_num ?MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO ; }
@@ -3230,8 +3381,12 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, ft_prio->flow_table = ft; free: -if (err) +if (err && handler) { +if (handler->ibcounters && +atomic_read (&handler->ibcounters->usecnt) ==1 ) +counters_clear_description (handler->ibcounters);kfree (handler); + }kvfree (spec);return err ?ERR_PTR (err) : handler; }
@@ -3241,7 +3396,7 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,const struct ib_flow_attr *flow_attr, struct mlx5_flow_destination *dst) { - return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0); + return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0, NULL); } static struct mlx5_ib_flow_handler *create_dont_trap_rule(struct mlx5_ib_dev *dev,
@@ -3381,12 +3536,43 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,struct mlx5_ib_flow_prio *ft_prio_tx =NULL ;struct mlx5_ib_flow_prio *ft_prio;bool is_egress = flow_attr->flags &IB_FLOW_ATTR_FLAGS_EGRESS ; +struct mlx5_ib_create_flow *ucmd =NULL , ucmd_hdr; +size_t min_ucmd_sz, required_ucmd_sz;int err;int underlay_qpn; -if (udata && - udata->inlen && !ib_is_udata_cleared (udata,0 , udata->inlen)) -return ERR_PTR (-EOPNOTSUPP ); +if (udata && udata->inlen) { + min_ucmd_sz = offsetof(typeof (ucmd_hdr ), reserved) + +sizeof (ucmd_hdr.reserved); +if (udata->inlen < min_ucmd_sz) +return ERR_PTR (-EOPNOTSUPP ); + + err =ib_copy_from_udata (&ucmd_hdr, udata, min_ucmd_sz); +if (err) +return ERR_PTR (err); + +/* currently supports only one counters data */ +if (ucmd_hdr.ncounters_data >1 ) +return ERR_PTR (-EINVAL ); + + required_ucmd_sz = min_ucmd_sz + +sizeof (struct mlx5_ib_flow_counters_data ) * + ucmd_hdr.ncounters_data; +if (udata->inlen > required_ucmd_sz && + !ib_is_udata_cleared (udata, required_ucmd_sz, + udata->inlen - required_ucmd_sz)) +return ERR_PTR (-EOPNOTSUPP ); + + ucmd =kzalloc (required_ucmd_sz,GFP_KERNEL ); +if (!ucmd) +return ERR_PTR (-ENOMEM ); + + err =ib_copy_from_udata (ucmd, udata, required_ucmd_sz); +if (err) { +kfree (ucmd); +return ERR_PTR (err); + } + }if (flow_attr->priority >MLX5_IB_FLOW_LAST_PRIO )return ERR_PTR (-ENOMEM );
@@ -3441,7 +3627,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, underlay_qpn = (mqp->flags &MLX5_IB_QP_UNDERLAY ) ? mqp->underlay_qpn :0 ; handler =_create_flow_rule (dev, ft_prio, flow_attr, - dst, underlay_qpn); + dst, underlay_qpn, ucmd); } }else if (flow_attr->type ==IB_FLOW_ATTR_ALL_DEFAULT || flow_attr->type ==IB_FLOW_ATTR_MC_DEFAULT ) {
@@ -3462,6 +3648,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,mutex_unlock (&dev->flow_db->lock);kfree (dst); +kfree (ucmd);return &handler->ibflow;
@@ -3472,6 +3659,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, unlock:mutex_unlock (&dev->flow_db->lock);kfree (dst); +kfree (ucmd);kfree (handler);return ERR_PTR (err); }
@@ -5136,6 +5324,11 @@ static int mlx5_ib_destroy_counters(struct ib_counters *counters) {struct mlx5_ib_mcounters *mcounters =to_mcounters (counters); +counters_clear_description (counters); +if (mcounters->hw_cntrs_hndl) +mlx5_fc_destroy (to_mdev (counters->device)->mdev, + mcounters->hw_cntrs_hndl); +kfree (mcounters);return 0 ;
@@ -5150,6 +5343,8 @@ static struct ib_counters *mlx5_ib_create_counters(struct ib_device *device,if (!mcounters)return ERR_PTR (-ENOMEM ); +mutex_init (&mcounters->mcntrs_mutex); +return &mcounters->ibcntrs; }
drivers/infiniband/hw/mlx5/mlx5_ib.h +15 -0
@@ -175,6 +175,7 @@ struct mlx5_ib_flow_handler {struct ib_flow ibflow;struct mlx5_ib_flow_prio *prio;struct mlx5_flow_handle *rule; +struct ib_counters *ibcounters; };struct mlx5_ib_flow_db {
@@ -813,8 +814,22 @@ struct mlx5_memic {DECLARE_BITMAP (memic_alloc_pages,MLX5_MAX_MEMIC_PAGES ); }; +enum mlx5_ib_counters_type { +MLX5_IB_COUNTERS_FLOW , +}; +struct mlx5_ib_mcounters {struct ib_counters ibcntrs; +enum mlx5_ib_counters_type type; +void *hw_cntrs_hndl; +/* max index set as part of create_flow */ +u32 cntrs_max_index; +/* number of counters data entries (<description,index> pair) */ +u32 ncounters; +/* counters data array for descriptions and indexes */ +struct mlx5_ib_flow_counters_desc *counters_data; +/* protects access to mcounters internal data */ +struct mutex mcntrs_mutex; }; static inline struct mlx5_ib_mcounters *
include/linux/mlx5/fs.h +1 -0
@@ -160,6 +160,7 @@ struct mlx5_flow_act {u32 modify_id;uintptr_t esp_id;struct mlx5_fs_vlan vlan; +struct ib_counters *counters; };#define MLX5_DECLARE_FLOW_ACT (name) \
include/uapi/rdma/mlx5-abi.h +24 -0
@@ -36,6 +36,7 @@#include <linux/types.h> #include <linux/if_ether.h> /* For ETH_ALEN. */ +#include <rdma/ib_user_ioctl_verbs.h> enum {MLX5_QP_FLAG_SIGNATURE =1 <<0 ,
@@ -443,4 +444,27 @@ enum {enum {MLX5_IB_CLOCK_INFO_V1 =0 , }; + +struct mlx5_ib_flow_counters_desc { +__u32 description; +__u32 index; +}; + +struct mlx5_ib_flow_counters_data { + RDMA_UAPI_PTR(struct mlx5_ib_flow_counters_desc *, counters_data); +__u32 ncounters; +__u32 reserved; +}; + +struct mlx5_ib_create_flow { +__u32 ncounters_data; +__u32 reserved; +/* +* Following are counters data based on ncounters_data, each +* entry in the data[] should match a corresponding counter object +* that was pointed by a counters spec upon the flow creation +*/ +struct mlx5_ib_flow_counters_data data[]; +}; +#endif /* MLX5_ABI_USER_H */
Signature · 1 line
2.14.3
PATCH v3 13/14 IB/mlx5: Add flow counters read support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
Implements the flow counters read wrapper.
--- drivers/infiniband/hw/mlx5/main.c | 15 +++++++++++++++ drivers/infiniband/hw/mlx5/mlx5_ib.h | 13 ++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)
drivers/infiniband/hw/mlx5/main.c +15 -0
@@ -3157,6 +3157,19 @@ static void set_underlay_qp(struct mlx5_ib_dev *dev, } } +static int read_flow_counters (struct ib_device *ibdev, +struct mlx5_read_counters_attr *read_attr) +{ +struct mlx5_fc *fc = read_attr->hw_cntrs_hndl; +struct mlx5_ib_dev *dev =to_mdev (ibdev); + +return mlx5_fc_query (dev->mdev, fc, + &read_attr->out[IB_COUNTER_PACKETS ], + &read_attr->out[IB_COUNTER_BYTES ]); +} + +/* flow counters currently expose two counters packets and bytes */ +#define FLOW_COUNTERS_NUM 2 static int counters_set_description(struct ib_counters *counters, enum mlx5_ib_counters_type counters_type, struct mlx5_ib_flow_counters_desc *desc_data,
@@ -3171,6 +3184,8 @@ static int counters_set_description(struct ib_counters *counters,/* init the fields for the object */ mcounters->type = counters_type; + mcounters->read_counters = read_flow_counters; + mcounters->counters_num =FLOW_COUNTERS_NUM ; mcounters->ncounters = ncounters;/* each counter entry have both description and index pair */ for (i =0 ; i < ncounters; i++) {
drivers/infiniband/hw/mlx5/mlx5_ib.h +12 -1
@@ -814,6 +814,12 @@ struct mlx5_memic {DECLARE_BITMAP (memic_alloc_pages,MLX5_MAX_MEMIC_PAGES ); }; +struct mlx5_read_counters_attr { +struct mlx5_fc *hw_cntrs_hndl; +u64 *out; +u32 flags; +}; +enum mlx5_ib_counters_type {MLX5_IB_COUNTERS_FLOW , };
@@ -821,7 +827,12 @@ enum mlx5_ib_counters_type {struct mlx5_ib_mcounters {struct ib_counters ibcntrs;enum mlx5_ib_counters_type type; -void *hw_cntrs_hndl; +/* number of counters supported for this counters type */ +u32 counters_num; +struct mlx5_fc *hw_cntrs_hndl; +/* read function for this counters type */ +int (*read_counters)(struct ib_device *ibdev, +struct mlx5_read_counters_attr *read_attr);/* max index set as part of create_flow */ u32 cntrs_max_index;/* number of counters data entries (<description,index> pair) */
Signature · 1 line
2.14.3
PATCH v3 14/14 IB/mlx5: Add counters read support
In reply to Leon RomanovskyFrom: Raed Salem <[email protected]>
This patch implements the uverbs counters read API, it will use the specific read counters function to the given type to accomplish its task.
--- drivers/infiniband/hw/mlx5/main.c | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
drivers/infiniband/hw/mlx5/main.c +43 -0
@@ -5335,6 +5335,48 @@ static void depopulate_specs_root(struct mlx5_ib_dev *dev)uverbs_free_spec_tree (dev->ib_dev.specs_root); } +static int mlx5_ib_read_counters (struct ib_counters *counters, +struct ib_counters_read_attr *read_attr, +struct uverbs_attr_bundle *attrs) +{ +struct mlx5_ib_mcounters *mcounters =to_mcounters (counters); +struct mlx5_read_counters_attr mread_attr = {}; +struct mlx5_ib_flow_counters_desc *desc; +int ret, i; + +mutex_lock (&mcounters->mcntrs_mutex); +if (mcounters->cntrs_max_index > read_attr->ncounters) { + ret = -EINVAL ; + goto err_bound; + } + + mread_attr.out =kcalloc (mcounters->counters_num,sizeof (u64), +GFP_KERNEL ); +if (!mread_attr.out) { + ret = -ENOMEM ; + goto err_bound; + } + + mread_attr.hw_cntrs_hndl = mcounters->hw_cntrs_hndl; + mread_attr.flags = read_attr->flags; + ret = mcounters->read_counters (counters->device, &mread_attr); +if (ret) + goto err_read; + +/* do the pass over the counters data array to assign according to the +* descriptions and indexing pairs +*/ + desc = mcounters->counters_data; +for (i =0 ; i < mcounters->ncounters; i++) + read_attr->counters_buff[desc[i].index] += mread_attr.out[desc[i].description]; + +err_read: +kfree (mread_attr.out); +err_bound: +mutex_unlock (&mcounters->mcntrs_mutex); +return ret; +} +static int mlx5_ib_destroy_counters (struct ib_counters *counters) {struct mlx5_ib_mcounters *mcounters =to_mcounters (counters);
@@ -5608,6 +5650,7 @@ int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev) dev->ib_dev.driver_id =RDMA_DRIVER_MLX5 ; dev->ib_dev.create_counters = mlx5_ib_create_counters; dev->ib_dev.destroy_counters = mlx5_ib_destroy_counters; + dev->ib_dev.read_counters = mlx5_ib_read_counters; err =init_node_data (dev);if (err)
Signature · 1 line
2.14.3
Quoted 31 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Changelog:
v2->v3:
* Change functionmlx5_fc_querysignature to hide the details of internal core driver structmlx5_fc
* Add commen to data[] field at structmlx5_ib_flow_counters_data(mlx5-abi.h)
* Use array of structmlx5_ib_flow_counters_descto clarify the outputv1->v2:
* Removed conversion from struct mlx5_fc* to void*
* Fixed one place with double space in it
* Balanced release of hardware handler in case of counters allocation failure
* Added Tested-by
* Minimize time spent holding mutex lock
* Fixed deadlock caused by nested lock in error path
* Protect from handler pointer derefence in the error pathsNot changed:
mlx5-abi.h
v0->v1:
* Decouple from DevX submission
* Useuverbs_attr_get_objat counters read method
* Added define for max read buffer size (MAX_COUNTERS_BUFF_SIZE)
* Removed the structmlx5_ib_flow_counterbasic_flow_cntsand the related structs used, used define instead
* Took Matan's patch from DevX
*uverbs_free_countersremoved void* casting
* Added check to bound ncounters value (added define
* Changed user supplied data buffer structure to be array of struct <desc,index> pair (applied this change to user space also)
Quoted 5 lines
Not changed:
* UAPI files
* Addition of uhw to flowThanks
The corresponding rdma-core PR [1] was updated to match this V3 series.
[1] https://github.com/linux-rdma/rdma-core/pull/330
Yishai
Quoted 86 lines
----------------------------------------------------------------------
From Raed:This series comes to allow user space applications to monitor real time traffic activity and events of the verbs objects it manages, e.g.:
ibv_qp,ibv_wq,ibv_flow.This API enables generic counters creation and define mapping to association with a verbs object, current mlx5 driver using this API for flow counters.
With this API, an application can monitor the entire life cycle of object activity, defined here as a static counters attachment. This API also allows dynamic counters monitoring of measurement points for a partial period in the verbs object life cycle.
In addition it presents the implementation of the generic counters interface.
This will be achieved by extending flow creation by adding a new flow count specification type which allows the user to associate a previously created flow counters using the generic verbs counters interface to the created flow, once associated the user could read statistics by using the read function of the generic counters interface.
The API includes:
1. create and destroyed API of a new counters objects
2. read the counters values from HWNote:
Attaching API to allow application to define the measurement points per objects is a user space only API and this data is passed to kernel when the counted object (e.g. flow) is created with the counters object.Thanks
Matan Barak (2):
IB/uverbs: Add anib_uobjectgetter toioctl()infrastructure IB/core: Support passing uhw forcreate_flowOr Gerlitz (1):
net/mlx5: Use flow counter pointer as input to the query functionRaed Salem (11):
net/mlx5: Export flow counter related API IB/core: Introduce counters object and its create/destroy IB/uverbs: Add create/destroy counters support IB/core: Introduce counters read verb IB/uverbs: Add read counters support
IB/core: Add support for flow counters IB/uverbs: Add support for flow counters IB/mlx5: Add counters create and destroy support IB/mlx5: Add flow counters binding support IB/mlx5: Add flow counters read support IB/mlx5: Add counters read supportdrivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/uverbs.h | 2 + drivers/infiniband/core/uverbs_cmd.c | 88 +++++- drivers/infiniband/core/uverbs_std_types.c | 3 +- .../infiniband/core/uverbs_std_types_counters.c | 157 +++++++++++ drivers/infiniband/core/uverbs_std_types_cq.c | 23 +- .../infiniband/core/uverbs_std_types_flow_action.c | 4 +- drivers/infiniband/core/verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 6 +- drivers/infiniband/hw/mlx5/main.c | 305 ++++++++++++++++++++- drivers/infiniband/hw/mlx5/mlx5_ib.h | 36 +++ drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 15 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.h | 2 - .../net/ethernet/mellanox/mlx5/core/fs_counters.c | 7 +- include/linux/mlx5/fs.h | 4 + include/rdma/ib_verbs.h | 43 ++- include/rdma/uverbs_ioctl.h | 11 + include/uapi/rdma/ib_user_ioctl_cmds.h | 21 ++ include/uapi/rdma/ib_user_verbs.h | 13 + include/uapi/rdma/mlx5-abi.h | 24 ++ 20 files changed, 712 insertions(+), 56 deletions(-)create mode 100644
drivers/infiniband/core/uverbs_std_types_counters.c--
2.14.3--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 16 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Changelog:
v2->v3:
* Change functionmlx5_fc_querysignature to hide the details of internal core driver structmlx5_fc
* Add commen to data[] field at structmlx5_ib_flow_counters_data(mlx5-abi.h)
* Use array of structmlx5_ib_flow_counters_descto clarify the outputv1->v2:
* Removed conversion from struct mlx5_fc* to void*
* Fixed one place with double space in it
* Balanced release of hardware handler in case of counters allocation failure
* Added Tested-by
* Minimize time spent holding mutex lock
* Fixed deadlock caused by nested lock in error path
* Protect from handler pointer derefence in the error paths
Okay,
I've revised some of the commit messages, fixed the two bad check-patch warnings, and fixed the patch ordering..
https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-counters
Please send a PR with the mlx-core bits and above commits.
Thanks,
Jason
Quoted 20 lines · Jason Gunthorpe
Quoted 16 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Changelog:
v2->v3:
* Change functionmlx5_fc_querysignature to hide the details of internal core driver structmlx5_fc
* Add commen to data[] field at structmlx5_ib_flow_counters_data(mlx5-abi.h)
* Use array of structmlx5_ib_flow_counters_descto clarify the outputv1->v2:
* Removed conversion from struct mlx5_fc* to void*
* Fixed one place with double space in it
* Balanced release of hardware handler in case of counters allocation failure
* Added Tested-by
* Minimize time spent holding mutex lock
* Fixed deadlock caused by nested lock in error path
* Protect from handler pointer derefence in the error pathsOkay,
Quoted 8 lines
Acked-by Jason Gunthorpe <[email protected]>I've revised some of the commit messages, fixed the two bad check-patch warnings, and fixed the patch ordering..
https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-counters
Please send a PR with the mlx-core bits and above commits.
Hi,
I applied two mlx5-next commits to the relevant tree:
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/commit/?h=mlx5-next&id=930821e39d0a5f91ed58fea1692afe04f0fe0e1f
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/commit/?h=mlx5-next&id=5f9bf63ae80c4d0e5e986b6c1280bf8174978545
In first commit, I dropped the words "as used to be", per-Saeed's request.
The proper signed tag for whole the series is: verbs_flow_countersgit://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.git tags/verbs_flow_counters
Thanks
Quoted 3 lines
Thanks,
Jason
Quoted 32 lines · Leon Romanovsky
Quoted 20 lines · Jason Gunthorpe
Quoted 16 lines · Leon Romanovsky
From: Leon Romanovsky <[email protected]>
Changelog:
v2->v3:
* Change functionmlx5_fc_querysignature to hide the details of internal core driver structmlx5_fc
* Add commen to data[] field at structmlx5_ib_flow_counters_data(mlx5-abi.h)
* Use array of structmlx5_ib_flow_counters_descto clarify the outputv1->v2:
* Removed conversion from struct mlx5_fc* to void*
* Fixed one place with double space in it
* Balanced release of hardware handler in case of counters allocation failure
* Added Tested-by
* Minimize time spent holding mutex lock
* Fixed deadlock caused by nested lock in error path
* Protect from handler pointer derefence in the error pathsOkay,
Quoted 8 lines
Acked-by Jason Gunthorpe <[email protected]>I've revised some of the commit messages, fixed the two bad check-patch warnings, and fixed the patch ordering..
https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-counters
Please send a PR with the mlx-core bits and above commits.
Hi,
Quoted 8 lines
I applied two mlx5-next commits to the relevant tree:
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/commit/?h=mlx5-next&id=930821e39d0a5f91ed58fea1692afe04f0fe0e1f
https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux.git/commit/?h=mlx5-next&id=5f9bf63ae80c4d0e5e986b6c1280bf8174978545In first commit, I dropped the words "as used to be", per-Saeed's request.
The proper signed tag for whole the series is:
verbs_flow_countersgit://git.kernel.org/pub/scm/linux/kernel/git/leon/linux-rdma.gittags/verbs_flow_counters
Okay pulled, thanks
Jason