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