Skip to content

Commit

Permalink
RDMA/nldev: Add support to get status of all counters
Browse files Browse the repository at this point in the history
This patch adds the ability to get the name, index and status of all
counters for each link through RDMA netlink. This can be used for
user-space to get the current optional-counter mode.

Examples:
$ rdma statistic mode
link rocep8s0f0/1 optional-counters cc_rx_ce_pkts

$ rdma statistic mode supported
link rocep8s0f0/1 supported optional-counters cc_rx_ce_pkts,cc_rx_cnp_pkts,cc_tx_cnp_pkts
link rocep8s0f1/1 supported optional-counters cc_rx_ce_pkts,cc_rx_cnp_pkts,cc_tx_cnp_pkts

Link: https://lore.kernel.org/r/20211008122439.166063-8-markzhang@nvidia.com
Signed-off-by: Aharon Landau <aharonl@nvidia.com>
Signed-off-by: Neta Ostrovsky <netao@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
  • Loading branch information
Aharon Landau authored and Jason Gunthorpe committed Oct 12, 2021
1 parent 5e2ddd1 commit 7301d0a
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
98 changes: 98 additions & 0 deletions drivers/infiniband/core/nldev.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
[RDMA_NLDEV_NET_NS_FD] = { .type = NLA_U32 },
[RDMA_NLDEV_SYS_ATTR_NETNS_MODE] = { .type = NLA_U8 },
[RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK] = { .type = NLA_U8 },
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX] = { .type = NLA_U32 },
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC] = { .type = NLA_U8 },
};

static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
Expand Down Expand Up @@ -2264,6 +2266,99 @@ static int nldev_stat_get_dumpit(struct sk_buff *skb,
return ret;
}

static int nldev_stat_get_counter_status_doit(struct sk_buff *skb,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX], *table, *entry;
struct rdma_hw_stats *stats;
struct ib_device *device;
struct sk_buff *msg;
u32 devid, port;
int ret, i;

ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
nldev_policy, extack);
if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX] ||
!tb[RDMA_NLDEV_ATTR_PORT_INDEX])
return -EINVAL;

devid = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
device = ib_device_get_by_index(sock_net(skb->sk), devid);
if (!device)
return -EINVAL;

port = nla_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
if (!rdma_is_port_valid(device, port)) {
ret = -EINVAL;
goto err;
}

stats = ib_get_hw_stats_port(device, port);
if (!stats) {
ret = -EINVAL;
goto err;
}

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
goto err;
}

nlh = nlmsg_put(
msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_STAT_GET_STATUS),
0, 0);

ret = -EMSGSIZE;
if (fill_nldev_handle(msg, device) ||
nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port))
goto err_msg;

table = nla_nest_start(msg, RDMA_NLDEV_ATTR_STAT_HWCOUNTERS);
if (!table)
goto err_msg;

mutex_lock(&stats->lock);
for (i = 0; i < stats->num_counters; i++) {
entry = nla_nest_start(msg,
RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY);
if (!entry)
goto err_msg_table;

if (nla_put_string(msg,
RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_NAME,
stats->descs[i].name) ||
nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX, i))
goto err_msg_entry;

if ((stats->descs[i].flags & IB_STAT_FLAG_OPTIONAL) &&
(nla_put_u8(msg, RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC,
!test_bit(i, stats->is_disabled))))
goto err_msg_entry;

nla_nest_end(msg, entry);
}
mutex_unlock(&stats->lock);

nla_nest_end(msg, table);
nlmsg_end(msg, nlh);
ib_device_put(device);
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);

err_msg_entry:
nla_nest_cancel(msg, entry);
err_msg_table:
mutex_unlock(&stats->lock);
nla_nest_cancel(msg, table);
err_msg:
nlmsg_free(msg);
err:
ib_device_put(device);
return ret;
}

static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
[RDMA_NLDEV_CMD_GET] = {
.doit = nldev_get_doit,
Expand Down Expand Up @@ -2353,6 +2448,9 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
.dump = nldev_res_get_mr_raw_dumpit,
.flags = RDMA_NL_ADMIN_PERM,
},
[RDMA_NLDEV_CMD_STAT_GET_STATUS] = {
.doit = nldev_stat_get_counter_status_doit,
},
};

void __init nldev_init(void)
Expand Down
5 changes: 5 additions & 0 deletions include/uapi/rdma/rdma_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ enum rdma_nldev_command {

RDMA_NLDEV_CMD_RES_SRQ_GET, /* can dump */

RDMA_NLDEV_CMD_STAT_GET_STATUS,

RDMA_NLDEV_NUM_OPS
};

Expand Down Expand Up @@ -549,6 +551,9 @@ enum rdma_nldev_attr {

RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK, /* u8 */

RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX, /* u32 */
RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC, /* u8 */

/*
* Always the end
*/
Expand Down

0 comments on commit 7301d0a

Please sign in to comment.