]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
rdma: Add support to get QP in raw format
authorMaor Gottlieb <maorg@mellanox.com>
Wed, 24 Jun 2020 10:40:10 +0000 (13:40 +0300)
committerDavid Ahern <dsahern@kernel.org>
Sun, 5 Jul 2020 18:11:00 +0000 (18:11 +0000)
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>
man/man8/rdma-resource.8
man/man8/rdma.8
rdma/rdma.c
rdma/rdma.h
rdma/res-qp.c
rdma/res.h
rdma/utils.c

index 05030d0a1606da42fd7c21a8c3590f53920f751d..8d0d14c6d66b02c62191b3ff39baa35469ff36a1 100644 (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.
index 221bf3343bf4cb5981476fd88705aa0be4f5b30b..c9e5d50d5ad799507cc5e2f927c87fa719ca1a0b 100644 (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.
index 22050555735dea309738e5f0bfebcae8200cd6c2..c24894d63aa810116c4104b6774cd71b800ee748 100644 (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)
index 735b1bf7c9f667fa2ad74e3ee5c676b323418655..a6c6bdea5a80c3461c172d2e88844caa11323cd2 100644 (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_ */
index 801cfca960d72f60d26211a7faa339e5beddde09..a38be3995d1924c38faa6f8b1e3eb1f85623f294 100644 (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;
        }
index 525171fcec511cd3da1b83aad33806a8e6273cdd..24eee2a133cfc0712d73890ce3a14dd07b8b4e62 100644 (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)                                          \
        {                                                                              \
index e25c3adfb80258dfefc9a1c8069b3b46e91e0d2a..4d3de4fadba2e5deb5a496988bae6486a5f0ef0d 100644 (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;