Skip to contentSkip to conversation

RDMA resource tracking

PATCH Superseded Leon Romanovsky 6 participants 28 messages Jan 11, 2018 – Jan 17, 2018 16 messages not in the archive

Subsystems (7)

v3 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v3 cover RDMA resource tracking

Changelog:
v2->v3:
* Added support of PID namespaces.
* Rewrote rdma_restraack_add function to ensure that it won't appear in lists before it is valid.
* Replace pid/task name caching logic to use task_struct instead.
* Removed report of name of task's for user space objects. Users are expected to read it through /proc/PID/comm.
v1->v2:
* Rebased on latest rdma/for-next
* Replaced mutex lock which protect linked lists to be RW semaphore. It has no impact on current implementation, because there is only one reader (nldev) and it is serialized. However better to be prepared for multiple readers from the beginning.
* Added reinitialization next QP entry logic to ensure that it exists and didn't vanish during fill_req_qp() work.
v0->v1:
* Dropped RFC
* Separated to thre series, one for for-rc, and two for-next.

-------
The original goal of this series was to allow ability to view connection (QP) information about running processes, however I used this opportunity and created common infrastructure to track and report various resources. The report part is implemented in netlink (nldev), but smart ULPs can now create advanced usage models based on device utilization.

The current implementation relies on one lock per-object per-device, so creation/destroying of various objects (CQ, PD, e.t.c) on various or the same devices doesn't interfere each with another.

The data protection is performed with SRCU and its reader-writer model ensures that resource won't be destroyed till readers will finish their work.

Possible future work will include:
* Reducing number of locks in RDMA, because of SRCU.
* Converting CMA to be based completely on resource tracking.
* Addition of other objects and extending current to give full and detailed state of the RDMA kernel stack.
* Replacing synchronize_srcu with call_srcu to make destroy flow non-blocking.
* Provide reliable device reset flow, preserving resource creation ordering.

Thanks
---------------------------------------

Cc Steve Wise <[email protected]>

Leon Romanovsky (7):
RDMA/restrack: Add general infrastructure to track RDMA resources RDMA/core: Add helper function to create named QPs
RDMA: Annotate create QP callers
RDMA/core: Add resource tracking for create and destroy CQs RDMA/core: Add resource tracking for create and destroy PDs RDMA/nldev: Provide global resource utilization RDMA/nldev: Provide detailed QP information

 drivers/infiniband/core/Makefile           |   2 +-
 drivers/infiniband/core/cma.c              |   1 +
 drivers/infiniband/core/core_priv.h        |  20 ++
 drivers/infiniband/core/cq.c               |   3 +
 drivers/infiniband/core/device.c           |   7 +
 drivers/infiniband/core/mad.c              |   1 +
 drivers/infiniband/core/nldev.c            | 405 +++++++++++++++++++++++++++++
 drivers/infiniband/core/restrack.c         | 182 +++++++++++++
 drivers/infiniband/core/uverbs_cmd.c       |   5 +-
 drivers/infiniband/core/uverbs_std_types.c |   2 +
 drivers/infiniband/core/verbs.c            |   8 +-
 drivers/infiniband/hw/mlx4/mad.c           |   1 +
 drivers/infiniband/hw/mlx4/qp.c            |   1 +
 drivers/infiniband/hw/mlx5/gsi.c           |   2 +
 drivers/infiniband/ulp/ipoib/ipoib_cm.c    |   4 +-
 drivers/infiniband/ulp/ipoib/ipoib_verbs.c |   1 +
 drivers/infiniband/ulp/srp/ib_srp.c        |   1 +
 drivers/infiniband/ulp/srpt/ib_srpt.c      |   1 +
 include/rdma/ib_verbs.h                    |  23 +-
 include/rdma/restrack.h                    | 138 ++++++++++
 include/uapi/rdma/rdma_netlink.h           |  56 ++++
 net/smc/smc_ib.c                           |   1 +
 22 files changed, 858 insertions(+), 7 deletions(-)
 create mode 100644 drivers/infiniband/core/restrack.c
 create mode 100644 include/rdma/restrack.h

--
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

#2 lore raw

PATCH v3 1/7 RDMA/restrack: Add general infrastructure to track RDMA resources

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

The RDMA subsystem has very strict set of objects to work on it, but it completely lacks tracking facilities and no visibility of resource utilization.

The following patch adds such infrastructure to keep track of RDMA resources to help with debugging of user space applications. The primary user of this infrastructure is RDMA nldev netlink (following patches), but it is not limited too.

At this stage, the main three objects (PD, CQ and QP) are added, and more will be added later.

There are four new functions in use by RDMA/core:

 * rdma_restrack_init(...)   - initializes restrack database
 * rdma_restrack_clean(...)  - cleans restrack database
 * rdma_restrack_add(...)    - adds object to be tracked
 * rdma_restrack_del(...)    - removes object from tracking

3 functions and one iterator visible to kernel users:
* rdma_restrack_count(...) - returns number of allocated objects of specific type
* rdma_restrack_lock(...) - Lock primitive to protect access to list of resources
* rdma_restrack_unlock(...)- Unlock primitive to protect access to list of resources
* for_each_res_safe(...) - iterates over all relevant objects in
the restrack database.

---
 drivers/infiniband/core/Makefile    |   2 +-
 drivers/infiniband/core/core_priv.h |   1 +
 drivers/infiniband/core/device.c    |   7 ++
 drivers/infiniband/core/restrack.c  | 182 ++++++++++++++++++++++++++++++++++++
 include/rdma/ib_verbs.h             |  17 +++-
 include/rdma/restrack.h             | 138 +++++++++++++++++++++++++++
 6 files changed, 345 insertions(+), 2 deletions(-)
 create mode 100644 drivers/infiniband/core/restrack.c
 create mode 100644 include/rdma/restrack.h
drivers/infiniband/core/Makefile +1 -1
index 504b926552c6..f69833db0a32 100644
@@ -12,7 +12,7 @@ ib_core-y :=			packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
 				device.o fmr_pool.o cache.o netlink.o \
 				roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
 				multicast.o mad.o smi.o agent.o mad_rmpp.o \
-				security.o nldev.o
+				security.o nldev.o restrack.o
 
 ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
 ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o
drivers/infiniband/core/core_priv.h +1 -0
index aef9aa0ac0e6..2b1372da708a 100644
@@ -40,6 +40,7 @@
 #include <rdma/ib_verbs.h>
 #include <rdma/opa_addr.h>
 #include <rdma/ib_mad.h>
+#include <rdma/restrack.h>
 #include "mad_priv.h"
 
 /* Total number of ports combined across all struct ib_devices's */
drivers/infiniband/core/device.c +7 -0
index 2826e06311a5..c3e389f8c99a 100644
@@ -263,6 +263,11 @@ struct ib_device *ib_alloc_device(size_t size)
 	if (!device)
 		return NULL;
 
+	if (rdma_restrack_init(&device->res)) {
+		kfree(device);
+		return NULL;
+	}
+
 	device->dev.class = &ib_class;
 	device_initialize(&device->dev);
 
@@ -596,6 +601,8 @@ void ib_unregister_device(struct ib_device *device)
 	}
 	up_read(&lists_rwsem);
 
+	rdma_restrack_clean(&device->res);
+
 	ib_device_unregister_rdmacg(device);
 	ib_device_unregister_sysfs(device);
 
drivers/infiniband/core/restrack.c new file +182 -0

182 lines not on this page · raw message

include/rdma/ib_verbs.h +16 -1
index f25c03687ee9..271265cd7c1a 100644
@@ -63,6 +63,7 @@
 #include <linux/uaccess.h>
 #include <linux/cgroup_rdma.h>
 #include <uapi/rdma/ib_user_verbs.h>
+#include <rdma/restrack.h>
 
 #define IB_FW_VERSION_NAME_MAX	ETHTOOL_FWVERS_LEN
 
