* [PATCH iproute2-next 00/10] RDMA resource tracking
@ 2018-01-31 8:11 Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 01/10] rdma: Add option to provide "-" sign for the port number Leon Romanovsky
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw)
To: David Ahern
Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev,
Stephen Hemminger
Changelog:
v2 -> v3:
* Rebased to commit: 1e24e773f144 ("Merge branch 'iproute2-master' into iproute2-next")
* Refreshed include/uapi/rdma/rdma_netlink.h file
* Fixed bug, where cxgb4 was printed twice.
v1 -> v2;
* Added checks for all occurrences of strdup failures and added patch
with fix of already merged code.
* Sync with latest kernel code.
* Rewrote table representation to be similar to "ip route" output.
* Implemented string filters.
* Removed curr/max representation from the summary output.
v0 -> v1:
* Fixed subject title in patch #1: rdam -> rdma.
* Added newline between variable declaration and the code.
* Add check to failure in strdup() call in rd_check_is_string_filtered().
* Rewrote res_qp_parse_cb() to avoid long lines and extra indentation.
------------------------------------------------------------------------
David, Stephen,
The kernel code is accepted to the RDMA and will be sent to Linus in
this merge window, and this is refreshed version of user space part.
Because, I found bug in handling cxgb4 devices and we cleaned header
file a little bit more, it was more wise to resend the series instead
of applying v2.
https://patchwork.ozlabs.org/project/netdev/list/?series=RDMA+resource+tracking&submitter=68852&state=8&q=&archive=&delegate=
Thanks
Cc: RDMA mailing list <linux-rdma@vger.kernel.org>
Cc: Steve Wise <swise@opengridcomputing.com>
[1] https://www.spinics.net/lists/linux-rdma/msg59535.html
Leon Romanovsky (10):
rdma: Add option to provide "-" sign for the port number
rdma: Make visible the number of arguments
rdma: Add filtering infrastructure
rdma: Set pointer to device name position
rdma: Allow external usage of compare string routine
rdma: Update kernel header file
rdma: Add resource tracking summary
rdma: Add QP resource tracking information
rdma: Document resource tracking
rdma: Check return value of strdup call
include/uapi/rdma/rdma_netlink.h | 67 +++++-
man/man8/rdma-resource.8 | 86 +++++++
rdma/Makefile | 2 +-
rdma/link.c | 2 +-
rdma/rdma.c | 4 +-
rdma/rdma.h | 28 ++-
rdma/res.c | 486 +++++++++++++++++++++++++++++++++++++++
rdma/utils.c | 321 +++++++++++++++++++++++++-
8 files changed, 971 insertions(+), 25 deletions(-)
create mode 100644 man/man8/rdma-resource.8
create mode 100644 rdma/res.c
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH iproute2-next 01/10] rdma: Add option to provide "-" sign for the port number 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 02/10] rdma: Make visible the number of arguments Leon Romanovsky ` (6 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> According to the IBTA spec [1], the physical connected port is provided for the QP in RTR-to-INIT stage performed by modify_qp(). It causes to do not have port number for newly created QPs. The following patch adds "-" sign to present absence of port, because QPs are going to be associated with rdmatool link object, which needs port number as an index. [1] InfiniBand Architecture Release 1.3 - "Table 96 QP State Transition Properties" Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- rdma/link.c | 2 +- rdma/rdma.h | 3 +-- rdma/utils.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/rdma/link.c b/rdma/link.c index 676cb21d..66bcd50e 100644 --- a/rdma/link.c +++ b/rdma/link.c @@ -285,7 +285,7 @@ static int link_one_show(struct rd *rd) static int link_show(struct rd *rd) { - return rd_exec_link(rd, link_one_show); + return rd_exec_link(rd, link_one_show, true); } int cmd_link(struct rd *rd) diff --git a/rdma/rdma.h b/rdma/rdma.h index 8d53d3a0..cbd9aa89 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -64,7 +64,6 @@ bool rd_no_arg(struct rd *rd); void rd_arg_inc(struct rd *rd); char *rd_argv(struct rd *rd); -uint32_t get_port_from_argv(struct rd *rd); /* * Commands interface @@ -73,7 +72,7 @@ int cmd_dev(struct rd *rd); int cmd_link(struct rd *rd); int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str); int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)); -int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd)); +int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port); void rd_free(struct rd *rd); /* diff --git a/rdma/utils.c b/rdma/utils.c index 7b2001e2..b9c668a3 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -10,6 +10,7 @@ */ #include "rdma.h" +#include <ctype.h> static int rd_argc(struct rd *rd) { @@ -50,13 +51,43 @@ bool rd_no_arg(struct rd *rd) return rd_argc(rd) == 0; } -uint32_t get_port_from_argv(struct rd *rd) +/* + * Possible input:output + * dev/port | first port | is_dump_all + * mlx5_1 | 0 | true + * mlx5_1/ | 0 | true + * mlx5_1/0 | 0 | false + * mlx5_1/1 | 1 | false + * mlx5_1/- | 0 | false + * + * In strict mode, /- will return error. + */ +static int get_port_from_argv(struct rd *rd, uint32_t *port, + bool *is_dump_all, bool strict_port) { char *slash; + *port = 0; + *is_dump_all = true; + slash = strchr(rd_argv(rd), '/'); /* if no port found, return 0 */ - return slash ? atoi(slash + 1) : 0; + if (slash++) { + if (*slash == '-') { + if (strict_port) + return -EINVAL; + *is_dump_all = false; + return 0; + } + + if (isdigit(*slash)) { + *is_dump_all = false; + *port = atoi(slash); + } + if (!*port && strlen(slash)) + return -EINVAL; + } + return 0; } static struct dev_map *dev_map_alloc(const char *dev_name) @@ -152,7 +183,7 @@ void rd_free(struct rd *rd) dev_map_cleanup(rd); } -int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd)) +int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port) { struct dev_map *dev_map; uint32_t port; @@ -163,7 +194,8 @@ int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd)) if (rd_no_arg(rd)) { list_for_each_entry(dev_map, &rd->dev_map_list, list) { rd->dev_idx = dev_map->idx; - for (port = 1; port < dev_map->num_ports + 1; port++) { + port = (strict_port) ? 1 : 0; + for (; port < dev_map->num_ports + 1; port++) { rd->port_idx = port; ret = cb(rd); if (ret) @@ -172,21 +204,23 @@ int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd)) } } else { + bool is_dump_all; + dev_map = dev_map_lookup(rd, true); - port = get_port_from_argv(rd); - if (!dev_map || port > dev_map->num_ports) { + ret = get_port_from_argv(rd, &port, &is_dump_all, strict_port); + if (!dev_map || port > dev_map->num_ports || (!port && ret)) { pr_err("Wrong device name\n"); ret = -ENOENT; goto out; } rd_arg_inc(rd); rd->dev_idx = dev_map->idx; - rd->port_idx = port ? : 1; + rd->port_idx = port; for (; rd->port_idx < dev_map->num_ports + 1; rd->port_idx++) { ret = cb(rd); if (ret) goto out; - if (port) + if (!is_dump_all) /* * We got request to show link for devname * with port index. -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 02/10] rdma: Make visible the number of arguments 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 01/10] rdma: Add option to provide "-" sign for the port number Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> ` (5 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- rdma/rdma.h | 1 + rdma/utils.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rdma/rdma.h b/rdma/rdma.h index cbd9aa89..1b66ae04 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -74,6 +74,7 @@ int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str); int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)); int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port); void rd_free(struct rd *rd); +int rd_argc(struct rd *rd); /* * Device manipulation diff --git a/rdma/utils.c b/rdma/utils.c index b9c668a3..af2b374d 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -12,7 +12,7 @@ #include "rdma.h" #include <ctype.h> -static int rd_argc(struct rd *rd) +int rd_argc(struct rd *rd) { return rd->argc; } -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
[parent not found: <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>]
* [PATCH iproute2-next 03/10] rdma: Add filtering infrastructure [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 07/10] rdma: Add resource tracking summary Leon Romanovsky ` (3 subsequent siblings) 4 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> This patch adds general infrastructure to RDMAtool to handle various filtering options needed for the downstream resource tracking patches. The infrastructure is generic and stores filters in list of key<->value entries. There are three types of filters: 1. Numeric - the values are intended to be digits combined with '-' to mark range and ',' to mark multiple entries, e.g. pid 1-100,234,400-401 is perfectly legit filter to limit process ids. 2. String - the values are consist from strings and "," as a denominator. 3. Link - special case to allow '/' in string to provide link name, e.g. link mlx4_1/2. Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> --- rdma/rdma.c | 1 + rdma/rdma.h | 20 ++++++ rdma/utils.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) diff --git a/rdma/rdma.c b/rdma/rdma.c index 0e8fd688..a21ba440 100644 --- a/rdma/rdma.c +++ b/rdma/rdma.c @@ -47,6 +47,7 @@ static int rd_init(struct rd *rd, int argc, char **argv, char *filename) rd->argc = argc; rd->argv = argv; INIT_LIST_HEAD(&rd->dev_map_list); + INIT_LIST_HEAD(&rd->filter_list); if (rd->json_output) { rd->jw = jsonw_new(stdout); diff --git a/rdma/rdma.h b/rdma/rdma.h index 1b66ae04..8e60ce26 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -29,6 +29,18 @@ #define RDMA_BITMAP_ENUM(name, bit_no) RDMA_BITMAP_##name = BIT(bit_no), #define RDMA_BITMAP_NAMES(name, bit_no) [bit_no] = #name, +#define MAX_NUMBER_OF_FILTERS 64 +struct filters { + char name[32]; + bool is_number; +}; + +struct filter_entry { + struct list_head list; + char *key; + char *value; +}; + struct dev_map { struct list_head list; char *dev_name; @@ -50,6 +62,7 @@ struct rd { json_writer_t *jw; bool json_output; bool pretty_output; + struct list_head filter_list; }; struct rd_cmd { @@ -81,6 +94,13 @@ int rd_argc(struct rd *rd); */ struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index); +/* + * Filter manipulation + */ +int rd_build_filter(struct rd *rd, const struct filters valid_filters[]); +bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val); +bool rd_check_is_string_filtered(struct rd *rd, const char *key, const char *val); +bool rd_check_is_key_exist(struct rd *rd, const char *key); /* * Netlink */ diff --git a/rdma/utils.c b/rdma/utils.c index af2b374d..157699c0 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -114,6 +114,234 @@ static void dev_map_cleanup(struct rd *rd) } } +static int add_filter(struct rd *rd, char *key, char *value, + const struct filters valid_filters[]) +{ + char cset[] = "1234567890,-"; + struct filter_entry *fe; + bool key_found = false; + int idx = 0; + int ret; + + fe = calloc(1, sizeof(*fe)); + if (!fe) + return -ENOMEM; + + while (idx < MAX_NUMBER_OF_FILTERS && valid_filters[idx].name) { + if (!strcmpx(key, valid_filters[idx].name)) { + key_found = true; + break; + } + idx++; + } + if (!key_found) { + pr_err("Unsupported filter option: %s\n", key); + ret = -EINVAL; + goto err; + } + + /* + * Check the filter validity, not optimal, but works + * + * Actually, there are three types of filters + * numeric - for example PID or QPN + * string - for example states + * link - user requested to filter on specific link + * e.g. mlx5_1/1, mlx5_1/-, mlx5_1 ... + */ + if (valid_filters[idx].is_number && + strspn(value, cset) != strlen(value)) { + pr_err("%s filter accepts \"%s\" characters only\n", key, cset); + ret = -EINVAL; + goto err; + } + + fe->key = strdup(key); + fe->value = strdup(value); + if (!fe->key || !fe->value) { + ret = -ENOMEM; + goto err_alloc; + } + + for (idx = 0; idx < strlen(fe->value); idx++) + fe->value[idx] = tolower(fe->value[idx]); + + list_add_tail(&fe->list, &rd->filter_list); + return 0; + +err_alloc: + free(fe->value); + free(fe->key); +err: + free(fe); + return ret; +} + +int rd_build_filter(struct rd *rd, const struct filters valid_filters[]) +{ + int ret = 0; + int idx = 0; + + if (!valid_filters || !rd_argc(rd)) + goto out; + + if (rd_argc(rd) == 1) { + pr_err("No filter data was supplied to filter option %s\n", rd_argv(rd)); + ret = -EINVAL; + goto out; + } + + if (rd_argc(rd) % 2) { + pr_err("There is filter option without data\n"); + ret = -EINVAL; + goto out; + } + + while (idx != rd_argc(rd)) { + /* + * We can do micro-optimization and skip "dev" + * and "link" filters, but it is not worth of it. + */ + ret = add_filter(rd, *(rd->argv + idx), + *(rd->argv + idx + 1), valid_filters); + if (ret) + goto out; + idx += 2; + } + +out: + return ret; +} + +bool rd_check_is_key_exist(struct rd *rd, const char *key) +{ + struct filter_entry *fe; + + list_for_each_entry(fe, &rd->filter_list, list) { + if (!strcmpx(fe->key, key)) + return true; + } + + return false; +} + +/* + * Check if string entry is filtered: + * * key doesn't exist -> user didn't request -> not filtered + */ +bool rd_check_is_string_filtered(struct rd *rd, + const char *key, const char *val) +{ + bool key_is_filtered = false; + struct filter_entry *fe; + char *p = NULL; + char *str; + + list_for_each_entry(fe, &rd->filter_list, list) { + if (!strcmpx(fe->key, key)) { + /* We found the key */ + p = strdup(fe->value); + key_is_filtered = true; + if (!p) { + /* + * Something extremely wrong if we fail + * to allocate small amount of bytes. + */ + pr_err("Found key, but failed to allocate memory to store value\n"); + return key_is_filtered; + } + + /* + * Need to check if value in range + * It can come in the following formats + * and their permutations: + * str + * str1,str2 + */ + str = strtok(p, ","); + while (str) { + if (strlen(str) == strlen(val) && + !strcasecmp(str, val)) { + key_is_filtered = false; + goto out; + } + str = strtok(NULL, ","); + } + goto out; + } + } + +out: + free(p); + return key_is_filtered; +} + +/* + * Check if key is filtered: + * key doesn't exist -> user didn't request -> not filtered + */ +bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val) +{ + bool key_is_filtered = false; + struct filter_entry *fe; + + list_for_each_entry(fe, &rd->filter_list, list) { + uint32_t left_val = 0, fe_value = 0; + bool range_check = false; + char *p = fe->value; + + if (!strcmpx(fe->key, key)) { + /* We found the key */ + key_is_filtered = true; + /* + * Need to check if value in range + * It can come in the following formats + * (and their permutations): + * numb + * numb1,numb2 + * ,numb1,numb2 + * numb1-numb2 + * numb1,numb2-numb3,numb4-numb5 + */ + while (*p) { + if (isdigit(*p)) { + fe_value = strtol(p, &p, 10); + if (fe_value == val || + (range_check && left_val < val && + val < fe_value)) { + key_is_filtered = false; + goto out; + } + range_check = false; + } else { + if (*p == '-') { + left_val = fe_value; + range_check = true; + } + p++; + } + } + goto out; + } + } + +out: + return key_is_filtered; +} + +static void filters_cleanup(struct rd *rd) +{ + struct filter_entry *fe, *tmp; + + list_for_each_entry_safe(fe, tmp, + &rd->filter_list, list) { + list_del(&fe->list); + free(fe->key); + free(fe->value); + free(fe); + } +} + static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_DEV_INDEX] = MNL_TYPE_U32, [RDMA_NLDEV_ATTR_DEV_NAME] = MNL_TYPE_NUL_STRING, @@ -181,6 +409,7 @@ void rd_free(struct rd *rd) return; free(rd->buff); dev_map_cleanup(rd); + filters_cleanup(rd); } int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port) -- 2.16.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 07/10] rdma: Add resource tracking summary [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> 2018-01-31 8:11 ` [PATCH iproute2-next 03/10] rdma: Add filtering infrastructure Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information Leon Romanovsky ` (2 subsequent siblings) 4 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> The global resource summary information. The object names, current utilization and maximum numbers are received as is from the kernel. $ rdma res 1: mlx5_0: pd 3 cq 5 qp 4 2: mlx5_1: pd 3 cq 5 qp 4 3: mlx5_2: pd 3 cq 5 qp 4 4: mlx5_3: pd 2 cq 3 qp 2 5: mlx5_4: pd 3 cq 5 qp 4 $ rdma res show mlx5_4 5: mlx5_4: pd 3 cq 5 qp 44 Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> --- rdma/Makefile | 2 +- rdma/rdma.c | 3 +- rdma/rdma.h | 1 + rdma/res.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rdma/utils.c | 4 ++ 5 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 rdma/res.c diff --git a/rdma/Makefile b/rdma/Makefile index 454f25f8..360f09b2 100644 --- a/rdma/Makefile +++ b/rdma/Makefile @@ -5,7 +5,7 @@ TARGETS := ifeq ($(HAVE_MNL),y) -RDMA_OBJ = rdma.o utils.o dev.o link.o +RDMA_OBJ = rdma.o utils.o dev.o link.o res.o TARGETS += rdma endif diff --git a/rdma/rdma.c b/rdma/rdma.c index a21ba440..19608f41 100644 --- a/rdma/rdma.c +++ b/rdma/rdma.c @@ -15,7 +15,7 @@ static void help(char *name) { pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n" - "where OBJECT := { dev | link | help }\n" + "where OBJECT := { dev | link | resource | help }\n" " OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty]}\n", name); } @@ -32,6 +32,7 @@ static int rd_cmd(struct rd *rd) { "help", cmd_help }, { "dev", cmd_dev }, { "link", cmd_link }, + { "resource", cmd_res }, { 0 } }; diff --git a/rdma/rdma.h b/rdma/rdma.h index d2cde895..5809f706 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -83,6 +83,7 @@ char *rd_argv(struct rd *rd); */ int cmd_dev(struct rd *rd); int cmd_link(struct rd *rd); +int cmd_res(struct rd *rd); int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str); int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)); int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port); diff --git a/rdma/res.c b/rdma/res.c new file mode 100644 index 00000000..bd97c58e --- /dev/null +++ b/rdma/res.c @@ -0,0 +1,161 @@ +/* + * res.c RDMA tool + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> + */ + +#include "rdma.h" +#include <inttypes.h> + +static int res_help(struct rd *rd) +{ + pr_out("Usage: %s resource\n", rd->filename); + pr_out(" resource show [DEV]\n"); + return 0; +} + +static int res_print_summary(struct rd *rd, struct nlattr **tb) +{ + struct nlattr *nla_table = tb[RDMA_NLDEV_ATTR_RES_SUMMARY]; + struct nlattr *nla_entry; + const char *name; + uint64_t curr; + int err; + + mnl_attr_for_each_nested(nla_entry, nla_table) { + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; + char json_name[32]; + + err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); + if (err != MNL_CB_OK) + return -EINVAL; + + if (!nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] || + !nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]) { + return -EINVAL; + } + + name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]); + curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]); + if (rd->json_output) { + snprintf(json_name, 32, "%s", name); + jsonw_lluint_field(rd->jw, json_name, curr); + } else { + pr_out("%s %"PRId64 " ", name, curr); + } + } + return 0; +} + +static int res_no_args_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] || + !tb[RDMA_NLDEV_ATTR_RES_SUMMARY]) + return MNL_CB_ERROR; + + idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); + name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); + if (rd->json_output) { + jsonw_uint_field(rd->jw, "ifindex", idx); + jsonw_string_field(rd->jw, "ifname", name); + } else { + pr_out("%u: %s: ", idx, name); + } + + res_print_summary(rd, tb); + + if (!rd->json_output) + pr_out("\n"); + return MNL_CB_OK; +} + +static int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback) +{ + uint32_t flags = NLM_F_REQUEST | NLM_F_ACK; + uint32_t seq; + int ret; + + if (command != RDMA_NLDEV_CMD_RES_GET) + flags |= NLM_F_DUMP; + + rd_prepare_msg(rd, command, &seq, flags); + mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx); + if (rd->port_idx) + mnl_attr_put_u32(rd->nlh, + RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx); + + ret = rd_send_msg(rd); + if (ret) + return ret; + + if (rd->json_output) + jsonw_start_object(rd->jw); + ret = rd_recv_msg(rd, callback, rd, seq); + if (rd->json_output) + jsonw_end_object(rd->jw); + return ret; +} + +#define RES_FUNC(name, command, valid_filters, strict_port) \ + static int _##name(struct rd *rd)\ + { \ + return _res_send_msg(rd, command, name##_parse_cb); \ + } \ + static int name(struct rd *rd) \ + {\ + int ret = rd_build_filter(rd, valid_filters); \ + if (ret) \ + return ret; \ + if ((uintptr_t)valid_filters != (uintptr_t)NULL) { \ + ret = rd_set_arg_to_devname(rd); \ + if (ret) \ + return ret;\ + } \ + if (strict_port) \ + return rd_exec_dev(rd, _##name); \ + else \ + return rd_exec_link(rd, _##name, strict_port); \ + } + +RES_FUNC(res_no_args, RDMA_NLDEV_CMD_RES_GET, NULL, true); + +static int res_show(struct rd *rd) +{ + const struct rd_cmd cmds[] = { + { NULL, res_no_args }, + { 0 } + }; + + /* + * Special case to support "rdma res show DEV_NAME" + */ + if (rd_argc(rd) == 1 && dev_map_lookup(rd, false)) + return rd_exec_dev(rd, _res_no_args); + + return rd_exec_cmd(rd, cmds, "parameter"); +} + +int cmd_res(struct rd *rd) +{ + const struct rd_cmd cmds[] = { + { NULL, res_show }, + { "show", res_show }, + { "list", res_show }, + { "help", res_help }, + { 0 } + }; + + return rd_exec_cmd(rd, cmds, "resource command"); +} diff --git a/rdma/utils.c b/rdma/utils.c index 9e15b7cf..344f0a93 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -356,6 +356,10 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_PORT_STATE] = MNL_TYPE_U8, [RDMA_NLDEV_ATTR_PORT_PHYS_STATE] = MNL_TYPE_U8, [RDMA_NLDEV_ATTR_DEV_NODE_TYPE] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_RES_SUMMARY] = MNL_TYPE_NESTED, + [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY] = MNL_TYPE_NESTED, + [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = MNL_TYPE_NUL_STRING, + [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = MNL_TYPE_U64, }; int rd_attr_cb(const struct nlattr *attr, void *data) -- 2.16.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> 2018-01-31 8:11 ` [PATCH iproute2-next 03/10] rdma: Add filtering infrastructure Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 07/10] rdma: Add resource tracking summary Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky [not found] ` <20180131081156.19607-9-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> 2018-01-31 8:17 ` [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky 2018-02-06 1:25 ` Stephen Hemminger 4 siblings, 1 reply; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> This patch adds ss-similar interface to view various resource tracked objects. At this stage, only QP is presented. 1. Get all QPs for the specific device: $ rdma res show qp link mlx5_4 link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] $ rdma res show qp link mlx5_4/ link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] 2. Provide illegal port number (0 is illegal): $ rdma res show qp link mlx5_4/0 Wrong device name 3. Get QPs of specific port: $ rdma res show qp link mlx5_4/1 link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] 4. Get QPs which have not assigned port yet: link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] 5. Limit to specific Local QPNs: $ rdma res show qp link mlx5_4/1 lqpn 1-3,7 link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] . Filter types (strings): $ rdma res show qp link mlx5_4/1 type UD,gSi link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> --- rdma/res.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rdma/utils.c | 11 ++ 2 files changed, 336 insertions(+) diff --git a/rdma/res.c b/rdma/res.c index bd97c58e..2a63e712 100644 --- a/rdma/res.c +++ b/rdma/res.c @@ -16,6 +16,9 @@ static int res_help(struct rd *rd) { pr_out("Usage: %s resource\n", rd->filename); pr_out(" resource show [DEV]\n"); + pr_out(" resource show [qp]\n"); + pr_out(" resource show qp link [DEV/PORT]\n"); + pr_out(" resource show qp link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n"); return 0; } @@ -129,12 +132,334 @@ static int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback) return rd_exec_link(rd, _##name, strict_port); \ } +static const char *path_mig_to_str(uint8_t idx) +{ + static const char * const path_mig_str[] = { "MIGRATED", + "REARM", "ARMED" }; + + if (idx < ARRAY_SIZE(path_mig_str)) + return path_mig_str[idx]; + return "UNKNOWN"; +} + +static const char *qp_states_to_str(uint8_t idx) +{ + static const char * const qp_states_str[] = { "RESET", "INIT", + "RTR", "RTS", "SQD", + "SQE", "ERR" }; + + if (idx < ARRAY_SIZE(qp_states_str)) + return qp_states_str[idx]; + return "UNKNOWN"; +} + +static const char *qp_types_to_str(uint8_t idx) +{ + static const char * const qp_types_str[] = { "SMI", "GSI", "RC", + "UC", "UD", "RAW_IPV6", + "RAW_ETHERTYPE", + "UNKNOWN", "RAW_PACKET", + "XRC_INI", "XRC_TGT" }; + + if (idx < ARRAY_SIZE(qp_types_str)) + return qp_types_str[idx]; + return "UNKNOWN"; +} + +static void print_lqpn(struct rd *rd, uint32_t val) +{ + if (rd->json_output) + jsonw_uint_field(rd->jw, "lqpn", val); + else + pr_out("lqpn %u ", val); +} + +static void print_rqpn(struct rd *rd, uint32_t val, struct nlattr **nla_line) +{ + if (!nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) + return; + + if (rd->json_output) + jsonw_uint_field(rd->jw, "rqpn", val); + else + pr_out("rqpn %u ", val); +} + +static void print_type(struct rd *rd, uint32_t val) +{ + if (rd->json_output) + jsonw_string_field(rd->jw, "type", + qp_types_to_str(val)); + else + pr_out("type %s ", qp_types_to_str(val)); +} + +static void print_state(struct rd *rd, uint32_t val) +{ + if (rd->json_output) + jsonw_string_field(rd->jw, "state", + qp_states_to_str(val)); + else + pr_out("state %s ", qp_states_to_str(val)); +} + +static void print_rqpsn(struct rd *rd, uint32_t val, struct nlattr **nla_line) +{ + if (!nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) + return; + + if (rd->json_output) + jsonw_uint_field(rd->jw, "rq-psn", val); + else + pr_out("rq-psn %u ", val); +} + +static void print_sqpsn(struct rd *rd, uint32_t val) +{ + if (rd->json_output) + jsonw_uint_field(rd->jw, "sq-psn", val); + else + pr_out("sq-psn %u ", val); +} + +static void print_pathmig(struct rd *rd, uint32_t val, + struct nlattr **nla_line) +{ + if (!nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) + return; + + if (rd->json_output) + jsonw_string_field(rd->jw, + "path-mig-state", + path_mig_to_str(val)); + else + pr_out("path-mig-state %s ", path_mig_to_str(val)); +} + +static void print_pid(struct rd *rd, uint32_t val) +{ + if (rd->json_output) + jsonw_uint_field(rd->jw, "pid", val); + else + pr_out("pid %u ", val); +} + +static void print_comm(struct rd *rd, const char *str, + struct nlattr **nla_line) +{ + char tmp[18]; + + if (rd->json_output) { + /* Don't beatify output in JSON format */ + jsonw_string_field(rd->jw, "comm", str); + return; + } + + if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) + snprintf(tmp, sizeof(tmp), "%s", str); + else + snprintf(tmp, sizeof(tmp), "[%s]", str); + + pr_out("comm %s ", tmp); +} + +static void print_link(struct rd *rd, uint32_t idx, const char *name, + uint32_t port, struct nlattr **nla_line) +{ + if (rd->json_output) { + jsonw_uint_field(rd->jw, "ifindex", idx); + + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) + jsonw_uint_field(rd->jw, "port", port); + + jsonw_string_field(rd->jw, "ifname", name); + } else { + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) + pr_out("link %s/%u ", name, port); + else + pr_out("link %s/- ", name); + } +} + +static char *get_task_name(uint32_t pid) +{ + char *comm; + FILE *f; + + if (asprintf(&comm, "/proc/%d/comm", pid) < 0) + return NULL; + + f = fopen(comm, "r"); + free(comm); + if (!f) + return NULL; + + if (fscanf(f, "%ms\n", &comm) != 1) + comm = NULL; + + fclose(f); + + return comm; +} + +static int res_qp_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; + 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_QP]) + 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_QP]; + + mnl_attr_for_each_nested(nla_entry, nla_table) { + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; + uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn; + uint8_t type, state, path_mig_state = 0; + uint32_t port = 0, pid = 0; + char *comm = NULL; + int err; + + err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); + if (err != MNL_CB_OK) + return MNL_CB_ERROR; + + if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] || + !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] || + !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] || + !nla_line[RDMA_NLDEV_ATTR_RES_STATE] || + (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && + !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { + return MNL_CB_ERROR; + } + + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) + port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]); + + if (port != rd->port_idx) + continue; + + lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); + if (rd_check_is_filtered(rd, "lqpn", lqpn)) + continue; + + if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) { + rqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]); + if (rd_check_is_filtered(rd, "rqpn", rqpn)) + continue; + } else { + if (rd_check_is_key_exist(rd, "rqpn")) + continue; + } + + if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) { + rq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]); + if (rd_check_is_filtered(rd, "rq-psn", rq_psn)) + continue; + } else { + if (rd_check_is_key_exist(rd, "rq-psn")) + continue; + } + + sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]); + if (rd_check_is_filtered(rd, "sq-psn", sq_psn)) + continue; + + if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) { + path_mig_state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]); + if (rd_check_is_string_filtered(rd, "path-mig-state", path_mig_to_str(path_mig_state))) + continue; + } else { + if (rd_check_is_key_exist(rd, "path-mig-state")) + continue; + } + + type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]); + if (rd_check_is_string_filtered(rd, "type", qp_types_to_str(type))) + continue; + + state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]); + if (rd_check_is_string_filtered(rd, "state", qp_states_to_str(state))) + continue; + + if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { + pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]); + comm = get_task_name(pid); + } + + if (rd_check_is_filtered(rd, "pid", pid)) + continue; + + if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) + /* discard const from mnl_attr_get_str */ + comm = (char *)mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); + + if (rd->json_output) + jsonw_start_array(rd->jw); + + print_link(rd, idx, name, port, nla_line); + + print_lqpn(rd, lqpn); + print_rqpn(rd, rqpn, nla_line); + + print_type(rd, type); + print_state(rd, state); + + print_rqpsn(rd, rq_psn, nla_line); + print_sqpsn(rd, sq_psn); + + print_pathmig(rd, path_mig_state, nla_line); + print_pid(rd, pid); + print_comm(rd, comm, nla_line); + + if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) + free(comm); + + if (rd->json_output) + jsonw_end_array(rd->jw); + else + pr_out("\n"); + } + return MNL_CB_OK; +} + RES_FUNC(res_no_args, RDMA_NLDEV_CMD_RES_GET, NULL, true); +static const struct +filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {{ .name = "link", + .is_number = false }, + { .name = "lqpn", + .is_number = true }, + { .name = "rqpn", + .is_number = true }, + { .name = "pid", + .is_number = true }, + { .name = "sq-psn", + .is_number = true }, + { .name = "rq-psn", + .is_number = true }, + { .name = "type", + .is_number = false }, + { .name = "path-mig-state", + .is_number = false }, + { .name = "state", + .is_number = false } }; + +RES_FUNC(res_qp, RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false); + static int res_show(struct rd *rd) { const struct rd_cmd cmds[] = { { NULL, res_no_args }, + { "qp", res_qp }, { 0 } }; diff --git a/rdma/utils.c b/rdma/utils.c index 344f0a93..059aa788 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -360,6 +360,17 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY] = MNL_TYPE_NESTED, [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] = MNL_TYPE_NUL_STRING, [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR] = MNL_TYPE_U64, + [RDMA_NLDEV_ATTR_RES_QP] = MNL_TYPE_NESTED, + [RDMA_NLDEV_ATTR_RES_QP_ENTRY] = MNL_TYPE_NESTED, + [RDMA_NLDEV_ATTR_RES_LQPN] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_RES_RQPN] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_RES_RQ_PSN] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_RES_SQ_PSN] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_RES_TYPE] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_RES_STATE] = MNL_TYPE_U8, + [RDMA_NLDEV_ATTR_RES_PID] = MNL_TYPE_U32, + [RDMA_NLDEV_ATTR_RES_KERN_NAME] = MNL_TYPE_NUL_STRING, }; int rd_attr_cb(const struct nlattr *attr, void *data) -- 2.16.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 18+ messages in thread
[parent not found: <20180131081156.19607-9-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>]
* RE: [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information [not found] ` <20180131081156.19607-9-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> @ 2018-02-01 20:05 ` Steve Wise 2018-02-05 13:22 ` Leon Romanovsky 0 siblings, 1 reply; 18+ messages in thread From: Steve Wise @ 2018-02-01 20:05 UTC (permalink / raw) To: 'Leon Romanovsky', 'David Ahern' Cc: 'RDMA mailing list', 'netdev', 'Stephen Hemminger', 'Leon Romanovsky' Hey Leon, > > From: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> > > This patch adds ss-similar interface to view various resource > tracked objects. At this stage, only QP is presented. > > 1. Get all QPs for the specific device: > $ rdma res show qp link mlx5_4 > link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] > link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] > > $ rdma res show qp link mlx5_4/ > link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] > link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] > > 2. Provide illegal port number (0 is illegal): > $ rdma res show qp link mlx5_4/0 > Wrong device name > > 3. Get QPs of specific port: > $ rdma res show qp link mlx5_4/1 > link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] > > 4. Get QPs which have not assigned port yet: > link mlx5_4/- lqpn 8 type UD state RESET sq-psn 0 pid 0 comm [ib_ipoib] > > 5. Limit to specific Local QPNs: > $ rdma res show qp link mlx5_4/1 lqpn 1-3,7 > link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 0 type SMI state RTS sq-psn 0 pid 0 comm [ib_core] > > . Filter types (strings): > $ rdma res show qp link mlx5_4/1 type UD,gSi > link mlx5_4/1 lqpn 7 type UD state RTS sq-psn 0 pid 0 comm [ib_core] > link mlx5_4/1 lqpn 1 type GSI state RTS sq-psn 0 pid 0 comm [ib_core] > > Signed-off-by: Leon Romanovsky <leonro-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org> > --- > rdma/res.c | 325 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > rdma/utils.c | 11 ++ > 2 files changed, 336 insertions(+) > > diff --git a/rdma/res.c b/rdma/res.c > index bd97c58e..2a63e712 100644 > --- a/rdma/res.c > +++ b/rdma/res.c > @@ -16,6 +16,9 @@ static int res_help(struct rd *rd) > { > pr_out("Usage: %s resource\n", rd->filename); > pr_out(" resource show [DEV]\n"); > + pr_out(" resource show [qp]\n"); > + pr_out(" resource show qp link [DEV/PORT]\n"); > + pr_out(" resource show qp link [DEV/PORT] [FILTER-NAME FILTER- > VALUE]\n"); > return 0; > } > > @@ -129,12 +132,334 @@ static int _res_send_msg(struct rd *rd, uint32_t > command, mnl_cb_t callback) > return rd_exec_link(rd, _##name, strict_port); \ > } > > +static const char *path_mig_to_str(uint8_t idx) > +{ > + static const char * const path_mig_str[] = { "MIGRATED", > + "REARM", "ARMED" }; > + > + if (idx < ARRAY_SIZE(path_mig_str)) > + return path_mig_str[idx]; > + return "UNKNOWN"; > +} > + > +static const char *qp_states_to_str(uint8_t idx) > +{ > + static const char * const qp_states_str[] = { "RESET", "INIT", > + "RTR", "RTS", "SQD", > + "SQE", "ERR" }; > + > + if (idx < ARRAY_SIZE(qp_states_str)) > + return qp_states_str[idx]; > + return "UNKNOWN"; > +} > + > +static const char *qp_types_to_str(uint8_t idx) > +{ > + static const char * const qp_types_str[] = { "SMI", "GSI", "RC", > + "UC", "UD", "RAW_IPV6", > + "RAW_ETHERTYPE", > + "UNKNOWN", > "RAW_PACKET", > + "XRC_INI", "XRC_TGT" }; > + > + if (idx < ARRAY_SIZE(qp_types_str)) > + return qp_types_str[idx]; > + return "UNKNOWN"; > +} > + > +static void print_lqpn(struct rd *rd, uint32_t val) > +{ > + if (rd->json_output) > + jsonw_uint_field(rd->jw, "lqpn", val); > + else > + pr_out("lqpn %u ", val); > +} > + > +static void print_rqpn(struct rd *rd, uint32_t val, struct nlattr **nla_line) > +{ > + if (!nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) > + return; > + > + if (rd->json_output) > + jsonw_uint_field(rd->jw, "rqpn", val); > + else > + pr_out("rqpn %u ", val); > +} > + > +static void print_type(struct rd *rd, uint32_t val) > +{ > + if (rd->json_output) > + jsonw_string_field(rd->jw, "type", > + qp_types_to_str(val)); > + else > + pr_out("type %s ", qp_types_to_str(val)); > +} > + > +static void print_state(struct rd *rd, uint32_t val) > +{ > + if (rd->json_output) > + jsonw_string_field(rd->jw, "state", > + qp_states_to_str(val)); > + else > + pr_out("state %s ", qp_states_to_str(val)); > +} > + > +static void print_rqpsn(struct rd *rd, uint32_t val, struct nlattr **nla_line) > +{ > + if (!nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) > + return; > + > + if (rd->json_output) > + jsonw_uint_field(rd->jw, "rq-psn", val); > + else > + pr_out("rq-psn %u ", val); > +} > + > +static void print_sqpsn(struct rd *rd, uint32_t val) > +{ > + if (rd->json_output) > + jsonw_uint_field(rd->jw, "sq-psn", val); > + else > + pr_out("sq-psn %u ", val); > +} > + > +static void print_pathmig(struct rd *rd, uint32_t val, > + struct nlattr **nla_line) > +{ > + if (!nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) > + return; > + > + if (rd->json_output) > + jsonw_string_field(rd->jw, > + "path-mig-state", > + path_mig_to_str(val)); > + else > + pr_out("path-mig-state %s ", path_mig_to_str(val)); > +} > + > +static void print_pid(struct rd *rd, uint32_t val) > +{ > + if (rd->json_output) > + jsonw_uint_field(rd->jw, "pid", val); > + else > + pr_out("pid %u ", val); > +} > + > +static void print_comm(struct rd *rd, const char *str, > + struct nlattr **nla_line) > +{ > + char tmp[18]; > + > + if (rd->json_output) { > + /* Don't beatify output in JSON format */ > + jsonw_string_field(rd->jw, "comm", str); > + return; > + } > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) > + snprintf(tmp, sizeof(tmp), "%s", str); > + else > + snprintf(tmp, sizeof(tmp), "[%s]", str); > + > + pr_out("comm %s ", tmp); > +} > + > +static void print_link(struct rd *rd, uint32_t idx, const char *name, > + uint32_t port, struct nlattr **nla_line) > +{ > + if (rd->json_output) { > + jsonw_uint_field(rd->jw, "ifindex", idx); > + > + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) > + jsonw_uint_field(rd->jw, "port", port); > + > + jsonw_string_field(rd->jw, "ifname", name); > + } else { > + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) > + pr_out("link %s/%u ", name, port); > + else > + pr_out("link %s/- ", name); > + } > +} > + > +static char *get_task_name(uint32_t pid) > +{ > + char *comm; > + FILE *f; > + > + if (asprintf(&comm, "/proc/%d/comm", pid) < 0) > + return NULL; > + > + f = fopen(comm, "r"); > + free(comm); > + if (!f) > + return NULL; > + > + if (fscanf(f, "%ms\n", &comm) != 1) > + comm = NULL; > + > + fclose(f); > + > + return comm; > +} > + > +static int res_qp_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; > + 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_QP]) > + 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_QP]; > + > + mnl_attr_for_each_nested(nla_entry, nla_table) { > + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; > + uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn; > + uint8_t type, state, path_mig_state = 0; > + uint32_t port = 0, pid = 0; > + char *comm = NULL; > + int err; > + > + err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); > + if (err != MNL_CB_OK) > + return MNL_CB_ERROR; > + > + if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] || > + !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] || > + !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] || > + !nla_line[RDMA_NLDEV_ATTR_RES_STATE] || > + (!nla_line[RDMA_NLDEV_ATTR_RES_PID] && > + !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) { > + return MNL_CB_ERROR; > + } > + > + if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) > + port = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]); > + > + if (port != rd->port_idx) > + continue; > + > + lqpn = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]); > + if (rd_check_is_filtered(rd, "lqpn", lqpn)) > + continue; > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) { > + rqpn = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]); > + if (rd_check_is_filtered(rd, "rqpn", rqpn)) > + continue; > + } else { > + if (rd_check_is_key_exist(rd, "rqpn")) > + continue; > + } > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) { > + rq_psn = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]); > + if (rd_check_is_filtered(rd, "rq-psn", rq_psn)) > + continue; > + } else { > + if (rd_check_is_key_exist(rd, "rq-psn")) > + continue; > + } > + > + sq_psn = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]); > + if (rd_check_is_filtered(rd, "sq-psn", sq_psn)) > + continue; > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) { > + path_mig_state = > mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]); > + if (rd_check_is_string_filtered(rd, "path-mig-state", > path_mig_to_str(path_mig_state))) > + continue; > + } else { > + if (rd_check_is_key_exist(rd, "path-mig-state")) > + continue; > + } > + > + type = > mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]); > + if (rd_check_is_string_filtered(rd, "type", > qp_types_to_str(type))) > + continue; > + > + state = > mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]); > + if (rd_check_is_string_filtered(rd, "state", > qp_states_to_str(state))) > + continue; > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) { > + pid = > mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]); > + comm = get_task_name(pid); > + } > + > + if (rd_check_is_filtered(rd, "pid", pid)) > + continue; Is comm leaked here when ATTR_RES_PID is present? > + > + if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) > + /* discard const from mnl_attr_get_str */ > + comm = (char > *)mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); And also here if the kernel ever passes up both PID and KERN_NAME (which it isn't supposed to). Steve. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information 2018-02-01 20:05 ` Steve Wise @ 2018-02-05 13:22 ` Leon Romanovsky [not found] ` <20180205132231.GD2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org> 0 siblings, 1 reply; 18+ messages in thread From: Leon Romanovsky @ 2018-02-05 13:22 UTC (permalink / raw) To: Steve Wise Cc: 'David Ahern', 'RDMA mailing list', 'netdev', 'Stephen Hemminger' [-- Attachment #1: Type: text/plain, Size: 1033 bytes --] On Thu, Feb 01, 2018 at 02:05:08PM -0600, Steve Wise wrote: > Hey Leon, <...> > > > +static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data) > > +{ <...> > > + > > + mnl_attr_for_each_nested(nla_entry, nla_table) { > > + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; > > + uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn; > > + uint8_t type, state, path_mig_state = 0; > > + uint32_t port = 0, pid = 0; > > + char *comm = NULL; <...> > > + > > + if (rd_check_is_filtered(rd, "pid", pid)) > > + continue; > > Is comm leaked here when ATTR_RES_PID is present? > > > > + > > + if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) > > + /* discard const from mnl_attr_get_str */ > > + comm = (char > > *)mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); > > And also here if the kernel ever passes up both PID and KERN_NAME (which it > isn't supposed to). Yes, you are right, and the bad thing that I prepared everything to call free() unconditionally by setting comm to be NULL. Thanks > > > Steve. > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
[parent not found: <20180205132231.GD2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>]
* Re: [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information [not found] ` <20180205132231.GD2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org> @ 2018-02-05 14:00 ` Leon Romanovsky [not found] ` <20180205140037.GF2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org> 0 siblings, 1 reply; 18+ messages in thread From: Leon Romanovsky @ 2018-02-05 14:00 UTC (permalink / raw) To: 'David Ahern' Cc: Steve Wise, 'RDMA mailing list', 'Stephen Hemminger' [-- Attachment #1: Type: text/plain, Size: 1993 bytes --] On Mon, Feb 05, 2018 at 03:22:31PM +0200, Leon Romanovsky wrote: > On Thu, Feb 01, 2018 at 02:05:08PM -0600, Steve Wise wrote: > > Hey Leon, > > <...> > > > > > > +static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data) > > > +{ > > <...> > > > > + > > > + mnl_attr_for_each_nested(nla_entry, nla_table) { > > > + struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; > > > + uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn; > > > + uint8_t type, state, path_mig_state = 0; > > > + uint32_t port = 0, pid = 0; > > > + char *comm = NULL; > > <...> > > > > + > > > + if (rd_check_is_filtered(rd, "pid", pid)) > > > + continue; > > > > Is comm leaked here when ATTR_RES_PID is present? > > > > > > > + > > > + if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) > > > + /* discard const from mnl_attr_get_str */ > > > + comm = (char > > > *)mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]); > > > > And also here if the kernel ever passes up both PID and KERN_NAME (which it > > isn't supposed to). > > Yes, you are right, and the bad thing that I prepared everything to call > free() unconditionally by setting comm to be NULL. Stephen, David, How do you want me to proceed? The actual change is pretty minor: diff --git a/rdma/res.c b/rdma/res.c index 2a63e712..31d0c4a7 100644 --- a/rdma/res.c +++ b/rdma/res.c @@ -395,8 +395,10 @@ static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data) comm = get_task_name(pid); } - if (rd_check_is_filtered(rd, "pid", pid)) + if (rd_check_is_filtered(rd, "pid", pid)) { + free(comm); continue; + } if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) /* discard const from mnl_attr_get_str */ @@ -420,8 +422,7 @@ static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data) print_pid(rd, pid); print_comm(rd, comm, nla_line); - if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) - free(comm); + free(comm); if (rd->json_output) jsonw_end_array(rd->jw); > > Thanks > > > > > > > Steve. > > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply related [flat|nested] 18+ messages in thread
[parent not found: <20180205140037.GF2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>]
* Re: [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information [not found] ` <20180205140037.GF2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org> @ 2018-02-05 16:21 ` David Ahern 0 siblings, 0 replies; 18+ messages in thread From: David Ahern @ 2018-02-05 16:21 UTC (permalink / raw) To: Leon Romanovsky, 'Stephen Hemminger' Cc: Steve Wise, 'RDMA mailing list' On 2/5/18 7:00 AM, Leon Romanovsky wrote: > > Stephen, David, > > How do you want me to proceed? > Since the RDMA code is in Linus' tree for 4.16, I think the patches should go through Stephen's tree and the master branch. Stephen needs to decide about the fixup. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iproute2-next 00/10] RDMA resource tracking [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> ` (2 preceding siblings ...) 2018-01-31 8:11 ` [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information Leon Romanovsky @ 2018-01-31 8:17 ` Leon Romanovsky 2018-02-06 1:25 ` Stephen Hemminger 4 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:17 UTC (permalink / raw) To: David Ahern; +Cc: RDMA mailing list, Steve Wise, netdev, Stephen Hemminger [-- Attachment #1: Type: text/plain, Size: 1542 bytes --] On Wed, Jan 31, 2018 at 10:11:46AM +0200, Leon Romanovsky wrote: > Changelog: > v2 -> v3: > * Rebased to commit: 1e24e773f144 ("Merge branch 'iproute2-master' into iproute2-next") > * Refreshed include/uapi/rdma/rdma_netlink.h file > * Fixed bug, where cxgb4 was printed twice. > v1 -> v2; > * Added checks for all occurrences of strdup failures and added patch > with fix of already merged code. > * Sync with latest kernel code. > * Rewrote table representation to be similar to "ip route" output. > * Implemented string filters. > * Removed curr/max representation from the summary output. > v0 -> v1: > * Fixed subject title in patch #1: rdam -> rdma. > * Added newline between variable declaration and the code. > * Add check to failure in strdup() call in rd_check_is_string_filtered(). > * Rewrote res_qp_parse_cb() to avoid long lines and extra indentation. > > ------------------------------------------------------------------------ > > David, Stephen, > > The kernel code is accepted to the RDMA and will be sent to Linus in > this merge window, and this is refreshed version of user space part. > > Because, I found bug in handling cxgb4 devices and we cleaned header > file a little bit more, it was more wise to resend the series instead > of applying v2. > > https://patchwork.ozlabs.org/project/netdev/list/?series=RDMA+resource+tracking&submitter=68852&state=8&q=&archive=&delegate= > > Thanks And as expected, I forgot to add version in the subject line. Sorry for that. Thanks [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iproute2-next 00/10] RDMA resource tracking [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> ` (3 preceding siblings ...) 2018-01-31 8:17 ` [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky @ 2018-02-06 1:25 ` Stephen Hemminger 2018-02-06 7:29 ` Leon Romanovsky 4 siblings, 1 reply; 18+ messages in thread From: Stephen Hemminger @ 2018-02-06 1:25 UTC (permalink / raw) To: Leon Romanovsky; +Cc: David Ahern, RDMA mailing list, Steve Wise, netdev On Wed, 31 Jan 2018 10:11:46 +0200 Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote: > Changelog: > v2 -> v3: > * Rebased to commit: 1e24e773f144 ("Merge branch 'iproute2-master' into iproute2-next") > * Refreshed include/uapi/rdma/rdma_netlink.h file > * Fixed bug, where cxgb4 was printed twice. > v1 -> v2; > * Added checks for all occurrences of strdup failures and added patch > with fix of already merged code. > * Sync with latest kernel code. > * Rewrote table representation to be similar to "ip route" output. > * Implemented string filters. > * Removed curr/max representation from the summary output. > v0 -> v1: > * Fixed subject title in patch #1: rdam -> rdma. > * Added newline between variable declaration and the code. > * Add check to failure in strdup() call in rd_check_is_string_filtered(). > * Rewrote res_qp_parse_cb() to avoid long lines and extra indentation. > > ------------------------------------------------------------------------ > > David, Stephen, > > The kernel code is accepted to the RDMA and will be sent to Linus in > this merge window, and this is refreshed version of user space part. > > Because, I found bug in handling cxgb4 devices and we cleaned header > file a little bit more, it was more wise to resend the series instead > of applying v2. > > https://patchwork.ozlabs.org/project/netdev/list/?series=RDMA+resource+tracking&submitter=68852&state=8&q=&archive=&delegate= > > Thanks > > Cc: RDMA mailing list <linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org> > Cc: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org> > > [1] https://www.spinics.net/lists/linux-rdma/msg59535.html > > Leon Romanovsky (10): > rdma: Add option to provide "-" sign for the port number > rdma: Make visible the number of arguments > rdma: Add filtering infrastructure > rdma: Set pointer to device name position > rdma: Allow external usage of compare string routine > rdma: Update kernel header file > rdma: Add resource tracking summary > rdma: Add QP resource tracking information > rdma: Document resource tracking > rdma: Check return value of strdup call > > include/uapi/rdma/rdma_netlink.h | 67 +++++- > man/man8/rdma-resource.8 | 86 +++++++ > rdma/Makefile | 2 +- > rdma/link.c | 2 +- > rdma/rdma.c | 4 +- > rdma/rdma.h | 28 ++- > rdma/res.c | 486 +++++++++++++++++++++++++++++++++++++++ > rdma/utils.c | 321 +++++++++++++++++++++++++- > 8 files changed, 971 insertions(+), 25 deletions(-) > create mode 100644 man/man8/rdma-resource.8 > create mode 100644 rdma/res.c > > -- > 2.16.1 > Applied these to the master branch. Dropped the kernel header update, picked that up through the other update process. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH iproute2-next 00/10] RDMA resource tracking 2018-02-06 1:25 ` Stephen Hemminger @ 2018-02-06 7:29 ` Leon Romanovsky 0 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-02-06 7:29 UTC (permalink / raw) To: Stephen Hemminger; +Cc: David Ahern, RDMA mailing list, Steve Wise, netdev [-- Attachment #1: Type: text/plain, Size: 3120 bytes --] On Mon, Feb 05, 2018 at 05:25:53PM -0800, Stephen Hemminger wrote: > On Wed, 31 Jan 2018 10:11:46 +0200 > Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote: > > > Changelog: > > v2 -> v3: > > * Rebased to commit: 1e24e773f144 ("Merge branch 'iproute2-master' into iproute2-next") > > * Refreshed include/uapi/rdma/rdma_netlink.h file > > * Fixed bug, where cxgb4 was printed twice. > > v1 -> v2; > > * Added checks for all occurrences of strdup failures and added patch > > with fix of already merged code. > > * Sync with latest kernel code. > > * Rewrote table representation to be similar to "ip route" output. > > * Implemented string filters. > > * Removed curr/max representation from the summary output. > > v0 -> v1: > > * Fixed subject title in patch #1: rdam -> rdma. > > * Added newline between variable declaration and the code. > > * Add check to failure in strdup() call in rd_check_is_string_filtered(). > > * Rewrote res_qp_parse_cb() to avoid long lines and extra indentation. > > > > ------------------------------------------------------------------------ > > > > David, Stephen, > > > > The kernel code is accepted to the RDMA and will be sent to Linus in > > this merge window, and this is refreshed version of user space part. > > > > Because, I found bug in handling cxgb4 devices and we cleaned header > > file a little bit more, it was more wise to resend the series instead > > of applying v2. > > > > https://patchwork.ozlabs.org/project/netdev/list/?series=RDMA+resource+tracking&submitter=68852&state=8&q=&archive=&delegate= > > > > Thanks > > > > Cc: RDMA mailing list <linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org> > > Cc: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org> > > > > [1] https://www.spinics.net/lists/linux-rdma/msg59535.html > > > > Leon Romanovsky (10): > > rdma: Add option to provide "-" sign for the port number > > rdma: Make visible the number of arguments > > rdma: Add filtering infrastructure > > rdma: Set pointer to device name position > > rdma: Allow external usage of compare string routine > > rdma: Update kernel header file > > rdma: Add resource tracking summary > > rdma: Add QP resource tracking information > > rdma: Document resource tracking > > rdma: Check return value of strdup call > > > > include/uapi/rdma/rdma_netlink.h | 67 +++++- > > man/man8/rdma-resource.8 | 86 +++++++ > > rdma/Makefile | 2 +- > > rdma/link.c | 2 +- > > rdma/rdma.c | 4 +- > > rdma/rdma.h | 28 ++- > > rdma/res.c | 486 +++++++++++++++++++++++++++++++++++++++ > > rdma/utils.c | 321 +++++++++++++++++++++++++- > > 8 files changed, 971 insertions(+), 25 deletions(-) > > create mode 100644 man/man8/rdma-resource.8 > > create mode 100644 rdma/res.c > > > > -- > > 2.16.1 > > > > Applied these to the master branch. > Dropped the kernel header update, picked that up through the other update process. Thanks a lot [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 04/10] rdma: Set pointer to device name position 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky ` (2 preceding siblings ...) [not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 05/10] rdma: Allow external usage of compare string routine Leon Romanovsky ` (3 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> The dev and link execution callbacks expects that next command line argument is device or port name. Set pointer to device or port name position prior calls to rd_exec_dev()/rd_exec_link(). Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- rdma/rdma.h | 1 + rdma/utils.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/rdma/rdma.h b/rdma/rdma.h index 8e60ce26..35506a96 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -87,6 +87,7 @@ int rd_exec_cmd(struct rd *rd, const struct rd_cmd *c, const char *str); int rd_exec_dev(struct rd *rd, int (*cb)(struct rd *rd)); int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port); void rd_free(struct rd *rd); +int rd_set_arg_to_devname(struct rd *rd); int rd_argc(struct rd *rd); /* diff --git a/rdma/utils.c b/rdma/utils.c index 157699c0..f93f05e1 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -412,6 +412,25 @@ void rd_free(struct rd *rd) filters_cleanup(rd); } +int rd_set_arg_to_devname(struct rd *rd) +{ + int ret = 0; + + while (!rd_no_arg(rd)) { + if (rd_argv_match(rd, "dev") || rd_argv_match(rd, "link")) { + rd_arg_inc(rd); + if (rd_no_arg(rd)) { + pr_err("No device name was supplied\n"); + ret = -EINVAL; + } + goto out; + } + rd_arg_inc(rd); + } +out: + return ret; +} + int rd_exec_link(struct rd *rd, int (*cb)(struct rd *rd), bool strict_port) { struct dev_map *dev_map; -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 05/10] rdma: Allow external usage of compare string routine 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky ` (3 preceding siblings ...) 2018-01-31 8:11 ` [PATCH iproute2-next 04/10] rdma: Set pointer to device name position Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 06/10] rdma: Update kernel header file Leon Romanovsky ` (2 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- rdma/rdma.h | 2 ++ rdma/utils.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rdma/rdma.h b/rdma/rdma.h index 35506a96..d2cde895 100644 --- a/rdma/rdma.h +++ b/rdma/rdma.h @@ -90,6 +90,8 @@ void rd_free(struct rd *rd); int rd_set_arg_to_devname(struct rd *rd); int rd_argc(struct rd *rd); +int strcmpx(const char *str1, const char *str2); + /* * Device manipulation */ diff --git a/rdma/utils.c b/rdma/utils.c index f93f05e1..9e15b7cf 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -24,7 +24,7 @@ char *rd_argv(struct rd *rd) return *rd->argv; } -static int strcmpx(const char *str1, const char *str2) +int strcmpx(const char *str1, const char *str2) { if (strlen(str1) > strlen(str2)) return -1; -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 06/10] rdma: Update kernel header file 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky ` (4 preceding siblings ...) 2018-01-31 8:11 ` [PATCH iproute2-next 05/10] rdma: Allow external usage of compare string routine Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 09/10] rdma: Document resource tracking Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 10/10] rdma: Check return value of strdup call Leon Romanovsky 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> Synchronize iporute2 package with latest kernel RDMA netlink header file. Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- include/uapi/rdma/rdma_netlink.h | 67 ++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h index 48fbf3c3..4c77e2a7 100644 --- a/include/uapi/rdma/rdma_netlink.h +++ b/include/uapi/rdma/rdma_netlink.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _RDMA_NETLINK_H -#define _RDMA_NETLINK_H +#ifndef _UAPI_RDMA_NETLINK_H +#define _UAPI_RDMA_NETLINK_H #include <linux/types.h> @@ -227,14 +227,16 @@ enum rdma_nldev_command { RDMA_NLDEV_CMD_UNSPEC, RDMA_NLDEV_CMD_GET, /* can dump */ - RDMA_NLDEV_CMD_SET, - RDMA_NLDEV_CMD_NEW, - RDMA_NLDEV_CMD_DEL, - RDMA_NLDEV_CMD_PORT_GET, /* can dump */ - RDMA_NLDEV_CMD_PORT_SET, - RDMA_NLDEV_CMD_PORT_NEW, - RDMA_NLDEV_CMD_PORT_DEL, + /* 2 - 4 are free to use */ + + RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */ + + /* 6 - 8 are free to use */ + + RDMA_NLDEV_CMD_RES_GET = 9, /* can dump */ + + RDMA_NLDEV_CMD_RES_QP_GET, /* can dump */ RDMA_NLDEV_NUM_OPS }; @@ -303,6 +305,51 @@ enum rdma_nldev_attr { RDMA_NLDEV_ATTR_DEV_NODE_TYPE, /* u8 */ + RDMA_NLDEV_ATTR_RES_SUMMARY, /* nested table */ + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY, /* nested table */ + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME, /* string */ + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR, /* u64 */ + + RDMA_NLDEV_ATTR_RES_QP, /* nested table */ + RDMA_NLDEV_ATTR_RES_QP_ENTRY, /* nested table */ + /* + * Local QPN + */ + RDMA_NLDEV_ATTR_RES_LQPN, /* u32 */ + /* + * Remote QPN, + * Applicable for RC and UC only IBTA 11.2.5.3 QUERY QUEUE PAIR + */ + RDMA_NLDEV_ATTR_RES_RQPN, /* u32 */ + /* + * Receive Queue PSN, + * Applicable for RC and UC only 11.2.5.3 QUERY QUEUE PAIR + */ + RDMA_NLDEV_ATTR_RES_RQ_PSN, /* u32 */ + /* + * Send Queue PSN + */ + RDMA_NLDEV_ATTR_RES_SQ_PSN, /* u32 */ + RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE, /* u8 */ + /* + * QP types as visible to RDMA/core, the reserved QPT + * are not exported through this interface. + */ + RDMA_NLDEV_ATTR_RES_TYPE, /* u8 */ + RDMA_NLDEV_ATTR_RES_STATE, /* u8 */ + /* + * Process ID which created object, + * in case of kernel origin, PID won't exist. + */ + RDMA_NLDEV_ATTR_RES_PID, /* u32 */ + /* + * The name of process created following resource. + * It will exist only for kernel objects. + * For user created objects, the user is supposed + * to read /proc/PID/comm file. + */ + RDMA_NLDEV_ATTR_RES_KERN_NAME, /* string */ + RDMA_NLDEV_ATTR_MAX }; -#endif /* _RDMA_NETLINK_H */ +#endif /* _UAPI_RDMA_NETLINK_H */ -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 09/10] rdma: Document resource tracking 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky ` (5 preceding siblings ...) 2018-01-31 8:11 ` [PATCH iproute2-next 06/10] rdma: Update kernel header file Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 2018-01-31 8:11 ` [PATCH iproute2-next 10/10] rdma: Check return value of strdup call Leon Romanovsky 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> Spartan version of resource tracking documentation. Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- man/man8/rdma-resource.8 | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 man/man8/rdma-resource.8 diff --git a/man/man8/rdma-resource.8 b/man/man8/rdma-resource.8 new file mode 100644 index 00000000..ff5d25d7 --- /dev/null +++ b/man/man8/rdma-resource.8 @@ -0,0 +1,86 @@ +.TH RDMA\-RESOURCE 8 "26 Dec 2017" "iproute2" "Linux" +.SH NAME +rdma-resource \- rdma resource configuration +.SH SYNOPSIS +.sp +.ad l +.in +8 +.ti -8 +.B rdma +.RI "[ " OPTIONS " ]" +.B resource +.RI " { " COMMAND " | " +.BR help " }" +.sp + +.ti -8 +.IR OPTIONS " := { " +\fB\-j\fR[\fIson\fR] | +\fB\-d\fR[\fIetails\fR] } + +.ti -8 +.B rdma resource show +.RI "[ " DEV/PORT_INDEX " ]" + +.ti -8 +.B rdma resource help + +.SH "DESCRIPTION" +.SS rdma resource show - display rdma resource tracking information + +.PP +.I "DEV/PORT_INDEX" +- specifies the RDMA link to show. +If this argument is omitted all links are listed. + +.SH "EXAMPLES" +.PP +rdma resource show +.RS 4 +Shows summary for all devices on the system. +.RE +.PP +rdma resource show mlx5_2 +.RS 4 +Shows the state of specified rdma device. +.RE +.PP +rdma res show qp link mlx5_4 +.RS 4 +Get all QPs for the specific device. +.RE +.PP +rdma res show qp link mlx5_4/1 +.RS 4 +Get QPs of specific port. +.RE +.PP +rdma res show qp link mlx5_4/0 +.RS 4 +Provide illegal port number (0 is illegal). +.RE +.PP +rdma res show qp link mlx5_4/- +.RS 4 +Get QPs which have not assigned port yet. +.RE +.PP +rdma res show qp link mlx5_4/- -d +.RS 4 +Detailed view. +.RE +.PP +rdma res show qp link mlx5_4/1 lqpn 0-6 +.RS 4 +Limit to specific Local QPNs. +.RE +.PP + +.SH SEE ALSO +.BR rdma (8), +.BR rdma-dev (8), +.BR rdma-link (8), +.br + +.SH AUTHOR +Leon Romanovsky <leonro@mellanox.com> -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH iproute2-next 10/10] rdma: Check return value of strdup call 2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky ` (6 preceding siblings ...) 2018-01-31 8:11 ` [PATCH iproute2-next 09/10] rdma: Document resource tracking Leon Romanovsky @ 2018-01-31 8:11 ` Leon Romanovsky 7 siblings, 0 replies; 18+ messages in thread From: Leon Romanovsky @ 2018-01-31 8:11 UTC (permalink / raw) To: David Ahern Cc: RDMA mailing list, Steve Wise, Leon Romanovsky, netdev, Stephen Hemminger, Leon Romanovsky From: Leon Romanovsky <leonro@mellanox.com> Fixes: 74bd75c2b68d ("rdma: Add basic infrastructure for RDMA tool") Signed-off-by: Leon Romanovsky <leonro@mellanox.com> --- rdma/utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rdma/utils.c b/rdma/utils.c index 059aa788..f9460162 100644 --- a/rdma/utils.c +++ b/rdma/utils.c @@ -98,6 +98,10 @@ static struct dev_map *dev_map_alloc(const char *dev_name) if (!dev_map) return NULL; dev_map->dev_name = strdup(dev_name); + if (!dev_map->dev_name) { + free(dev_map); + return NULL; + } return dev_map; } -- 2.16.1 ^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2018-02-06 7:29 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-31 8:11 [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 01/10] rdma: Add option to provide "-" sign for the port number Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 02/10] rdma: Make visible the number of arguments Leon Romanovsky
[not found] ` <20180131081156.19607-1-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2018-01-31 8:11 ` [PATCH iproute2-next 03/10] rdma: Add filtering infrastructure Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 07/10] rdma: Add resource tracking summary Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 08/10] rdma: Add QP resource tracking information Leon Romanovsky
[not found] ` <20180131081156.19607-9-leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2018-02-01 20:05 ` Steve Wise
2018-02-05 13:22 ` Leon Romanovsky
[not found] ` <20180205132231.GD2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
2018-02-05 14:00 ` Leon Romanovsky
[not found] ` <20180205140037.GF2567-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
2018-02-05 16:21 ` David Ahern
2018-01-31 8:17 ` [PATCH iproute2-next 00/10] RDMA resource tracking Leon Romanovsky
2018-02-06 1:25 ` Stephen Hemminger
2018-02-06 7:29 ` Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 04/10] rdma: Set pointer to device name position Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 05/10] rdma: Allow external usage of compare string routine Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 06/10] rdma: Update kernel header file Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 09/10] rdma: Document resource tracking Leon Romanovsky
2018-01-31 8:11 ` [PATCH iproute2-next 10/10] rdma: Check return value of strdup call Leon Romanovsky
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).