Merge branch 'rdma-mr-stats' into next

Leon Romanovsky  says:

====================

This is supplementary part of "ODP information and statistics"
kernel series.
https://lore.kernel.org/linux-rdma/20191016062308.11886-1-leon@kernel.org

====================

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2019-10-27 10:28:49 -07:00
commit 9a1e4561f1
6 changed files with 144 additions and 10 deletions

View File

@ -1,4 +1,4 @@
.TH RDMA\-STATISTIC 8 "17 Mar 2019" "iproute2" "Linux"
.TH RDMA\-STATISTIC 8 "27 June 2019" "iproute2" "Linux"
.SH NAME
rdma-statistic \- RDMA statistic counter configuration
.SH SYNOPSIS
@ -15,7 +15,7 @@ rdma-statistic \- RDMA statistic counter configuration
.ti -8
.B rdma statistic
.RI "[ " OBJECT " ]"
.RI "{ " OBJECT " }"
.B show
.ti -8
@ -63,7 +63,7 @@ rdma-statistic \- RDMA statistic counter configuration
.ti -8
.IR OBJECT " := "
.RB "{ " qp " }"
.RB "{ " qp " | " mr " }"
.ti -8
.IR CRITERIA " := "
@ -80,13 +80,13 @@ rdma-statistic \- RDMA statistic counter configuration
- specifies counters on this RDMA port to show.
.SS rdma statistic <object> set - configure counter statistic auto-mode for a specific device/port
In auto mode all objects belong to one category are bind automatically to a single counter set.
In auto mode all objects belong to one category are bind automatically to a single counter set. Not applicable for MR's.
.SS rdma statistic <object> bind - manually bind an object (e.g., a qp) with a counter
When bound the statistics of this object are available in this counter.
When bound the statistics of this object are available in this counter. Not applicable for MR's.
.SS rdma statistic <object> unbind - manually unbind an object (e.g., a qp) from the counter previously bound
When unbound the statistics of this object are no longer available in this counter; And if object id is not specified then all objects on this counter will be unbound.
When unbound the statistics of this object are no longer available in this counter; And if object id is not specified then all objects on this counter will be unbound. Not applicable for MR's.
.I "COUNTER-ID"
- specifies the id of the counter to be bound.
@ -152,9 +152,16 @@ On device mlx5_2 port 1, bind the specified qp on the specified counter
rdma statistic qp unbind link mlx5_2/1 cntn 4
.RS 4
On device mlx5_2 port 1, unbind all QPs on the specified counter. After that this counter will be released automatically by the kernel.
.RE
.PP
rdma statistic show mr
.RS 4
List all currently allocated MR's and their counters.
.RE
.PP
rdma statistic show mr mrn 6
.RS 4
Dump a specific MR statistics with mrn 6. Dumps nothing if does not exists.
.SH SEE ALSO
.BR rdma (8),
@ -163,5 +170,7 @@ On device mlx5_2 port 1, unbind all QPs on the specified counter. After that thi
.BR rdma-resource (8),
.br
.SH AUTHOR
.SH AUTHORS
Mark Zhang <markz@mellanox.com>
.br
Erez Alfasi <ereza@mellanox.com>

View File

@ -7,7 +7,7 @@ ifeq ($(HAVE_MNL),y)
CFLAGS += -I./include/uapi/
RDMA_OBJ = rdma.o utils.o dev.o link.o res.o res-pd.o res-mr.o res-cq.o \
res-cmid.o res-qp.o sys.o stat.o
res-cmid.o res-qp.o sys.o stat.o stat-mr.o
TARGETS += rdma
endif

View File

@ -103,6 +103,10 @@ int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
mnl_attr_put_u32(rd->nlh, id, idx);
if (command == RDMA_NLDEV_CMD_STAT_GET)
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES,
RDMA_NLDEV_ATTR_RES_MR);
ret = rd_send_msg(rd);
if (ret)
return ret;
@ -130,6 +134,10 @@ int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback)
mnl_attr_put_u32(rd->nlh,
RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
if (command == RDMA_NLDEV_CMD_STAT_GET)
mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES,
RDMA_NLDEV_ATTR_RES_MR);
ret = rd_send_msg(rd);
if (ret)
return ret;