@@ -1527,9 +1528,10 @@ struct ib_pd {
 	u32			unsafe_global_rkey;
 
 	/*
-	 * Implementation details of the RDMA core, don't use in drivers:
+	 * Implementation details of the RDMA core, don't use in the drivers
 	 */
 	struct ib_mr	       *__internal_mr;
+	struct rdma_restrack_entry res;
 };
 
 struct ib_xrcd {
@@ -1570,6 +1572,10 @@ struct ib_cq {
 		struct irq_poll		iop;
 		struct work_struct	work;
 	};
+	/*
+	 * Internal to RDMA/core, don't use in the drivers
+	 */
+	struct rdma_restrack_entry res;
 };
 
 struct ib_srq {
@@ -1746,6 +1752,11 @@ struct ib_qp {
 	struct ib_rwq_ind_table *rwq_ind_tbl;
 	struct ib_qp_security  *qp_sec;
 	u8			port;
+
+	/*
+	 * Internal to RDMA/core, don't use in the drivers
+	 */
+	struct rdma_restrack_entry     res;
 };
 
 struct ib_mr {
@@ -2352,6 +2363,10 @@ struct ib_device {
 #endif
 
 	u32                          index;
+	/*
+	 * Implementation details of the RDMA core, don't use in the drivers
+	 */
+	struct rdma_restrack_root     res;
 
 	/**
 	 * The following mandatory functions are used only at device
include/rdma/restrack.h new file +138 -0

138 lines not on this page · raw message

Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-2-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#4 lore raw

RE: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

Quoted 30 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

The RDMA subsystem has very strict set of objects to work on it, but it completely lacks tracking facilities and no visibility of resource utilization.

The following patch adds such infrastructure to keep track of RDMA resources to help with debugging of user space applications. The primary user of this infrastructure is RDMA nldev netlink (following patches), but it is not limited too.

At this stage, the main three objects (PD, CQ and QP) are added, and more will be added later.

There are four new functions in use by RDMA/core:

 * rdma_restrack_init(...)   - initializes restrack database
 * rdma_restrack_clean(...)  - cleans restrack database
 * rdma_restrack_add(...)    - adds object to be tracked
 * rdma_restrack_del(...)    - removes object from tracking

3 functions and one iterator visible to kernel users:
* rdma_restrack_count(...) - returns number of allocated objects of specific type
* rdma_restrack_lock(...) - Lock primitive to protect access to list of resources
* rdma_restrack_unlock(...)- Unlock primitive to protect access to list of resources
* for_each_res_safe(...) - iterates over all relevant objects in
the restrack database.

Quoted 2 lines

--
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

#5 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

In reply to a message not in the archive

T24gVGh1LCAyMDE4LTAxLTExIGF0IDE3OjMxICswMjAwLCBMZW9uIFJvbWFub3Zza3kgd3JvdGU6 DQo+ICtzdHJ1Y3QgcmRtYV9yZXN0cmFja19lbnRyeSB7DQo+ICsgICAgICAgc3RydWN0IGxpc3Rf aGVhZCAgICAgICAgbGlzdDsNCj4gKw0KPiArICAgICAgIC8qDQo+ICsgICAgICAgICogVGhlIGVu dHJpZXMgYXJlIGZpbGxlZCBkdXJpbmcgcmRtYV9yZXN0cmFja19hZGQsDQo+ICsgICAgICAgICog Y2FuIGJlIGF0dGVtcHRlZCB0byBiZSBmcmVlIGR1cmluZyByZG1hX3Jlc3RyYWNrX2RlbC4NCj4g KyAgICAgICAgKg0KPiArICAgICAgICAqIEFzIGFuIGV4YW1wbGUgZm9yIHRoYXQsIHNlZSBtbHg1 IFFQcyB3aXRoIHR5cGUgTUxYNV9JQl9RUFRfSFdfR1NJDQo+ICsgICAgICAgICovDQo+ICsgICAg ICAgYm9vbCAgICAgICAgICAgICAgICAgICAgdmFsaWQ7DQo+ICsNCj4gKyAgICAgICAvKg0KPiAr ICAgICAgICAqIFNsZWVwYWJhbGUgUkNVIHRvIHByb3RlY3Qgb2JqZWN0IGRhdGEuDQo+ICsgICAg ICAgICovDQo+ICsgICAgICAgc3RydWN0IHNyY3Vfc3RydWN0ICAgICAgc3JjdTsNCj4gKw0KPiAr ICAgICAgIHN0cnVjdCB0YXNrX3N0cnVjdCAgICAgICp0YXNrOw0KPiArICAgICAgIGNoYXIgICAg ICAgICAgICAgICAgICAgICp0YXNrX2NvbW07DQo+ICt9Ow0KDQpQbGVhc2UgdXNlIHRoZSBrZXJu ZWwtZG9jIHN5bnRheCB0byBkb2N1bWVudCB0aGUgbWVhbmluZyBvZiB0aGUgbmFtZXMgb2YgdGhl DQpmaWVsZHMgaW4gdGhpcyBzdHJ1Y3R1cmUuIEl0IGlzIGUuZy4gbm9udHJpdmlhbCB0byBndWVz cyB3aGF0ICJ0YXNrX2NvbW0iIHN0YW5kcw0KZm9yLiBUaGUgcHJlc2Vuc2Ugb2YgYSB0YXNrX3N0 cnVjdCBwb2ludGVyIGlzIGFsc28gbm9udHJpdmlhbC4NCg0KUFM6IEkgdGhpbmsgdGhlIHNwZWxs aW5nIG9mICJTbGVlcGFiYWxlIiBzaG91bGQgYmUgZml4ZWQuDQoNClRoYW5rcywNCg0KQmFydC4= --
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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#7 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

Quoted 16 lines · Bart Van Assche
Quoted 15 lines · Leon Romanovsky
include/rdma/restrack.h new file +15 -0
+struct rdma_restrack_entry {
+       struct list_head        list;
+
+       /*
+        * The entries are filled during rdma_restrack_add,
+        * can be attempted to be free during rdma_restrack_del.
+        *
+        * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
+        */
+       bool                    valid;
+
+       /*
+        * Sleepabale RCU to protect object data.
+        */
+       struct srcu_struct      srcu;
Quoted 8 lines

include/rdma/restrack.h line 90

Quoted 4 lines
include/rdma/restrack.h new file +4 -0
+
+       struct task_struct      *task;
+       char                    *task_comm;
+};

Please use the kernel-doc syntax to document the meaning of the names of the fields in this structure. It is e.g. nontrivial to guess what "task_comm" stands for. The presense of a task_struct pointer is also nontrivial.

And task_comm doesn't seem like a great name anymore, and should be const char *, right ?

Jason
--
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

A message that is not in the archive (sent off-list or not yet received): 20180111195535.GI30208-VPRAkNaXOzVWk0Htik3J/[email protected]

#9 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

Quoted 26 lines · Jason Gunthorpe
Quoted 16 lines · Bart Van Assche
Quoted 15 lines · Leon Romanovsky
include/rdma/restrack.h new file +15 -0
+struct rdma_restrack_entry {
+       struct list_head        list;
+
+       /*
+        * The entries are filled during rdma_restrack_add,
+        * can be attempted to be free during rdma_restrack_del.
+        *
+        * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
+        */
+       bool                    valid;
+
+       /*
+        * Sleepabale RCU to protect object data.
+        */
+       struct srcu_struct      srcu;
Quoted 8 lines

include/rdma/restrack.h line 90

Quoted 4 lines
include/rdma/restrack.h new file +4 -0
+
+       struct task_struct      *task;
+       char                    *task_comm;
+};

Please use the kernel-doc syntax to document the meaning of the names of the fields in this structure. It is e.g. nontrivial to guess what "task_comm" stands for. The presense of a task_struct pointer is also nontrivial.

Quoted 2 lines

And task_comm doesn't seem like a great name anymore, and should be const char *, right ?

No problem, what will be great "name" now? "const char *name"?

Quoted 6 lines

Jason
--
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

A message that is not in the archive (sent off-list or not yet received): 20180112061924.GF15760-U/[email protected]

#11 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

Quoted 27 lines · Leon Romanovsky
Quoted 26 lines · Jason Gunthorpe
Quoted 24 lines · Bart Van Assche
Quoted 9 lines · Leon Romanovsky
(quoted diff) +9 -0
+struct rdma_restrack_entry {
+       struct list_head        list;
+
+       /*
+        * The entries are filled during rdma_restrack_add,
+        * can be attempted to be free during rdma_restrack_del.
+        *
+        * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
+        */

Review

Quoted 10 lines
(quoted diff) +10 -0
+       bool                    valid;
+
+       /*
+        * Sleepabale RCU to protect object data.
+        */
+       struct srcu_struct      srcu;
+
+       struct task_struct      *task;
+       char                    *task_comm;
+};

Please use the kernel-doc syntax to document the meaning of the names of the fields in this structure. It is e.g. nontrivial to guess what "task_comm" stands for. The presense of a task_struct pointer is also nontrivial.

Quoted 4 lines
Quoted 2 lines

And task_comm doesn't seem like a great name anymore, and should be const char *, right ?

No problem, what will be great "name" now? "const char *name"?

I haven't looked closely yet, but is is the kernel name for the object right? So kern_name? And same remark about the netlink attribute name as well.

I'm also uncertain that _ib_create_qp is a good idea, and I really dislike the _ for a public API.

Do you propose to add a kernel name to every kernel object we add restrack to?

It feels simpler to give a name to alloc_pd and use that name as the kernel name for every object created under it? Or is there a reason to have a per object name?

Jason

--
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

A message that is not in the archive (sent off-list or not yet received): 20180114212613.GD9088-uk2M96/[email protected]

#13 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

Quoted 28 lines · Jason Gunthorpe
Quoted 27 lines · Leon Romanovsky
Quoted 26 lines · Jason Gunthorpe
Quoted 24 lines · Bart Van Assche
Quoted 9 lines · Leon Romanovsky
(quoted diff) +9 -0
+struct rdma_restrack_entry {
+       struct list_head        list;
+
+       /*
+        * The entries are filled during rdma_restrack_add,
+        * can be attempted to be free during rdma_restrack_del.
+        *
+        * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
+        */

Review

Quoted 10 lines
(quoted diff) +10 -0
+       bool                    valid;
+
+       /*
+        * Sleepabale RCU to protect object data.
+        */
+       struct srcu_struct      srcu;
+
+       struct task_struct      *task;
+       char                    *task_comm;
+};

Please use the kernel-doc syntax to document the meaning of the names of the fields in this structure. It is e.g. nontrivial to guess what "task_comm" stands for. The presense of a task_struct pointer is also nontrivial.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

And task_comm doesn't seem like a great name anymore, and should be const char *, right ?

No problem, what will be great "name" now? "const char *name"?

I haven't looked closely yet, but is is the kernel name for the object right? So kern_name? And same remark about the netlink attribute name as well.

No problem

Quoted 10 lines

I'm also uncertain that _ib_create_qp is a good idea, and I really dislike the _ for a public API.

Do you propose to add a kernel name to every kernel object we add restrack to?

It feels simpler to give a name to alloc_pd and use that name as the kernel name for every object created under it? Or is there a reason to have a per object name?

Not really.

Quoted 3 lines

Jason

#14 lore raw

Re: [PATCH rdma-next v3 1/7] RDMA/restrack: Add general infrastructure to track RDMA resources

In reply to a message not in the archive
Quoted 25 lines · Bart Van Assche
Quoted 9 lines · Leon Romanovsky
include/rdma/restrack.h new file +9 -0
+struct rdma_restrack_entry {
+       struct list_head        list;
+
+       /*
+        * The entries are filled during rdma_restrack_add,
+        * can be attempted to be free during rdma_restrack_del.
+        *
+        * As an example for that, see mlx5 QPs with type MLX5_IB_QPT_HW_GSI
+        */

include/rdma/restrack.h line 90

Quoted 10 lines
include/rdma/restrack.h new file +10 -0
+       bool                    valid;
+
+       /*
+        * Sleepabale RCU to protect object data.
+        */
+       struct srcu_struct      srcu;
+
+       struct task_struct      *task;
+       char                    *task_comm;
+};

Please use the kernel-doc syntax to document the meaning of the names of the fields in this structure. It is e.g. nontrivial to guess what "task_comm" stands for. The presense of a task_struct pointer is also nontrivial.

Quoted 1 line

PS: I think the spelling of "Sleepabale" should be fixed.

I'll fix and resend.

Quoted 4 lines

Thanks,

Bart.

#15 lore raw

PATCH v3 2/7 RDMA/core: Add helper function to create named QPs

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

The QPs in the RDMA stack can be created by kernel or users space, but the owner is not visible to users after that.

The added helper keeps track of newly created QP together with the name of the owner. In case of kernel, the caller to create_qp is supposed to update QP's attribute with the name. For user space callers no change is needed and the name will be taken from the process name.

This helper sets qp->device field for all QP types including XRC_TGT, which RDMA/core didn't do before.

---
 drivers/infiniband/core/core_priv.h | 19 +++++++++++++++++++
 include/rdma/ib_verbs.h             |  6 ++++++
 2 files changed, 25 insertions(+)
drivers/infiniband/core/core_priv.h +19 -0
index 2b1372da708a..3f1442bd5fdc 100644
@@ -301,4 +301,23 @@ struct ib_device *ib_device_get_by_index(u32 ifindex);
 /* RDMA device netlink */
 void nldev_init(void);
 void nldev_exit(void);
+
+static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
+					  struct ib_pd *pd,
+					  struct ib_qp_init_attr *attr,
+					  struct ib_udata *udata)
+{
+	struct ib_qp *qp;
+
+	qp = dev->create_qp(pd, attr, udata);
+	if (!IS_ERR(qp)) {
+		qp->device = dev;
+		if (attr->qp_type < IB_QPT_MAX)
+			rdma_restrack_add(&qp->res,
+					  RDMA_RESTRACK_QP,
+					  attr->comm);
+	}
+
+	return qp;
+}
 #endif /* _CORE_PRIV_H */
include/rdma/ib_verbs.h +6 -0
index 271265cd7c1a..41d4f59cac5e 100644
@@ -1141,6 +1141,12 @@ struct ib_qp_init_attr {
 	u8			port_num;
 	struct ib_rwq_ind_table *rwq_ind_tbl;
 	u32			source_qpn;
+
+	/*
+	 * Name of entity which created this QP, empty string means that
+	 * it will be taken automatically from task_struct.
+	 */
+	char comm[TASK_COMM_LEN];
 };
 
 struct ib_qp_open_attr {
Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-3-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#17 lore raw

RE: [PATCH rdma-next v3 2/7] RDMA/core: Add helper function to create named QPs

Quoted 12 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

The QPs in the RDMA stack can be created by kernel or users space, but the owner is not visible to users after that.

The added helper keeps track of newly created QP together with the name of the owner. In case of kernel, the caller to create_qp is supposed to update QP's attribute with the name. For user space callers no change is needed and the name will be taken from the process name.

Quoted 5 lines

This helper sets qp->device field for all QP types including XRC_TGT, which RDMA/core didn't do before.

--
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

#18 lore raw

Re: [PATCH rdma-next v3 2/7] RDMA/core: Add helper function to create named QPs

In reply to a message not in the archive

T24gVGh1LCAyMDE4LTAxLTExIGF0IDE3OjMxICswMjAwLCBMZW9uIFJvbWFub3Zza3kgd3JvdGU6 DQo+IC0tLSBhL2luY2x1ZGUvcmRtYS9pYl92ZXJicy5oDQo+ICsrKyBiL2luY2x1ZGUvcmRtYS9p Yl92ZXJicy5oDQo+IEBAIC0xMTQxLDYgKzExNDEsMTIgQEAgc3RydWN0IGliX3FwX2luaXRfYXR0 ciB7DQo+ICAgICAgICAgdTggICAgICAgICAgICAgICAgICAgICAgcG9ydF9udW07DQo+ICAgICAg ICAgc3RydWN0IGliX3J3cV9pbmRfdGFibGUgKnJ3cV9pbmRfdGJsOw0KPiAgICAgICAgIHUzMiAg ICAgICAgICAgICAgICAgICAgIHNvdXJjZV9xcG47DQo+ICsNCj4gKyAgICAgICAvKg0KPiArICAg ICAgICAqIE5hbWUgb2YgZW50aXR5IHdoaWNoIGNyZWF0ZWQgdGhpcyBRUCwgZW1wdHkgc3RyaW5n IG1lYW5zIHRoYXQNCj4gKyAgICAgICAgKiBpdCB3aWxsIGJlIHRha2VuIGF1dG9tYXRpY2FsbHkg ZnJvbSB0YXNrX3N0cnVjdC4NCj4gKyAgICAgICAgKi8NCj4gKyAgICAgICBjaGFyIGNvbW1bVEFT S19DT01NX0xFTl07DQo+ICB9Ow0KDQpXaHkgaXMgImNvbW0iIGEgY2hhciBhcnJheSBpbnN0ZWFk IG9mIGEgY29uc3QgY2hhciBwb2ludGVyIG9yIGR5bmFtaWNhbGx5DQphbGxvY2F0ZWQgbWVtb3J5 IChrc3RyZHVwKCkpPyBDYW4gd2UgZ2V0IHJpZCBvZiB0aGUgc3RybmNweSgpIGNhbGxzIGluIGNv ZGUNCnRoYXQgZmlsbHMgaW4gdGhpcyBkYXRhIHN0cnVjdHVyZT8NCg0KVGhhbmtzLA0KDQpCYXJ0 Lg0KDQo=
--
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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#20 lore raw

Re: [PATCH rdma-next v3 2/7] RDMA/core: Add helper function to create named QPs

Quoted 10 lines · Bart Van Assche
Quoted 9 lines · Leon Romanovsky
include/rdma/ib_verbs.h +3 -0
@@ -1141,6 +1141,12 @@ struct ib_qp_init_attr {
        u8                      port_num;
        struct ib_rwq_ind_table *rwq_ind_tbl;
        u32                     source_qpn;
+
+       /*
+        * Name of entity which created this QP, empty string means that
Quoted 8 lines

include/rdma/ib_verbs.h struct ib_qp_init_attr { · line 1150

Quoted 4 lines
include/rdma/ib_verbs.h +3 -0
+        * it will be taken automatically from task_struct.
+        */
+       char comm[TASK_COMM_LEN];
 };

Why is "comm" a char array instead of a const char pointer or dynamically allocated memory (kstrdup())? Can we get rid of the strncpy() calls in code that fills in this data structure?

Yes, we can, initially, I didn't want to bother with corner cases of failure in allocations, but in last version of code it is already easy to deal, so I'll replace.

Quoted 5 lines

Thanks,

Bart.

A message that is not in the archive (sent off-list or not yet received): 20180112064243.GK15760-U/[email protected]

#22 lore raw

Re: [PATCH rdma-next v3 2/7] RDMA/core: Add helper function to create named QPs

Quoted 20 lines · Leon Romanovsky
Quoted 10 lines · Bart Van Assche
Quoted 9 lines · Leon Romanovsky
include/rdma/ib_verbs.h +3 -0
@@ -1141,6 +1141,12 @@ struct ib_qp_init_attr {
        u8                      port_num;
        struct ib_rwq_ind_table *rwq_ind_tbl;
        u32                     source_qpn;
+
+       /*
+        * Name of entity which created this QP, empty string means that
Quoted 8 lines

include/rdma/ib_verbs.h struct ib_qp_init_attr { · line 1150

Quoted 4 lines
include/rdma/ib_verbs.h +3 -0
+        * it will be taken automatically from task_struct.
+        */
+       char comm[TASK_COMM_LEN];
 };

Why is "comm" a char array instead of a const char pointer or dynamically allocated memory (kstrdup())? Can we get rid of the strncpy() calls in code that fills in this data structure?

Quoted 3 lines

Yes, we can, initially, I didn't want to bother with corner cases of failure in allocations, but in last version of code it is already easy to deal, so I'll replace.

OK, I started to replace per-your request and found myself replacing half of the code from dynamic allocations to be static initialization for the QP attributes. I need to do it to avoid dealing with release path too.

And found that it is simply too much for this series, and it can come as future optimization.

Thanks

Quoted 5 lines
Quoted 5 lines

Thanks,

Bart.

#23 lore raw

PATCH v3 3/7 RDMA: Annotate create QP callers

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Update all callers to provide owner name through QP attribute structure and connect create_qp with helper which supports resource tracking.

---
 drivers/infiniband/core/cma.c              | 1 +
 drivers/infiniband/core/mad.c              | 1 +
 drivers/infiniband/core/uverbs_cmd.c       | 3 +--
 drivers/infiniband/core/verbs.c            | 4 ++--
 drivers/infiniband/hw/mlx4/mad.c           | 1 +
 drivers/infiniband/hw/mlx4/qp.c            | 1 +
 drivers/infiniband/hw/mlx5/gsi.c           | 2 ++
 drivers/infiniband/ulp/ipoib/ipoib_cm.c    | 4 +++-
 drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 1 +
 drivers/infiniband/ulp/srp/ib_srp.c        | 1 +
 drivers/infiniband/ulp/srpt/ib_srpt.c      | 1 +
 net/smc/smc_ib.c                           | 1 +
 12 files changed, 16 insertions(+), 5 deletions(-)
drivers/infiniband/core/cma.c +1 -0
index a4dc89338fae..1d5dc0d13105 100644
@@ -861,6 +861,7 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
 		return -EINVAL;
 
 	qp_init_attr->port_num = id->port_num;
+	strncpy(qp_init_attr->comm, "rdma-cm", TASK_COMM_LEN);
 	qp = ib_create_qp(pd, qp_init_attr);
 	if (IS_ERR(qp))
 		return PTR_ERR(qp);
drivers/infiniband/core/mad.c +1 -0
index c50596f7f98a..f73551fc5a02 100644
@@ -3103,6 +3103,7 @@ static int create_mad_qp(struct ib_mad_qp_info *qp_info,
 	qp_init_attr.port_num = qp_info->port_priv->port_num;
 	qp_init_attr.qp_context = qp_info;
 	qp_init_attr.event_handler = qp_event_handler;
+	strncpy(qp_init_attr.comm, "rdma-mad", TASK_COMM_LEN);
 	qp_info->qp = ib_create_qp(qp_info->port_priv->pd, &qp_init_attr);
 	if (IS_ERR(qp_info->qp)) {
 		dev_err(&qp_info->port_priv->device->dev,
drivers/infiniband/core/uverbs_cmd.c +1 -2
index c216d98bb816..62b3c5d71cce 100644
@@ -1514,7 +1514,7 @@ static int create_qp(struct ib_uverbs_file *file,
 	if (cmd->qp_type == IB_QPT_XRC_TGT)
 		qp = ib_create_qp(pd, &attr);
 	else
-		qp = device->create_qp(pd, &attr, uhw);
+		qp = _ib_create_qp(device, pd, &attr, uhw);
 
 	if (IS_ERR(qp)) {
 		ret = PTR_ERR(qp);
@@ -1527,7 +1527,6 @@ static int create_qp(struct ib_uverbs_file *file,
 			goto err_cb;
 
 		qp->real_qp	  = qp;
-		qp->device	  = device;
 		qp->pd		  = pd;
 		qp->send_cq	  = attr.send_cq;
 		qp->recv_cq	  = attr.recv_cq;
drivers/infiniband/core/verbs.c +2 -2
index f3e446b48e3a..0c8743ec594a 100644
@@ -882,7 +882,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 	if (qp_init_attr->cap.max_rdma_ctxs)
 		rdma_rw_init_qp(device, qp_init_attr);
 
-	qp = device->create_qp(pd, qp_init_attr, NULL);
+	qp = _ib_create_qp(device, pd, qp_init_attr, NULL);
 	if (IS_ERR(qp))
 		return qp;
 
@@ -892,7 +892,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
 		return ERR_PTR(ret);
 	}
 
-	qp->device     = device;
 	qp->real_qp    = qp;
 	qp->uobject    = NULL;
 	qp->qp_type    = qp_init_attr->qp_type;
@@ -1538,6 +1537,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
 
+	rdma_restrack_del(&qp->res, RDMA_RESTRACK_QP);
 	ret = qp->device->destroy_qp(qp);
 	if (!ret) {
 		if (pd)
drivers/infiniband/hw/mlx4/mad.c +1 -0
index 0793a21d76f4..f816df420fb9 100644
@@ -1834,6 +1834,7 @@ static int create_pv_sqp(struct mlx4_ib_demux_pv_ctx *ctx,
 	qp_init_attr.init_attr.port_num = ctx->port;
 	qp_init_attr.init_attr.qp_context = ctx;
 	qp_init_attr.init_attr.event_handler = pv_qp_event_handler;
+	strncpy(qp_init_attr.init_attr.comm, "mlx4-sriov", TASK_COMM_LEN);
 	tun_qp->qp = ib_create_qp(ctx->pd, &qp_init_attr.init_attr);
 	if (IS_ERR(tun_qp->qp)) {
 		ret = PTR_ERR(tun_qp->qp);
drivers/infiniband/hw/mlx4/qp.c +1 -0
index f045491f2c14..ebdfac3eb673 100644
@@ -1689,6 +1689,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
 		if (is_eth &&
 		    dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ROCE_V1_V2) {
 			init_attr->create_flags |= MLX4_IB_QP_CREATE_ROCE_V2_GSI;
+			strncpy(init_attr->comm, "mlx4-gsi", TASK_COMM_LEN);
 			sqp->roce_v2_gsi = ib_create_qp(pd, init_attr);
 
 			if (IS_ERR(sqp->roce_v2_gsi)) {
drivers/infiniband/hw/mlx5/gsi.c +2 -0
index 79e6309460dc..b1b177d1a0dd 100644
@@ -184,6 +184,7 @@ struct ib_qp *mlx5_ib_gsi_create_qp(struct ib_pd *pd,
 		hw_init_attr.cap.max_send_sge = 0;
 		hw_init_attr.cap.max_inline_data = 0;
 	}
+	strncpy(hw_init_attr.comm, "mlx5-gsi", TASK_COMM_LEN);
 	gsi->rx_qp = ib_create_qp(pd, &hw_init_attr);
 	if (IS_ERR(gsi->rx_qp)) {
 		mlx5_ib_warn(dev, "unable to create hardware GSI QP. error %ld\n",
@@ -264,6 +265,7 @@ static struct ib_qp *create_gsi_ud_qp(struct mlx5_ib_gsi_qp *gsi)
 		.sq_sig_type = gsi->sq_sig_type,
 		.qp_type = IB_QPT_UD,
 		.create_flags = mlx5_ib_create_qp_sqpn_qp1(),
+		.comm = "mlx5-gsi",
 	};
 
 	return ib_create_qp(pd, &init_attr);
drivers/infiniband/ulp/ipoib/ipoib_cm.c +3 -1
index dfbb8fdda5f6..d165b3a25340 100644
@@ -263,6 +263,7 @@ static struct ib_qp *ipoib_cm_create_rx_qp(struct net_device *dev,
 		.sq_sig_type = IB_SIGNAL_ALL_WR,
 		.qp_type = IB_QPT_RC,
 		.qp_context = p,
+		.comm = "ipoib-cm",
 	};
 
 	if (!ipoib_cm_has_srq(dev)) {
@@ -1062,7 +1063,8 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net_device *dev, struct ipoib_
 		.sq_sig_type		= IB_SIGNAL_ALL_WR,
 		.qp_type		= IB_QPT_RC,
 		.qp_context		= tx,
-		.create_flags		= 0
+		.create_flags		= 0,
+		.comm			= "ipoib-cm",
 	};
 	struct ib_qp *tx_qp;
 
drivers/infiniband/ulp/ipoib/ipoib_verbs.c +1 -0
index 984a88096f39..d41d85f8ac7e 100644
@@ -206,6 +206,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
 	if (priv->hca_caps & IB_DEVICE_MANAGED_FLOW_STEERING)
 		init_attr.create_flags |= IB_QP_CREATE_NETIF_QP;
 
+	strncpy(init_attr.comm, "ipoib-verbs", TASK_COMM_LEN);
 	priv->qp = ib_create_qp(priv->pd, &init_attr);
 	if (IS_ERR(priv->qp)) {
 		pr_warn("%s: failed to create QP\n", ca->name);
drivers/infiniband/ulp/srp/ib_srp.c +1 -0
index 62d88212c1b0..fb8be6b2ddfb 100644
@@ -521,6 +521,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
 	init_attr->send_cq             = send_cq;
 	init_attr->recv_cq             = recv_cq;
 
+	strncpy(init_attr->comm, "srp", TASK_COMM_LEN);
 	qp = ib_create_qp(dev->pd, init_attr);
 	if (IS_ERR(qp)) {
 		ret = PTR_ERR(qp);
drivers/infiniband/ulp/srpt/ib_srpt.c +1 -0
index d78f60dcc2ba..3724132a266e 100644
@@ -1726,6 +1726,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
 		qp_init->cap.max_recv_sge = qp_init->cap.max_send_sge;
 	}
 
+	strncpy(qp_init->comm, "srpt", TASK_COMM_LEN);
 	ch->qp = ib_create_qp(sdev->pd, qp_init);
 	if (IS_ERR(ch->qp)) {
 		ret = PTR_ERR(ch->qp);
net/smc/smc_ib.c +1 -0
index 90f1a7f9085c..9f5bca333cce 100644
@@ -243,6 +243,7 @@ int smc_ib_create_queue_pair(struct smc_link *lnk)
 		},
 		.sq_sig_type = IB_SIGNAL_REQ_WR,
 		.qp_type = IB_QPT_RC,
+		.comm = "sec-ib",
 	};
 	int rc;
 
Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-4-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#25 lore raw

RE: [PATCH rdma-next v3 3/7] RDMA: Annotate create QP callers

Quoted 8 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Update all callers to provide owner name through QP attribute structure and connect create_qp with helper which supports resource tracking.

--
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

#26 lore raw

Re: [PATCH rdma-next v3 3/7] RDMA: Annotate create QP callers

In reply to a message not in the archive

drivers/infiniband/core/verbs.c int ib_destroy_qp(struct ib_qp *qp) · line 1543

Quoted 8 lines · Leon Romanovsky
drivers/infiniband/core/verbs.c +1 -0
@@ -1538,6 +1537,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
 
+	rdma_restrack_del(&qp->res, RDMA_RESTRACK_QP);
 	ret = qp->device->destroy_qp(qp);
 	if (!ret) {
 		if (pd)

This hunk belongs in a different patch right?

Jason
--
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

A message that is not in the archive (sent off-list or not yet received): 20180114212704.GE9088-uk2M96/[email protected]

#28 lore raw

Re: [PATCH rdma-next v3 3/7] RDMA: Annotate create QP callers

Quoted 11 lines · Jason Gunthorpe

drivers/infiniband/core/verbs.c int ib_destroy_qp(struct ib_qp *qp) · line 1543

Quoted 8 lines · Leon Romanovsky
drivers/infiniband/core/verbs.c +1 -0
@@ -1538,6 +1537,7 @@ int ib_destroy_qp(struct ib_qp *qp)
 	if (!qp->uobject)
 		rdma_rw_cleanup_mrs(qp);
 
+	rdma_restrack_del(&qp->res, RDMA_RESTRACK_QP);
 	ret = qp->device->destroy_qp(qp);
 	if (!ret) {
 		if (pd)

This hunk belongs in a different patch right?

In this patch, I changed call from device->create_qp() to the _ib_create_qp() and it is under the hood called to the rdma_restrack_add(). There was a need to add rdma_restrack_del() to balance refounts.

Quoted 2 lines

Jason

#29 lore raw

Re: [PATCH rdma-next v3 3/7] RDMA: Annotate create QP callers

In reply to a message not in the archive

net/smc/smc_ib.c int smc_ib_create_queue_pair(struct smc_link *lnk) · line 246

Quoted 7 lines · Leon Romanovsky
net/smc/smc_ib.c +1 -0
@@ -243,6 +243,7 @@ int smc_ib_create_queue_pair(struct smc_link *lnk)
                },
                .sq_sig_type = IB_SIGNAL_REQ_WR,
                .qp_type = IB_QPT_RC,
+               .comm = "sec-ib",

^^^
Typo? Should it be smc-ib?

Signature · 3 lines
Doug Ledford <[email protected]>
    GPG KeyID: B826A3330E572FDD
    Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD

A message that is not in the archive (sent off-list or not yet received): 1516203857.3403.255.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org

#31 lore raw

Re: [PATCH rdma-next v3 3/7] RDMA: Annotate create QP callers

Quoted 10 lines · Doug Ledford

net/smc/smc_ib.c int smc_ib_create_queue_pair(struct smc_link *lnk) · line 246

Quoted 7 lines · Leon Romanovsky
net/smc/smc_ib.c +1 -0
@@ -243,6 +243,7 @@ int smc_ib_create_queue_pair(struct smc_link *lnk)
                },
                .sq_sig_type = IB_SIGNAL_REQ_WR,
                .qp_type = IB_QPT_RC,
+               .comm = "sec-ib",

^^^
Typo? Should it be smc-ib?

Yes, thanks.
After Bart's feedback, I'm working on new version which doesn't require to annotate QPs.

Quoted 5 lines

--
Doug Ledford <[email protected]>

    GPG KeyID: B826A3330E572FDD
    Key fingerprint = AE6B 1BDA 122B 23B4 265B  1274 B826 A333 0E57 2FDD
#32 lore raw

PATCH v3 4/7 RDMA/core: Add resource tracking for create and destroy CQs

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Track all creation and destroy of CQ objects.

---
 drivers/infiniband/core/cq.c               | 3 +++
 drivers/infiniband/core/uverbs_cmd.c       | 1 +
 drivers/infiniband/core/uverbs_std_types.c | 2 ++
 drivers/infiniband/core/verbs.c            | 2 ++
 4 files changed, 8 insertions(+)
drivers/infiniband/core/cq.c +3 -0
index f2ae75fa3128..6344e007dbce 100644
@@ -154,6 +154,8 @@ struct ib_cq *ib_alloc_cq(struct ib_device *dev, void *private,
 	if (!cq->wc)
 		goto out_destroy_cq;
 
+	rdma_restrack_add(&cq->res, RDMA_RESTRACK_CQ, NULL);
+
 	switch (cq->poll_ctx) {
 	case IB_POLL_DIRECT:
 		cq->comp_handler = ib_cq_completion_direct;
@@ -208,6 +210,7 @@ void ib_free_cq(struct ib_cq *cq)
 		WARN_ON_ONCE(1);
 	}
 
+	rdma_restrack_del(&cq->res, RDMA_RESTRACK_CQ);
 	kfree(cq->wc);
 	ret = cq->device->destroy_cq(cq);
 	WARN_ON_ONCE(ret);
drivers/infiniband/core/uverbs_cmd.c +1 -0
index 62b3c5d71cce..c6ac0ee57f7c 100644
@@ -1033,6 +1033,7 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
 		goto err_cb;
 
 	uobj_alloc_commit(&obj->uobject);
+	rdma_restrack_add(&cq->res, RDMA_RESTRACK_CQ, NULL);
 
 	return obj;
 
drivers/infiniband/core/uverbs_std_types.c +2 -0
index c3ee5d9b336d..2d0d27865b09 100644
@@ -35,6 +35,7 @@
 #include <rdma/ib_verbs.h>
 #include <linux/bug.h>
 #include <linux/file.h>
+#include <rdma/restrack.h>
 #include "rdma_core.h"
 #include "uverbs.h"
 
@@ -319,6 +320,7 @@ static int uverbs_create_cq_handler(struct ib_device *ib_dev,
 	obj->uobject.object = cq;
 	obj->uobject.user_handle = user_handle;
 	atomic_set(&cq->usecnt, 0);
+	rdma_restrack_add(&cq->res, RDMA_RESTRACK_CQ, NULL);
 
 	ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe);
 	if (ret)
drivers/infiniband/core/verbs.c +2 -0
index 0c8743ec594a..ae592be45809 100644
@@ -1580,6 +1580,7 @@ struct ib_cq *ib_create_cq(struct ib_device *device,
 		cq->event_handler = event_handler;
 		cq->cq_context    = cq_context;
 		atomic_set(&cq->usecnt, 0);
+		rdma_restrack_add(&cq->res, RDMA_RESTRACK_CQ, NULL);
 	}
 
 	return cq;
@@ -1598,6 +1599,7 @@ int ib_destroy_cq(struct ib_cq *cq)
 	if (atomic_read(&cq->usecnt))
 		return -EBUSY;
 
+	rdma_restrack_del(&cq->res, RDMA_RESTRACK_CQ);
 	return cq->device->destroy_cq(cq);
 }
 EXPORT_SYMBOL(ib_destroy_cq);
Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-5-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#34 lore raw

RE: [PATCH rdma-next v3 4/7] RDMA/core: Add resource tracking for create and destroy CQs

Quoted 6 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Track all creation and destroy of CQ objects.

--
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

#35 lore raw

PATCH v3 5/7 RDMA/core: Add resource tracking for create and destroy PDs

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Track all creation and destroy of PD objects.

---
 drivers/infiniband/core/uverbs_cmd.c | 1 +
 drivers/infiniband/core/verbs.c      | 2 ++
 2 files changed, 3 insertions(+)
drivers/infiniband/core/uverbs_cmd.c +1 -0
index c6ac0ee57f7c..2cf3e20e5152 100644
@@ -340,6 +340,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
 	uobj->object = pd;
 	memset(&resp, 0, sizeof resp);
 	resp.pd_handle = uobj->id;
+	rdma_restrack_add(&pd->res, RDMA_RESTRACK_PD, NULL);
 
 	if (copy_to_user(u64_to_user_ptr(cmd.response), &resp, sizeof resp)) {
 		ret = -EFAULT;
drivers/infiniband/core/verbs.c +2 -0
index ae592be45809..8a3ef182c72a 100644
@@ -262,6 +262,7 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
 		pr_warn("%s: enabling unsafe global rkey\n", caller);
 		mr_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE;
 	}
+	rdma_restrack_add(&pd->res, RDMA_RESTRACK_PD, NULL);
 
 	if (mr_access_flags) {
 		struct ib_mr *mr;
@@ -312,6 +313,7 @@ void ib_dealloc_pd(struct ib_pd *pd)
 	   requires the caller to guarantee we can't race here. */
 	WARN_ON(atomic_read(&pd->usecnt));
 
+	rdma_restrack_del(&pd->res, RDMA_RESTRACK_PD);
 	/* Making delalloc_pd a void return is a WIP, no driver should return
 	   an error here. */
 	ret = pd->device->dealloc_pd(pd);
Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-6-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#37 lore raw

RE: [PATCH rdma-next v3 5/7] RDMA/core: Add resource tracking for create and destroy PDs

Quoted 6 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Track all creation and destroy of PD objects.

--
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

#38 lore raw

PATCH v3 6/7 RDMA/nldev: Provide global resource utilization

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Export through netlink interface, the global device utilization for the rdmatool as the main user of RDMA nldev interface.

Provide both dumpit and doit callbacks.

As an example of possible output from rdmatool for system with 5 Mellanox's card

$ rdma res
1: mlx5_0: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
2: mlx5_1: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
3: mlx5_2: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
4: mlx5_3: curr/max: qp 2/262144 cq 3/16777216 pd 2/16777216
5: mlx5_4: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
---
 drivers/infiniband/core/nldev.c  | 177 +++++++++++++++++++++++++++++++++++++++
 include/uapi/rdma/rdma_netlink.h |  11 +++
 2 files changed, 188 insertions(+)
drivers/infiniband/core/nldev.c +177 -0
index 5d790c507c7e..952c95b776c9 100644
@@ -31,6 +31,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/pid.h>
+#include <linux/pid_namespace.h>
 #include <net/netlink.h>
 #include <rdma/rdma_netlink.h>
 
@@ -52,6 +54,12 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
 	[RDMA_NLDEV_ATTR_PORT_STATE]	= { .type = NLA_U8 },
 	[RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = { .type = NLA_U8 },
 	[RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = { .type = NLA_U8 },
+	[RDMA_NLDEV_ATTR_RES_SUMMARY]	= { .type = NLA_NESTED },
+	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY]	= { .type = NLA_NESTED },
+	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = { .type = NLA_NUL_STRING,
+					     .len = 16 },
+	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = { .type = NLA_U64 },
+	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX]	= { .type = NLA_U64 },
 };
 
 static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
@@ -134,6 +142,90 @@ static int fill_port_info(struct sk_buff *msg,
 	return 0;
 }
 
+static int fill_res_info_entry(struct sk_buff *msg,
+			       const char *name, u64 curr, u64 max)
+{
+	struct nlattr *entry_attr;
+
+	entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY);
+	if (!entry_attr)
+		return -EMSGSIZE;
+
+	if (nla_put_string(msg, RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME, name))
+		goto err;
+	if (nla_put_u64_64bit(msg,
+			      RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR, curr, 0))
+		goto err;
+	if (nla_put_u64_64bit(msg,
+			      RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX, max, 0))
+		goto err;
+
+	nla_nest_end(msg, entry_attr);
+	return 0;
+
+err:
+	nla_nest_cancel(msg, entry_attr);
+	return -EMSGSIZE;
+}
+
+static u32 get_res_max(struct ib_device *dev, int idx)
+{
+	switch (idx) {
+	case RDMA_RESTRACK_PD: return dev->attrs.max_pd;
+	case RDMA_RESTRACK_CQ: return dev->attrs.max_cq;
+	case RDMA_RESTRACK_QP: return dev->attrs.max_qp;
+	default:	       return 0; /* unreachable */
+	}
+}
+
+static int fill_res_info(struct sk_buff *msg, struct ib_device *device)
+{
+	static const char *names[_RDMA_RESTRACK_MAX] = {
+		[RDMA_RESTRACK_PD] = "pd",
+		[RDMA_RESTRACK_CQ] = "cq",
+		[RDMA_RESTRACK_QP] = "qp",
+	};
+
+	struct rdma_restrack_root *res = &device->res;
+	struct nlattr *table_attr;
+	int ret, i;
+
+	if (fill_nldev_handle(msg, device))
+		return -EMSGSIZE;
+
+	/*
+	 * get_res_max() is per-device and it doesn't know anything about
+	 * PID namespace, so limit output to init namespace only.
+	 *
+	 * The netlink user will see the message returns with NLDEV
+	 * handles only.
+	 */
+
+	if (task_active_pid_ns(current) != &init_pid_ns)
+		return 0;
+
+	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY);
+	if (!table_attr)
+		return -EMSGSIZE;
+
+	for (i = 0; i < _RDMA_RESTRACK_MAX; i++) {
+		if (!names[i])
+			continue;
+		ret = fill_res_info_entry(msg, names[i],
+					  rdma_restrack_count(res, i),
+					  get_res_max(device, i));
+		if (ret)
+			goto err;
+	}
+
+	nla_nest_end(msg, table_attr);
+	return 0;
+
+err:
+	nla_nest_cancel(msg, table_attr);
+	return ret;
+}
+
 static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 			  struct netlink_ext_ack *extack)
 {
@@ -329,6 +421,87 @@ static int nldev_port_get_dumpit(struct sk_buff *skb,
 	return skb->len;
 }
 
+static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
+			      struct netlink_ext_ack *extack)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+	struct ib_device *device;
+	struct sk_buff *msg;
+	u32 index;
+	int ret;
+
+	ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+			  nldev_policy, extack);
+	if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
+		return -EINVAL;
+
+	index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+	device = ib_device_get_by_index(index);
+	if (!device)
+		return -EINVAL;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		goto err;
+
+	nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
+			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
+			0, 0);
+
+	ret = fill_res_info(msg, device);
+	if (ret)
+		goto err_free;
+
+	nlmsg_end(msg, nlh);
+	put_device(&device->dev);
+	return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
+
+err_free:
+	nlmsg_free(msg);
+err:
+	put_device(&device->dev);
+	return ret;
+}
+
+static int _nldev_res_get_dumpit(struct ib_device *device,
+				 struct sk_buff *skb,
+				 struct netlink_callback *cb,
+				 unsigned int idx)
+{
+	int start = cb->args[0];
+	struct nlmsghdr *nlh;
+
+	if (idx < start)
+		return 0;
+
+	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
+			0, NLM_F_MULTI);
+
+	if (fill_res_info(skb, device)) {
+		nlmsg_cancel(skb, nlh);
+		goto out;
+	}
+
+	nlmsg_end(skb, nlh);
+
+	idx++;
+
+out:
+	cb->args[0] = idx;
+	return skb->len;
+}
+
+static int nldev_res_get_dumpit(struct sk_buff *skb,
+				struct netlink_callback *cb)
+{
+	/*
+	 * There is no need to take lock, because
+	 * we are relying on ib_core's lists_rwsem
+	 */
+	return ib_enum_all_devs(_nldev_res_get_dumpit, skb, cb);
+}
+
 static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 	[RDMA_NLDEV_CMD_GET] = {
 		.doit = nldev_get_doit,
@@ -338,6 +511,10 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 		.doit = nldev_port_get_doit,
 		.dump = nldev_port_get_dumpit,
 	},
+	[RDMA_NLDEV_CMD_RES_GET] = {
+		.doit = nldev_res_get_doit,
+		.dump = nldev_res_get_dumpit,
+	},
 };
 
 void __init nldev_init(void)
include/uapi/rdma/rdma_netlink.h +11 -0
index cc002e316d09..e041d2eca4b8 100644
@@ -236,6 +236,11 @@ enum rdma_nldev_command {
 	RDMA_NLDEV_CMD_PORT_NEW,
 	RDMA_NLDEV_CMD_PORT_DEL,
 
+	RDMA_NLDEV_CMD_RES_GET, /* can dump */
+	RDMA_NLDEV_CMD_RES_SET,
+	RDMA_NLDEV_CMD_RES_NEW,
+	RDMA_NLDEV_CMD_RES_DEL,
+
 	RDMA_NLDEV_NUM_OPS
 };
 
@@ -303,6 +308,12 @@ enum rdma_nldev_attr {
 
 	RDMA_NLDEV_ATTR_DEV_NODE_TYPE,		/* u8 */
 
+	RDMA_NLDEV_ATTR_RES_SUMMARY,		/* nested table */
+	RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY,	/* nested table */
+	RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME,	/* string */
+	RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR,	/* u64 */
+	RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX,	/* u64 */
+
 	RDMA_NLDEV_ATTR_MAX
 };
 #endif /* _UAPI_RDMA_NETLINK_H */
Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-7-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#40 lore raw

RE: [PATCH rdma-next v3 6/7] RDMA/nldev: Provide global resource utilization

Quoted 18 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Export through netlink interface, the global device utilization for the rdmatool as the main user of RDMA nldev interface.

Provide both dumpit and doit callbacks.

As an example of possible output from rdmatool for system with 5 Mellanox's card

$ rdma res
1: mlx5_0: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
2: mlx5_1: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
3: mlx5_2: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
4: mlx5_3: curr/max: qp 2/262144 cq 3/16777216 pd 2/16777216
5: mlx5_4: curr/max: qp 4/262144 cq 5/16777216 pd 3/16777216
Quoted 2 lines

--
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

#41 lore raw

PATCH v3 7/7 RDMA/nldev: Provide detailed QP information

In reply to a message not in the archive

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Implement RDMA nldev netlink interface to get detailed QP information.

Currently only dumpit variant is implemented.

---
 drivers/infiniband/core/nldev.c  | 228 +++++++++++++++++++++++++++++++++++++++
 include/uapi/rdma/rdma_netlink.h |  45 ++++++++
 2 files changed, 273 insertions(+)
drivers/infiniband/core/nldev.c +228 -0
index 952c95b776c9..8b243f222088 100644
@@ -60,6 +60,18 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
 					     .len = 16 },
 	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = { .type = NLA_U64 },
 	[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX]	= { .type = NLA_U64 },
+	[RDMA_NLDEV_ATTR_RES_QP]		= { .type = NLA_NESTED },
+	[RDMA_NLDEV_ATTR_RES_QP_ENTRY]		= { .type = NLA_NESTED },
+	[RDMA_NLDEV_ATTR_RES_LQPN]		= { .type = NLA_U32 },
+	[RDMA_NLDEV_ATTR_RES_RQPN]		= { .type = NLA_U32 },
+	[RDMA_NLDEV_ATTR_RES_RQ_PSN]		= { .type = NLA_U32 },
+	[RDMA_NLDEV_ATTR_RES_SQ_PSN]		= { .type = NLA_U32 },
+	[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE] = { .type = NLA_U8 },
+	[RDMA_NLDEV_ATTR_RES_TYPE]		= { .type = NLA_U8 },
+	[RDMA_NLDEV_ATTR_RES_STATE]		= { .type = NLA_U8 },
+	[RDMA_NLDEV_ATTR_RES_PID]		= { .type = NLA_U32 },
+	[RDMA_NLDEV_ATTR_RES_PID_COMM]	= { .type = NLA_NUL_STRING,
+						    .len = TASK_COMM_LEN },
 };
 
 static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
@@ -226,6 +238,78 @@ static int fill_res_info(struct sk_buff *msg, struct ib_device *device)
 	return ret;
 }
 
+static int fill_res_qp_entry(struct sk_buff *msg,
+			     struct ib_qp *qp, uint32_t port)
+{
+	struct rdma_restrack_entry *res = &qp->res;
+	struct ib_qp_init_attr qp_init_attr;
+	struct nlattr *entry_attr;
+	struct ib_qp_attr qp_attr;
+	int ret;
+
+	ret = ib_query_qp(qp, &qp_attr, 0, &qp_init_attr);
+	if (ret)
+		return ret;
+
+	if (port && port != qp_attr.port_num)
+		return 0;
+
+	entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP_ENTRY);
+	if (!entry_attr)
+		goto out;
+
+	/* In create_qp() port is not set yet */
+	if (qp_attr.port_num &&
+	    nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp_attr.port_num))
+		goto err;
+
+	if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num))
+		goto err;
+	if (qp->qp_type == IB_QPT_RC || qp->qp_type == IB_QPT_UC) {
+		if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RQPN,
+				qp_attr.dest_qp_num))
+			goto err;
+		if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RQ_PSN,
+				qp_attr.rq_psn))
+			goto err;
+	}
+
+	if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_SQ_PSN, qp_attr.sq_psn))
+		goto err;
+
+	if (qp->qp_type == IB_QPT_RC || qp->qp_type == IB_QPT_UC ||
+	    qp->qp_type == IB_QPT_XRC_INI || qp->qp_type == IB_QPT_XRC_TGT) {
+		if (nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE,
+			       qp_attr.path_mig_state))
+			goto err;
+	}
+	if (nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_TYPE, qp->qp_type))
+		goto err;
+	if (nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_STATE, qp_attr.qp_state))
+		goto err;
+
+	/*
+	 * Existence of task means that it is user QP and netlink
+	 * user is invited to go and read /proc/PID/comm to get name
+	 * of the task file and res->task_com should be NULL.
+	 */
+	if (res->task &&
+	    nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PID, task_pid_vnr(res->task)))
+		goto err;
+
+	if (res->task_comm &&
+	    nla_put_string(msg, RDMA_NLDEV_ATTR_RES_PID_COMM, res->task_comm))
+		goto err;
+
+	nla_nest_end(msg, entry_attr);
+	return 0;
+
+err:
+	nla_nest_cancel(msg, entry_attr);
+out:
+	return -EMSGSIZE;
+}
+
 static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 			  struct netlink_ext_ack *extack)
 {
@@ -502,6 +586,137 @@ static int nldev_res_get_dumpit(struct sk_buff *skb,
 	return ib_enum_all_devs(_nldev_res_get_dumpit, skb, cb);
 }
 
+static int nldev_res_get_qp_dumpit(struct sk_buff *skb,
+				   struct netlink_callback *cb)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
+	struct rdma_restrack_entry *res, *nxt;
+	int err, ret, key, idx = 0;
+	struct nlattr *table_attr;
+	struct ib_device *device;
+	int start = cb->args[0];
+	struct nlmsghdr *nlh;
+	u32 index, port = 0;
+	struct ib_qp *qp;
+
+	err = nlmsg_parse(cb->nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
+			  nldev_policy, NULL);
+	/*
+	 * Right now, we are expecting the device index to get QP information,
+	 * but it is possible to extend this code to return all devices in
+	 * one shot by checking the existence of RDMA_NLDEV_ATTR_DEV_INDEX.
+	 * if it doesn't exist, we will iterate over all devices.
+	 *
+	 * But it is not needed for now.
+	 */
+	if (err || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
+		return -EINVAL;
+
+	index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+	device = ib_device_get_by_index(index);
+	if (!device)
+		return -EINVAL;
+
+	/*
+	 * If no PORT_INDEX is supplied, we will return QPs from whole device
+	 */
+	if (tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
+		port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
+		if (!rdma_is_port_valid(device, port)) {
+			ret = -EINVAL;
+			goto err_index;
+		}
+	}
+
+	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_QP_GET),
+			0, NLM_F_MULTI);
+
+	if (fill_nldev_handle(skb, device)) {
+		ret = -EMSGSIZE;
+		goto err;
+	}
+
+	table_attr = nla_nest_start(skb, RDMA_NLDEV_ATTR_RES_QP);
+	if (!table_attr) {
+		ret = -EMSGSIZE;
+		goto err;
+	}
+
+	rdma_restrack_lock(&device->res, RDMA_RESTRACK_QP);
+	for_each_res_safe(res, nxt, RDMA_RESTRACK_QP, device) {
+		if (idx < start) {
+			idx++;
+			continue;
+		}
+
+		key = srcu_read_lock(&res->srcu);
+
+		if ((!res->task && task_active_pid_ns(current) != &init_pid_ns) ||
+		    (res->task &&
+		     task_active_pid_ns(current) != task_active_pid_ns(res->task))) {
+			srcu_read_unlock(&res->srcu, key);
+			/*
+			 * 1. Kernel QPs should be visible in init namsapce only
+			 * 2. Preent only QPs visible in the current namespace
+			 */
+			continue;
+		}
+
+		qp = container_of(res, struct ib_qp, res);
+		/*
+		 * We are releasing the object list lock to ensure that
+		 * object creation/destroy doesn't can progress while
+		 * we are getting information about QP.
+		 *
+		 * It is needed to prevent writer starvation, because of
+		 * large number of reources in object list.
+		 */
+		rdma_restrack_unlock(&device->res, RDMA_RESTRACK_QP);
+		ret = fill_res_qp_entry(skb, qp, port);
+		rdma_restrack_lock(&device->res, RDMA_RESTRACK_QP);
+
+		/*
+		 * There is a need to ensure that next QP is valid,
+		 * because we dropped the lock protecting our linked list.
+		 *
+		 * The RCU protection of "res" ensures that it is safe.
+		 */
+		list_safe_reset_next(res, nxt, list);
+
+		srcu_read_unlock(&res->srcu, key);
+
+		if (ret == -EMSGSIZE)
+			/*
+			 * There is a chance to optimize here.
+			 * It can be done by using list_prepare_entry
+			 * and list_for_each_entry_continue afterwards.
+			 */
+			break;
+		if (ret)
+			goto res_err;
+		idx++;
+	}
+	rdma_restrack_unlock(&device->res, RDMA_RESTRACK_QP);
+
+	nla_nest_end(skb, table_attr);
+	nlmsg_end(skb, nlh);
+	cb->args[0] = idx;
+	put_device(&device->dev);
+	return 0;
+
+res_err:
+	nla_nest_cancel(skb, table_attr);
+	rdma_restrack_unlock(&device->res, RDMA_RESTRACK_QP);
+
+err:
+	nlmsg_cancel(skb, nlh);
+
+err_index:
+	put_device(&device->dev);
+	return ret;
+}
+
 static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 	[RDMA_NLDEV_CMD_GET] = {
 		.doit = nldev_get_doit,
@@ -515,6 +730,19 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
 		.doit = nldev_res_get_doit,
 		.dump = nldev_res_get_dumpit,
 	},
+	[RDMA_NLDEV_CMD_RES_QP_GET] = {
+		.dump = nldev_res_get_qp_dumpit,
+		/*
+		 * .doit is not implemented yet for two reasons:
+		 * 1. It is not needed yet.
+		 * 2. There is a need to provide identifier, while it is easy
+		 * for the QPs (device index + port index + LQPN), it is not
+		 * the case for the rest of resources (PD and CQ). Because it
+		 * is better to provide similar interface for all resources,
+		 * let's wait till we will have other resources implemented
+		 * too.
+		 */
+	},
 };
 
 void __init nldev_init(void)
include/uapi/rdma/rdma_netlink.h +45 -0

57 lines not on this page · raw message

Signature · 6 lines
2.15.1

--
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

A message that is not in the archive (sent off-list or not yet received): 20180111153132.11143-8-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org

Reviewed-by
#43 lore raw

RE: [PATCH rdma-next v3 7/7] RDMA/nldev: Provide detailed QP information

Quoted 9 lines

From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/[email protected]>

Implement RDMA nldev netlink interface to get detailed QP information.

Currently only dumpit variant is implemented.

--
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