]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
rdma: Add resource tracking summary
authorLeon Romanovsky <leonro@mellanox.com>
Wed, 31 Jan 2018 08:11:53 +0000 (10:11 +0200)
committerStephen Hemminger <stephen@networkplumber.org>
Tue, 6 Feb 2018 01:23:52 +0000 (17:23 -0800)
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@mellanox.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
rdma/Makefile
rdma/rdma.c
rdma/rdma.h
rdma/res.c [new file with mode: 0644]
rdma/utils.c

index 454f25f867b6ec3d2d2f453881c94bf05d0b6f21..360f09b27edd1d4ebb68373ab09e3a583662d5b7 100644 (file)
@@ -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
index a21ba440707b46f29a3d4a7f7d46bcb4cb6610af..19608f41faa518b8e83c8508ef7323d6a82f6228 100644 (file)
@@ -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 }
        };
 
index d2cde89513096323167b5bfdafa7c8c69f363080..5809f7068ad293980bdc53a62eac0ded9376be29 100644 (file)
@@ -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 (file)
index 0000000..bd97c58
--- /dev/null
@@ -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@mellanox.com>
+ */
+
+#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");
+}
index 9e15b7cfd9042da17967c5a7e5a228ae26e87f95..344f0a931bda2cd4285e764d5b519c4872be2c01 100644 (file)
@@ -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)