iproute2/rdma/res.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2/*
   3 * res.c        RDMA tool
   4 * Authors:     Leon Romanovsky <leonro@mellanox.com>
   5 */
   6
   7#include "res.h"
   8#include <inttypes.h>
   9
  10static int res_help(struct rd *rd)
  11{
  12        pr_out("Usage: %s resource\n", rd->filename);
  13        pr_out("          resource show [DEV]\n");
  14        pr_out("          resource show [qp|cm_id|pd|mr|cq]\n");
  15        pr_out("          resource show qp link [DEV/PORT]\n");
  16        pr_out("          resource show qp link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n");
  17        pr_out("          resource show cm_id link [DEV/PORT]\n");
  18        pr_out("          resource show cm_id link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n");
  19        pr_out("          resource show cq link [DEV/PORT]\n");
  20        pr_out("          resource show cq link [DEV/PORT] [FILTER-NAME FILTER-VALUE]\n");
  21        pr_out("          resource show pd dev [DEV]\n");
  22        pr_out("          resource show pd dev [DEV] [FILTER-NAME FILTER-VALUE]\n");
  23        pr_out("          resource show mr dev [DEV]\n");
  24        pr_out("          resource show mr dev [DEV] [FILTER-NAME FILTER-VALUE]\n");
  25        return 0;
  26}
  27
  28static int res_print_summary(struct rd *rd, struct nlattr **tb)
  29{
  30        struct nlattr *nla_table = tb[RDMA_NLDEV_ATTR_RES_SUMMARY];
  31        struct nlattr *nla_entry;
  32        const char *name;
  33        uint64_t curr;
  34        int err;
  35
  36        mnl_attr_for_each_nested(nla_entry, nla_table) {
  37                struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
  38
  39                err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
  40                if (err != MNL_CB_OK)
  41                        return -EINVAL;
  42
  43                if (!nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] ||
  44                    !nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]) {
  45                        return -EINVAL;
  46                }
  47
  48                name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]);
  49                curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
  50                res_print_uint(
  51                        rd, name, curr,
  52                        nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
  53        }
  54        return 0;
  55}
  56
  57static int res_no_args_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
  58{
  59        return MNL_CB_OK;
  60}
  61
  62static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data)
  63{
  64        struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
  65        struct rd *rd = data;
  66        const char *name;
  67        uint32_t idx;
  68
  69        mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
  70        if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] ||
  71            !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
  72            !tb[RDMA_NLDEV_ATTR_RES_SUMMARY])
  73                return MNL_CB_ERROR;
  74
  75        idx =  mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
  76        name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
  77        open_json_object(NULL);
  78        print_color_uint(PRINT_ANY, COLOR_NONE, "ifindex", "%u: ", idx);
  79        print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "%s: ", name);
  80        res_print_summary(rd, tb);
  81        newline(rd);
  82        return MNL_CB_OK;
  83}
  84
  85int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
  86                      uint32_t idx, uint32_t id)
  87{
  88        uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
  89        uint32_t seq;
  90        int ret;
  91
  92        rd_prepare_msg(rd, command, &seq, flags);
  93        mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
  94        if (rd->port_idx)
  95                mnl_attr_put_u32(rd->nlh,
  96                                 RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
  97
  98        mnl_attr_put_u32(rd->nlh, id, idx);
  99
 100        if (command == RDMA_NLDEV_CMD_STAT_GET)
 101                mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES,
 102                                 RDMA_NLDEV_ATTR_RES_MR);
 103
 104        ret = rd_send_msg(rd);
 105        if (ret)
 106                return ret;
 107        ret = rd_recv_msg(rd, callback, rd, seq);
 108        return ret;
 109}
 110
 111int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback)
 112{
 113        uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
 114        uint32_t seq;
 115        int ret;
 116
 117        if (command != RDMA_NLDEV_CMD_RES_GET)
 118                flags |= NLM_F_DUMP;
 119
 120        rd_prepare_msg(rd, command, &seq, flags);
 121        mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
 122        if (rd->port_idx)
 123                mnl_attr_put_u32(rd->nlh,
 124                                 RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
 125
 126        if (command == RDMA_NLDEV_CMD_STAT_GET)
 127                mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_STAT_RES,
 128                                 RDMA_NLDEV_ATTR_RES_MR);
 129
 130        ret = rd_send_msg(rd);
 131        if (ret)
 132                return ret;
 133
 134        ret = rd_recv_msg(rd, callback, rd, seq);
 135        return ret;
 136}
 137
 138const char *qp_types_to_str(uint8_t idx)
 139{
 140        static const char * const qp_types_str[] = { "SMI", "GSI", "RC",
 141                                                     "UC", "UD", "RAW_IPV6",
 142                                                     "RAW_ETHERTYPE",
 143                                                     "UNKNOWN", "RAW_PACKET",
 144                                                     "XRC_INI", "XRC_TGT",
 145                                                     [0xFF] = "DRIVER",
 146        };
 147
 148        if (idx < ARRAY_SIZE(qp_types_str) && qp_types_str[idx])
 149                return qp_types_str[idx];
 150        return "UNKNOWN";
 151}
 152
 153void print_comm(struct rd *rd, const char *str, struct nlattr **nla_line)
 154{
 155        char tmp[18];
 156
 157        if (!str)
 158                return;
 159
 160        if (nla_line[RDMA_NLDEV_ATTR_RES_PID] || rd->json_output)
 161                snprintf(tmp, sizeof(tmp), "%s", str);
 162        else
 163                snprintf(tmp, sizeof(tmp), "[%s]", str);
 164        print_color_string(PRINT_ANY, COLOR_NONE, "comm", "comm %s ", tmp);
 165}
 166
 167void print_dev(struct rd *rd, uint32_t idx, const char *name)
 168{
 169        print_color_int(PRINT_ANY, COLOR_NONE, "ifindex", NULL, idx);
 170        print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "dev %s ", name);
 171}
 172
 173void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port,
 174                struct nlattr **nla_line)
 175{
 176        char tmp[64] = {};
 177
 178        print_color_uint(PRINT_JSON, COLOR_NONE, "ifindex", NULL, idx);
 179        print_color_string(PRINT_ANY, COLOR_NONE, "ifname", NULL, name);
 180        if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]) {
 181                print_color_uint(PRINT_ANY, COLOR_NONE, "port", NULL, port);
 182                snprintf(tmp, sizeof(tmp), "%s/%d", name, port);
 183        } else {
 184                snprintf(tmp, sizeof(tmp), "%s/-", name);
 185        }
 186
 187        if (!rd->json_output)
 188                print_color_string(PRINT_ANY, COLOR_NONE, NULL, "link %s ",
 189                                   tmp);
 190}
 191
 192void print_qp_type(struct rd *rd, uint32_t val)
 193{
 194        print_color_string(PRINT_ANY, COLOR_NONE, "qp-type", "qp-type %s ",
 195                           qp_types_to_str(val));
 196}
 197
 198char *get_task_name(uint32_t pid)
 199{
 200        char *comm;
 201        FILE *f;
 202
 203        if (!pid)
 204                return NULL;
 205
 206        if (asprintf(&comm, "/proc/%d/comm", pid) < 0)
 207                return NULL;
 208
 209        f = fopen(comm, "r");
 210        free(comm);
 211        if (!f)
 212                return NULL;
 213
 214        if (fscanf(f, "%ms\n", &comm) != 1)
 215                comm = NULL;
 216
 217        fclose(f);
 218
 219        return comm;
 220}
 221
 222void print_key(struct rd *rd, const char *name, uint64_t val,
 223               struct nlattr *nlattr)
 224{
 225        if (!nlattr)
 226                return;
 227        print_color_string(PRINT_FP, COLOR_NONE, NULL, name, NULL);
 228        print_color_hex(PRINT_ANY, COLOR_NONE, name, " 0x%" PRIx64 " ", val);
 229}
 230
 231void res_print_uint(struct rd *rd, const char *name, uint64_t val,
 232                    struct nlattr *nlattr)
 233{
 234        if (!nlattr)
 235                return;
 236        print_color_uint(PRINT_ANY, COLOR_NONE, name, name, val);
 237        print_color_uint(PRINT_FP, COLOR_NONE, NULL, " %d ", val);
 238}
 239
 240RES_FUNC(res_no_args,   RDMA_NLDEV_CMD_RES_GET, NULL, true, 0);
 241
 242static int res_show(struct rd *rd)
 243{
 244        const struct rd_cmd cmds[] = {
 245                { NULL,         res_no_args     },
 246                { "qp",         res_qp          },
 247                { "cm_id",      res_cm_id       },
 248                { "cq",         res_cq          },
 249                { "mr",         res_mr          },
 250                { "pd",         res_pd          },
 251                { 0 }
 252        };
 253
 254        /*
 255         * Special case to support "rdma res show DEV_NAME"
 256         */
 257        if (rd_argc(rd) == 1 && dev_map_lookup(rd, false))
 258                return rd_exec_dev(rd, _res_no_args);
 259
 260        return rd_exec_cmd(rd, cmds, "parameter");
 261}
 262
 263int cmd_res(struct rd *rd)
 264{
 265        const struct rd_cmd cmds[] = {
 266                { NULL,         res_show },
 267                { "show",       res_show },
 268                { "list",       res_show },
 269                { "help",       res_help },
 270                { 0 }
 271        };
 272
 273        return rd_exec_cmd(rd, cmds, "resource command");
 274}
 275