rdma: Add support to get QP in raw format

Add 'raw' argument to get the resource in raw format.
When RDMA_NLDEV_ATTR_RES_RAW is set in the netlink message,
then the resource fields are in raw format, print it as byte array.

Example:
$rdma res show qp link rocep0s12f0/1 lqpn 1137 -j -r
[{"ifindex":7,"ifname":"mlx5_1","port":1,
"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...]}]

Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
Maor Gottlieb 2020-06-24 13:40:10 +03:00 committed by David Ahern
parent 8f23492823
commit 7c01e0fc9c
7 changed files with 81 additions and 11 deletions

View File

@ -83,6 +83,11 @@ rdma res show qp link mlx5_4/1 lqpn 0-6
Limit to specific Local QPNs.
.RE
.PP
rdma res show qp link mlx5_4/1 lqpn 6 -r
.RS 4
Driver specific details in raw format.
.RE
.PP
rdma resource show cm_id dst-port 7174
.RS 4
Show CM_IDs with destination ip port of 7174.

View File

@ -51,6 +51,10 @@ If there were any errors during execution of the commands, the application retur
.BR "\-d" , " --details"
Output detailed information. Adding a second \-d includes driver-specific details.
.TP
.BR "\-r" , " --raw"
Output includes driver-specific details in raw format.
.TP
.BR "\-p" , " --pretty"
When combined with -j generate a pretty JSON output.

View File

@ -13,7 +13,7 @@ static void help(char *name)
pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n"
" %s [ -f[orce] ] -b[atch] filename\n"
"where OBJECT := { dev | link | resource | system | statistic | help }\n"
" OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty]}\n", name, name);
" OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty] -r[aw]}\n", name, name);
}
static int cmd_help(struct rd *rd)
@ -112,6 +112,7 @@ int main(int argc, char **argv)
{ "json", no_argument, NULL, 'j' },
{ "pretty", no_argument, NULL, 'p' },
{ "details", no_argument, NULL, 'd' },
{ "raw", no_argument, NULL, 'r' },
{ "force", no_argument, NULL, 'f' },
{ "batch", required_argument, NULL, 'b' },
{ NULL, 0, NULL, 0 }
@ -120,6 +121,7 @@ int main(int argc, char **argv)
const char *batch_file = NULL;
bool show_details = false;
bool json_output = false;
bool show_raw = false;
bool force = false;
struct rd rd = {};
char *filename;
@ -127,7 +129,7 @@ int main(int argc, char **argv)
int err;
filename = basename(argv[0]);
while ((opt = getopt_long(argc, argv, ":Vhdpjfb:",
while ((opt = getopt_long(argc, argv, ":Vhdrpjfb:",
long_options, NULL)) >= 0) {
switch (opt) {
case 'V':
@ -143,6 +145,9 @@ int main(int argc, char **argv)
else
show_details = true;
break;
case 'r':
show_raw = true;
break;
case 'j':
json_output = 1;
break;
@ -172,6 +177,7 @@ int main(int argc, char **argv)
rd.show_driver_details = show_driver_details;
rd.json_output = json_output;
rd.pretty_output = pretty;
rd.show_raw = show_raw;
err = rd_init(&rd, filename);
if (err)

View File

@ -57,8 +57,9 @@ struct rd {
int argc;
char **argv;
char *filename;
bool show_details;
bool show_driver_details;
uint8_t show_details:1;
uint8_t show_driver_details:1;
uint8_t show_raw:1;
struct list_head dev_map_list;
uint32_t dev_idx;
uint32_t port_idx;
@ -134,9 +135,11 @@ int rd_attr_check(const struct nlattr *attr, int *typep);
* Print helpers
*/
void print_driver_table(struct rd *rd, struct nlattr *tb);
void print_raw_data(struct rd *rd, struct nlattr **nla_line);
void newline(struct rd *rd);
void newline_indent(struct rd *rd);
void print_on_off(struct rd *rd, const char *key_str, bool on);
void print_raw_data(struct rd *rd, struct nlattr **nla_line);
#define MAX_LINE_LENGTH 80
#endif /* _RDMA_TOOL_H_ */

View File

@ -64,6 +64,20 @@ static void print_pathmig(struct rd *rd, uint32_t val, struct nlattr **nla_line)
"path-mig-state %s ", path_mig_to_str(val));
}
static int res_qp_line_raw(struct rd *rd, const char *name, int idx,
struct nlattr **nla_line)
{
if (!nla_line[RDMA_NLDEV_ATTR_RES_RAW])
return MNL_CB_ERROR;
open_json_object(NULL);
print_link(rd, idx, name, rd->port_idx, nla_line);
print_raw_data(rd, nla_line);
newline(rd);
return MNL_CB_OK;
}
static int res_qp_line(struct rd *rd, const char *name, int idx,
struct nlattr **nla_line)
{
@ -184,7 +198,8 @@ int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
return res_qp_line(rd, name, idx, tb);
return (rd->show_raw) ? res_qp_line_raw(rd, name, idx, tb) :
res_qp_line(rd, name, idx, tb);
}
int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
@ -212,7 +227,8 @@ int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
if (ret != MNL_CB_OK)
break;
ret = res_qp_line(rd, name, idx, nla_line);
ret = (rd->show_raw) ? res_qp_line_raw(rd, name, idx, nla_line) :
res_qp_line(rd, name, idx, nla_line);
if (ret != MNL_CB_OK)
break;
}

View File

@ -23,24 +23,40 @@ int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data);
int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
static inline uint32_t res_get_command(uint32_t command, struct rd *rd)
{
if (!rd->show_raw)
return command;
switch (command) {
case RDMA_NLDEV_CMD_RES_QP_GET:
return RDMA_NLDEV_CMD_RES_QP_GET_RAW;
default:
return command;
}
}
#define RES_FUNC(name, command, valid_filters, strict_port, id) \
static inline int _##name(struct rd *rd) \
{ \
uint32_t idx; \
uint32_t idx, _command; \
int ret; \
_command = res_get_command(command, rd); \
if (id) { \
ret = rd_doit_index(rd, &idx); \
if (ret) { \
rd->suppress_errors = true; \
ret = _res_send_idx_msg(rd, command, \
ret = _res_send_idx_msg(rd, _command, \
name##_idx_parse_cb, \
idx, id); \
if (!ret) \
if (!ret || rd->show_raw) \
return ret; \
/* Fallback for old systems without .doit callbacks */ \
/* Fallback for old systems without .doit callbacks. \
* Kernel that supports raw, for sure supports doit. \
*/ \
} \
} \
return _res_send_msg(rd, command, name##_parse_cb); \
return _res_send_msg(rd, _command, name##_parse_cb); \
} \
static inline int name(struct rd *rd) \
{ \

View File

@ -450,6 +450,7 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
[RDMA_NLDEV_ATTR_STAT_RES] = MNL_TYPE_U32,
[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK] = MNL_TYPE_U32,
[RDMA_NLDEV_ATTR_DEV_DIM] = MNL_TYPE_U8,
[RDMA_NLDEV_ATTR_RES_RAW] = MNL_TYPE_BINARY,
};
int rd_attr_check(const struct nlattr *attr, int *typep)
@ -890,6 +891,25 @@ static int print_driver_entry(struct rd *rd, struct nlattr *key_attr,
return ret;
}
void print_raw_data(struct rd *rd, struct nlattr **nla_line)
{
uint8_t *data;
uint32_t len;
int i = 0;
if (!rd->show_raw)
return;
len = mnl_attr_get_payload_len(nla_line[RDMA_NLDEV_ATTR_RES_RAW]);
data = mnl_attr_get_payload(nla_line[RDMA_NLDEV_ATTR_RES_RAW]);
open_json_array(PRINT_JSON, "data");
while (i < len) {
print_color_uint(PRINT_ANY, COLOR_NONE, NULL, "%d", data[i]);
i++;
}
close_json_array(PRINT_ANY, ">");
}
void print_driver_table(struct rd *rd, struct nlattr *tb)
{
int print_type = RDMA_NLDEV_PRINT_TYPE_UNSPEC;