88
rdma/stat-mr.c Normal file
View File

@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/*
* stat-mr.c RDMA tool
* Authors: Erez Alfasi <ereza@mellanox.com>
*/
#include "res.h"
#include "stat.h"
#include <inttypes.h>
static int stat_mr_line(struct rd *rd, const char *name, int idx,
struct nlattr **nla_line)
{
uint32_t mrn = 0;
int ret;
if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
mrn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
if (rd_is_filtered_attr(rd, "mrn", mrn,
nla_line[RDMA_NLDEV_ATTR_RES_MRN]))
goto out;
if (rd->json_output)
jsonw_start_array(rd->jw);
print_dev(rd, idx, name);
res_print_uint(rd, "mrn", mrn, nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
if (nla_line[RDMA_NLDEV_ATTR_STAT_HWCOUNTERS]) {
ret = res_get_hwcounters(
rd, nla_line[RDMA_NLDEV_ATTR_STAT_HWCOUNTERS], true);
if (ret != MNL_CB_OK)
return ret;
}
newline(rd);
out:
return MNL_CB_OK;
}
int stat_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
struct rd *rd = data;
const char *name;
uint32_t idx;
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
return MNL_CB_ERROR;
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
return stat_mr_line(rd, name, idx, tb);
}
int stat_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
{
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
struct nlattr *nla_table, *nla_entry;
struct rd *rd = data;
int ret = MNL_CB_OK;
const char *name;
uint32_t idx;
mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
!tb[RDMA_NLDEV_ATTR_RES_MR])
return MNL_CB_ERROR;
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
nla_table = tb[RDMA_NLDEV_ATTR_RES_MR];
mnl_attr_for_each_nested(nla_entry, nla_table) {
struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
if (ret != MNL_CB_OK)
break;
ret = stat_mr_line(rd, name, idx, nla_line);
if (ret != MNL_CB_OK)
break;
}
return ret;
}

View File

@ -6,6 +6,7 @@
#include "rdma.h"
#include "res.h"
#include "stat.h"
#include <inttypes.h>
static int stat_help(struct rd *rd)
@ -174,7 +175,7 @@ static int stat_qp_get_mode(struct rd *rd)
return rd_exec_cmd(rd, cmds, "parameter");
}
static int res_get_hwcounters(struct rd *rd, struct nlattr *hwc_table, bool print)
int res_get_hwcounters(struct rd *rd, struct nlattr *hwc_table, bool print)
{
struct nlattr *nla_entry;
const char *nm;
@ -737,6 +738,7 @@ static int stat_show(struct rd *rd)
const struct rd_cmd cmds[] = {
{ NULL, stat_show_link },
{ "link", stat_show_link },
{ "mr", stat_mr },
{ "help", stat_help },
{ 0 }
};
@ -752,6 +754,7 @@ int cmd_stat(struct rd *rd)
{ "list", stat_show },
{ "help", stat_help },
{ "qp", stat_qp },
{ "mr", stat_mr },
{ 0 }
};

26
rdma/stat.h Normal file
View File

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/*
* stat.h RDMA tool
* Authors: Mark Zhang <markz@mellanox.com>
* Erez Alfasi <ereza@mellanox.com>
*/
#ifndef _RDMA_TOOL_STAT_H_
#define _RDMA_TOOL_STAT_H_
#include "rdma.h"
int res_get_hwcounters(struct rd *rd, struct nlattr *hwc_table,
bool print);
int stat_mr_parse_cb(const struct nlmsghdr *nlh, void *data);
int stat_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
static const
struct filters stat_mr_valid_filters[MAX_NUMBER_OF_FILTERS] = {
{ .name = "mrn", .is_number = true, .is_doit = true },
};
RES_FUNC(stat_mr, RDMA_NLDEV_CMD_STAT_GET, stat_mr_valid_filters, true,
RDMA_NLDEV_ATTR_RES_MRN);
#endif /* _RDMA_TOOL_STAT_H_ */