Skip to content

Commit bf3c5a9

Browse files
Leon Romanovskyjgunthorpe
authored andcommitted
RDMA/nldev: Provide global resource utilization
Expose through the netlink interface the global per-device utilization of the supported object types. Provide both dumpit and doit callbacks. As an example of possible output from rdmatool for system with 5 mlx5 cards: $ rdma res 1: mlx5_0: qp 4 cq 5 pd 3 2: mlx5_1: qp 4 cq 5 pd 3 3: mlx5_2: qp 4 cq 5 pd 3 4: mlx5_3: qp 2 cq 3 pd 2 5: mlx5_4: qp 4 cq 5 pd 3 Reviewed-by: Mark Bloch <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Reviewed-by: Steve Wise <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 9d5f8c2 commit bf3c5a9

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

drivers/infiniband/core/nldev.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
*/
3232

3333
#include <linux/module.h>
34+
#include <linux/pid.h>
35+
#include <linux/pid_namespace.h>
3436
#include <net/netlink.h>
3537
#include <rdma/rdma_netlink.h>
3638

@@ -52,6 +54,11 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
5254
[RDMA_NLDEV_ATTR_PORT_STATE] = { .type = NLA_U8 },
5355
[RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = { .type = NLA_U8 },
5456
[RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = { .type = NLA_U8 },
57+
[RDMA_NLDEV_ATTR_RES_SUMMARY] = { .type = NLA_NESTED },
58+
[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY] = { .type = NLA_NESTED },
59+
[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = { .type = NLA_NUL_STRING,
60+
.len = 16 },
61+
[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = { .type = NLA_U64 },
5562
};
5663

5764
static int fill_nldev_handle(struct sk_buff *msg, struct ib_device *device)
@@ -134,6 +141,65 @@ static int fill_port_info(struct sk_buff *msg,
134141
return 0;
135142
}
136143

144+
static int fill_res_info_entry(struct sk_buff *msg,
145+
const char *name, u64 curr)
146+
{
147+
struct nlattr *entry_attr;
148+
149+
entry_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY);
150+
if (!entry_attr)
151+
return -EMSGSIZE;
152+
153+
if (nla_put_string(msg, RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME, name))
154+
goto err;
155+
if (nla_put_u64_64bit(msg,
156+
RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR, curr, 0))
157+
goto err;
158+
159+
nla_nest_end(msg, entry_attr);
160+
return 0;
161+
162+
err:
163+
nla_nest_cancel(msg, entry_attr);
164+
return -EMSGSIZE;
165+
}
166+
167+
static int fill_res_info(struct sk_buff *msg, struct ib_device *device)
168+
{
169+
static const char * const names[RDMA_RESTRACK_MAX] = {
170+
[RDMA_RESTRACK_PD] = "pd",
171+
[RDMA_RESTRACK_CQ] = "cq",
172+
[RDMA_RESTRACK_QP] = "qp",
173+
};
174+
175+
struct rdma_restrack_root *res = &device->res;
176+
struct nlattr *table_attr;
177+
int ret, i, curr;
178+
179+
if (fill_nldev_handle(msg, device))
180+
return -EMSGSIZE;
181+
182+
table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_SUMMARY);
183+
if (!table_attr)
184+
return -EMSGSIZE;
185+
186+
for (i = 0; i < RDMA_RESTRACK_MAX; i++) {
187+
if (!names[i])
188+
continue;
189+
curr = rdma_restrack_count(res, i, task_active_pid_ns(current));
190+
ret = fill_res_info_entry(msg, names[i], curr);
191+
if (ret)
192+
goto err;
193+
}
194+
195+
nla_nest_end(msg, table_attr);
196+
return 0;
197+
198+
err:
199+
nla_nest_cancel(msg, table_attr);
200+
return ret;
201+
}
202+
137203
static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
138204
struct netlink_ext_ack *extack)
139205
{
@@ -329,6 +395,83 @@ static int nldev_port_get_dumpit(struct sk_buff *skb,
329395
return skb->len;
330396
}
331397

398+
static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
399+
struct netlink_ext_ack *extack)
400+
{
401+
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
402+
struct ib_device *device;
403+
struct sk_buff *msg;
404+
u32 index;
405+
int ret;
406+
407+
ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
408+
nldev_policy, extack);
409+
if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
410+
return -EINVAL;
411+
412+
index = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
413+
device = ib_device_get_by_index(index);
414+
if (!device)
415+
return -EINVAL;
416+
417+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
418+
if (!msg)
419+
goto err;
420+
421+
nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
422+
RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
423+
0, 0);
424+
425+
ret = fill_res_info(msg, device);
426+
if (ret)
427+
goto err_free;
428+
429+
nlmsg_end(msg, nlh);
430+
put_device(&device->dev);
431+
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
432+
433+
err_free:
434+
nlmsg_free(msg);
435+
err:
436+
put_device(&device->dev);
437+
return ret;
438+
}
439+
440+
static int _nldev_res_get_dumpit(struct ib_device *device,
441+
struct sk_buff *skb,
442+
struct netlink_callback *cb,
443+
unsigned int idx)
444+
{
445+
int start = cb->args[0];
446+
struct nlmsghdr *nlh;
447+
448+
if (idx < start)
449+
return 0;
450+
451+
nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
452+
RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
453+
0, NLM_F_MULTI);
454+
455+
if (fill_res_info(skb, device)) {
456+
nlmsg_cancel(skb, nlh);
457+
goto out;
458+
}
459+
460+
nlmsg_end(skb, nlh);
461+
462+
idx++;
463+
464+
out:
465+
cb->args[0] = idx;
466+
return skb->len;
467+
}
468+
469+
static int nldev_res_get_dumpit(struct sk_buff *skb,
470+
struct netlink_callback *cb)
471+
{
472+
return ib_enum_all_devs(_nldev_res_get_dumpit, skb, cb);
473+
}
474+
332475
static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
333476
[RDMA_NLDEV_CMD_GET] = {
334477
.doit = nldev_get_doit,
@@ -338,6 +481,10 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
338481
.doit = nldev_port_get_doit,
339482
.dump = nldev_port_get_dumpit,
340483
},
484+
[RDMA_NLDEV_CMD_RES_GET] = {
485+
.doit = nldev_res_get_doit,
486+
.dump = nldev_res_get_dumpit,
487+
},
341488
};
342489

343490
void __init nldev_init(void)

include/uapi/rdma/rdma_netlink.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ enum rdma_nldev_command {
236236
RDMA_NLDEV_CMD_PORT_NEW,
237237
RDMA_NLDEV_CMD_PORT_DEL,
238238

239+
RDMA_NLDEV_CMD_RES_GET, /* can dump */
240+
239241
RDMA_NLDEV_NUM_OPS
240242
};
241243

@@ -303,6 +305,11 @@ enum rdma_nldev_attr {
303305

304306
RDMA_NLDEV_ATTR_DEV_NODE_TYPE, /* u8 */
305307

308+
RDMA_NLDEV_ATTR_RES_SUMMARY, /* nested table */
309+
RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY, /* nested table */
310+
RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME, /* string */
311+
RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR, /* u64 */
312+
306313
RDMA_NLDEV_ATTR_MAX
307314
};
308315
#endif /* _UAPI_RDMA_NETLINK_H */

0 commit comments

Comments
 (0)