RDMA/nldev: provide detailed CM_ID information

Implement RDMA nldev netlink interface to get detailed CM_ID information.

Because cm_id's are attached to rdma devices in various work queue
contexts, the pid and task information at restrak_add() time is sometimes
not useful.  For example, an nvme/f host connection cm_id ends up being
bound to a device in a work queue context and the resulting pid at attach
time no longer exists after connection setup.  So instead we mark all
cm_id's created via the rdma_ucm as "user", and all others as "kernel".
This required tweaking the restrack code a little.  It also required
wrapping some rdma_cm functions to allow passing the module name string.

Signed-off-by: Steve Wise <[email protected]>
Reviewed-by: Leon Romanovsky <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
This commit is contained in:
Steve Wise 2018-03-01 13:57:44 -08:00 • committed by Doug Ledford
commit 00313983cd
8 changed files with 205 additions and 43 deletions

View file

@ -157,6 +157,11 @@ struct rdma_cm_id {
u8 port_num;
};
struct rdma_cm_id *__rdma_create_id(struct net *net,
rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps,
enum ib_qp_type qp_type, const char *caller);
/**
* rdma_create_id - Create an RDMA identifier.
*
@ -169,10 +174,9 @@ struct rdma_cm_id {
*
* The id holds a reference on the network namespace until it is destroyed.
*/
struct rdma_cm_id *rdma_create_id(struct net *net,
rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps,
enum ib_qp_type qp_type);
#define rdma_create_id(net, event_handler, context, ps, qp_type) \
__rdma_create_id((net), (event_handler), (context), (ps), (qp_type), \
KBUILD_MODNAME)
/**
* rdma_destroy_id - Destroys an RDMA identifier.
@ -284,6 +288,9 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
*/
int rdma_listen(struct rdma_cm_id *id, int backlog);
int __rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param,
const char *caller);
/**
* rdma_accept - Called to accept a connection request or response.
* @id: Connection identifier associated with the request.
@ -299,7 +306,8 @@ int rdma_listen(struct rdma_cm_id *id, int backlog);
* state of the qp associated with the id is modified to error, such that any
* previously posted receive buffers would be flushed.
*/
int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param);
#define rdma_accept(id, conn_param) \
__rdma_accept((id), (conn_param), KBUILD_MODNAME)
/**
* rdma_notify - Notifies the RDMA CM of an asynchronous event that has

View file

@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/kref.h>
#include <linux/completion.h>
#include <linux/sched/task.h>
/**
* enum rdma_restrack_type - HW objects to track
@ -28,6 +29,10 @@ enum rdma_restrack_type {
* @RDMA_RESTRACK_QP: Queue pair (QP)
*/
RDMA_RESTRACK_QP,
/**
* @RDMA_RESTRACK_CM_ID: Connection Manager ID (CM_ID)
*/
RDMA_RESTRACK_CM_ID,
/**
* @RDMA_RESTRACK_MAX: Last entry, used for array dclarations
*/
@ -150,4 +155,19 @@ int __must_check rdma_restrack_get(struct rdma_restrack_entry *res);
* @res: resource entry
*/
int rdma_restrack_put(struct rdma_restrack_entry *res);
/**
* rdma_restrack_set_task() - set the task for this resource
* @res: resource entry
* @task: task struct
*/
static inline void rdma_restrack_set_task(struct rdma_restrack_entry *res,
struct task_struct *task)
{
if (res->task)
put_task_struct(res->task);
get_task_struct(task);
res->task = task;
}
#endif /* _RDMA_RESTRACK_H_ */