Commit da5c8507 authored by Steve Wise's avatar Steve Wise Committed by Doug Ledford

RDMA/nldev: add driver-specific resource tracking

Each driver can register a "fill entry" function with the restrack core.
This function will be called when filling out a resource, allowing the
driver to add driver-specific details.  The details consist of a
nltable of nested attributes, that are in the form of <key, [print-type],
value> tuples.  Both key and value attributes are mandatory.  The key
nlattr must be a string, and the value nlattr can be one of the driver
attributes that are generic, but typed, allowing the attributes to be
validated.  Currently the driver nlattr types include string, s32,
u32, s64, and u64.  The print-type nlattr allows a driver to specify
an alternative display format for user tools displaying the attribute.
For example, a u32 attribute will default to "%u", but a print-type
attribute can be included for it to be displayed in hex.  This allows
the user tool to print the number in the format desired by the driver
driver.

More attrs can be defined as they become needed by drivers.
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Reviewed-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 25a0ad85
...@@ -98,6 +98,15 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = { ...@@ -98,6 +98,15 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
[RDMA_NLDEV_ATTR_NDEV_INDEX] = { .type = NLA_U32 }, [RDMA_NLDEV_ATTR_NDEV_INDEX] = { .type = NLA_U32 },
[RDMA_NLDEV_ATTR_NDEV_NAME] = { .type = NLA_NUL_STRING, [RDMA_NLDEV_ATTR_NDEV_NAME] = { .type = NLA_NUL_STRING,
.len = IFNAMSIZ }, .len = IFNAMSIZ },
[RDMA_NLDEV_ATTR_DRIVER] = { .type = NLA_NESTED },
[RDMA_NLDEV_ATTR_DRIVER_ENTRY] = { .type = NLA_NESTED },
[RDMA_NLDEV_ATTR_DRIVER_STRING] = { .type = NLA_NUL_STRING,
.len = RDMA_NLDEV_ATTR_ENTRY_STRLEN },
[RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE] = { .type = NLA_U8 },
[RDMA_NLDEV_ATTR_DRIVER_S32] = { .type = NLA_S32 },
[RDMA_NLDEV_ATTR_DRIVER_U32] = { .type = NLA_U32 },
[RDMA_NLDEV_ATTR_DRIVER_S64] = { .type = NLA_S64 },
[RDMA_NLDEV_ATTR_DRIVER_U64] = { .type = NLA_U64 },
}; };
static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device) static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
...@@ -285,6 +294,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -285,6 +294,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, struct netlink_callback *cb,
struct rdma_restrack_entry *res, uint32_t port) struct rdma_restrack_entry *res, uint32_t port)
{ {
struct ib_qp *qp = container_of(res, struct ib_qp, res); struct ib_qp *qp = container_of(res, struct ib_qp, res);
struct rdma_restrack_root *resroot = &qp->device->res;
struct ib_qp_init_attr qp_init_attr; struct ib_qp_init_attr qp_init_attr;
struct nlattr *entry_attr; struct nlattr *entry_attr;
struct ib_qp_attr qp_attr; struct ib_qp_attr qp_attr;
...@@ -334,6 +344,9 @@ static int fill_res_qp_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -334,6 +344,9 @@ static int fill_res_qp_entry(struct sk_buff *msg, struct netlink_callback *cb,
if (fill_res_name_pid(msg, res)) if (fill_res_name_pid(msg, res))
goto err; goto err;
if (resroot->fill_res_entry(msg, res))
goto err;
nla_nest_end(msg, entry_attr); nla_nest_end(msg, entry_attr);
return 0; return 0;
...@@ -349,6 +362,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, ...@@ -349,6 +362,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg,
{ {
struct rdma_id_private *id_priv = struct rdma_id_private *id_priv =
container_of(res, struct rdma_id_private, res); container_of(res, struct rdma_id_private, res);
struct rdma_restrack_root *resroot = &id_priv->id.device->res;
struct rdma_cm_id *cm_id = &id_priv->id; struct rdma_cm_id *cm_id = &id_priv->id;
struct nlattr *entry_attr; struct nlattr *entry_attr;
...@@ -390,6 +404,9 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, ...@@ -390,6 +404,9 @@ static int fill_res_cm_id_entry(struct sk_buff *msg,
if (fill_res_name_pid(msg, res)) if (fill_res_name_pid(msg, res))
goto err; goto err;
if (resroot->fill_res_entry(msg, res))
goto err;
nla_nest_end(msg, entry_attr); nla_nest_end(msg, entry_attr);
return 0; return 0;
...@@ -403,6 +420,7 @@ static int fill_res_cq_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -403,6 +420,7 @@ static int fill_res_cq_entry(struct sk_buff *msg, struct netlink_callback *cb,
struct rdma_restrack_entry *res, uint32_t port) struct rdma_restrack_entry *res, uint32_t port)
{ {
struct ib_cq *cq = container_of(res, struct ib_cq, res); struct ib_cq *cq = container_of(res, struct ib_cq, res);
struct rdma_restrack_root *resroot = &cq->device->res;
struct nlattr *entry_attr; struct nlattr *entry_attr;
entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_CQ_ENTRY); entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_CQ_ENTRY);
...@@ -423,6 +441,9 @@ static int fill_res_cq_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -423,6 +441,9 @@ static int fill_res_cq_entry(struct sk_buff *msg, struct netlink_callback *cb,
if (fill_res_name_pid(msg, res)) if (fill_res_name_pid(msg, res))
goto err; goto err;
if (resroot->fill_res_entry(msg, res))
goto err;
nla_nest_end(msg, entry_attr); nla_nest_end(msg, entry_attr);
return 0; return 0;
...@@ -436,6 +457,7 @@ static int fill_res_mr_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -436,6 +457,7 @@ static int fill_res_mr_entry(struct sk_buff *msg, struct netlink_callback *cb,
struct rdma_restrack_entry *res, uint32_t port) struct rdma_restrack_entry *res, uint32_t port)
{ {
struct ib_mr *mr = container_of(res, struct ib_mr, res); struct ib_mr *mr = container_of(res, struct ib_mr, res);
struct rdma_restrack_root *resroot = &mr->pd->device->res;
struct nlattr *entry_attr; struct nlattr *entry_attr;
entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_MR_ENTRY); entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_MR_ENTRY);
...@@ -459,6 +481,9 @@ static int fill_res_mr_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -459,6 +481,9 @@ static int fill_res_mr_entry(struct sk_buff *msg, struct netlink_callback *cb,
if (fill_res_name_pid(msg, res)) if (fill_res_name_pid(msg, res))
goto err; goto err;
if (resroot->fill_res_entry(msg, res))
goto err;
nla_nest_end(msg, entry_attr); nla_nest_end(msg, entry_attr);
return 0; return 0;
...@@ -472,6 +497,7 @@ static int fill_res_pd_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -472,6 +497,7 @@ static int fill_res_pd_entry(struct sk_buff *msg, struct netlink_callback *cb,
struct rdma_restrack_entry *res, uint32_t port) struct rdma_restrack_entry *res, uint32_t port)
{ {
struct ib_pd *pd = container_of(res, struct ib_pd, res); struct ib_pd *pd = container_of(res, struct ib_pd, res);
struct rdma_restrack_root *resroot = &pd->device->res;
struct nlattr *entry_attr; struct nlattr *entry_attr;
entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_PD_ENTRY); entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_PD_ENTRY);
...@@ -498,6 +524,9 @@ static int fill_res_pd_entry(struct sk_buff *msg, struct netlink_callback *cb, ...@@ -498,6 +524,9 @@ static int fill_res_pd_entry(struct sk_buff *msg, struct netlink_callback *cb,
if (fill_res_name_pid(msg, res)) if (fill_res_name_pid(msg, res))
goto err; goto err;
if (resroot->fill_res_entry(msg, res))
goto err;
nla_nest_end(msg, entry_attr); nla_nest_end(msg, entry_attr);
return 0; return 0;
......
...@@ -12,9 +12,16 @@ ...@@ -12,9 +12,16 @@
#include "cma_priv.h" #include "cma_priv.h"
static int fill_res_noop(struct sk_buff *msg,
struct rdma_restrack_entry *entry)
{
return 0;
}
void rdma_restrack_init(struct rdma_restrack_root *res) void rdma_restrack_init(struct rdma_restrack_root *res)
{ {
init_rwsem(&res->rwsem); init_rwsem(&res->rwsem);
res->fill_res_entry = fill_res_noop;
} }
static const char *type2str(enum rdma_restrack_type type) static const char *type2str(enum rdma_restrack_type type)
......
...@@ -44,6 +44,8 @@ enum rdma_restrack_type { ...@@ -44,6 +44,8 @@ enum rdma_restrack_type {
}; };
#define RDMA_RESTRACK_HASH_BITS 8 #define RDMA_RESTRACK_HASH_BITS 8
struct rdma_restrack_entry;
/** /**
* struct rdma_restrack_root - main resource tracking management * struct rdma_restrack_root - main resource tracking management
* entity, per-device * entity, per-device
...@@ -57,6 +59,13 @@ struct rdma_restrack_root { ...@@ -57,6 +59,13 @@ struct rdma_restrack_root {
* @hash: global database for all resources per-device * @hash: global database for all resources per-device
*/ */
DECLARE_HASHTABLE(hash, RDMA_RESTRACK_HASH_BITS); DECLARE_HASHTABLE(hash, RDMA_RESTRACK_HASH_BITS);
/**
* @fill_res_entry: driver-specific fill function
*
* Allows rdma drivers to add their own restrack attributes.
*/
int (*fill_res_entry)(struct sk_buff *msg,
struct rdma_restrack_entry *entry);
}; };
/** /**
......
...@@ -249,6 +249,15 @@ enum rdma_nldev_command { ...@@ -249,6 +249,15 @@ enum rdma_nldev_command {
RDMA_NLDEV_NUM_OPS RDMA_NLDEV_NUM_OPS
}; };
enum {
RDMA_NLDEV_ATTR_ENTRY_STRLEN = 16,
};
enum rdma_nldev_print_type {
RDMA_NLDEV_PRINT_TYPE_UNSPEC,
RDMA_NLDEV_PRINT_TYPE_HEX,
};
enum rdma_nldev_attr { enum rdma_nldev_attr {
/* don't change the order or add anything between, this is ABI! */ /* don't change the order or add anything between, this is ABI! */
RDMA_NLDEV_ATTR_UNSPEC, RDMA_NLDEV_ATTR_UNSPEC,
...@@ -390,6 +399,20 @@ enum rdma_nldev_attr { ...@@ -390,6 +399,20 @@ enum rdma_nldev_attr {
RDMA_NLDEV_ATTR_RES_PD_ENTRY, /* nested table */ RDMA_NLDEV_ATTR_RES_PD_ENTRY, /* nested table */
RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY, /* u32 */ RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY, /* u32 */
RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY, /* u32 */ RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY, /* u32 */
/*
* driver-specific attributes.
*/
RDMA_NLDEV_ATTR_DRIVER, /* nested table */
RDMA_NLDEV_ATTR_DRIVER_ENTRY, /* nested table */
RDMA_NLDEV_ATTR_DRIVER_STRING, /* string */
/*
* u8 values from enum rdma_nldev_print_type
*/
RDMA_NLDEV_ATTR_DRIVER_PRINT_TYPE, /* u8 */
RDMA_NLDEV_ATTR_DRIVER_S32, /* s32 */
RDMA_NLDEV_ATTR_DRIVER_U32, /* u32 */
RDMA_NLDEV_ATTR_DRIVER_S64, /* s64 */
RDMA_NLDEV_ATTR_DRIVER_U64, /* u64 */
/* /*
* Provides logical name and index of netdevice which is * Provides logical name and index of netdevice which is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment