iproute2/rdma/res-qp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2/*
   3 * res-qp.c     RDMA tool
   4 * Authors:     Leon Romanovsky <leonro@mellanox.com>
   5 */
   6
   7#include "res.h"
   8#include <inttypes.h>
   9
  10static const char *path_mig_to_str(uint8_t idx)
  11{
  12        static const char *const path_mig_str[] = { "MIGRATED", "REARM",
  13                                                    "ARMED" };
  14
  15        if (idx < ARRAY_SIZE(path_mig_str))
  16                return path_mig_str[idx];
  17        return "UNKNOWN";
  18}
  19
  20static const char *qp_states_to_str(uint8_t idx)
  21{
  22        static const char *const qp_states_str[] = { "RESET", "INIT", "RTR",
  23                                                     "RTS",   "SQD",  "SQE",
  24                                                     "ERR" };
  25
  26        if (idx < ARRAY_SIZE(qp_states_str))
  27                return qp_states_str[idx];
  28        return "UNKNOWN";
  29}
  30
  31static void print_rqpn(struct rd *rd, uint32_t val, struct nlattr **nla_line)
  32{
  33        if (!nla_line[RDMA_NLDEV_ATTR_RES_RQPN])
  34                return;
  35        print_color_uint(PRINT_ANY, COLOR_NONE, "rqpn", "rqpn %d ", val);
  36}
  37
  38static void print_type(struct rd *rd, uint32_t val)
  39{
  40        print_color_string(PRINT_ANY, COLOR_NONE, "type", "type %s ",
  41                           qp_types_to_str(val));
  42}
  43
  44static void print_state(struct rd *rd, uint32_t val)
  45{
  46        print_color_string(PRINT_ANY, COLOR_NONE, "state", "state %s ",
  47                           qp_states_to_str(val));
  48}
  49
  50static void print_rqpsn(struct rd *rd, uint32_t val, struct nlattr **nla_line)
  51{
  52        if (!nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN])
  53                return;
  54
  55        print_color_uint(PRINT_ANY, COLOR_NONE, "rq-psn", "rq-psn %d ", val);
  56}
  57
  58static void print_pathmig(struct rd *rd, uint32_t val, struct nlattr **nla_line)
  59{
  60        if (!nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE])
  61                return;
  62
  63        print_color_string(PRINT_ANY, COLOR_NONE, "path-mig-state",
  64                           "path-mig-state %s ", path_mig_to_str(val));
  65}
  66
  67static int res_qp_line_raw(struct rd *rd, const char *name, int idx,
  68                           struct nlattr **nla_line)
  69{
  70        if (!nla_line[RDMA_NLDEV_ATTR_RES_RAW])
  71                return MNL_CB_ERROR;
  72
  73        open_json_object(NULL);
  74        print_link(rd, idx, name, rd->port_idx, nla_line);
  75        print_raw_data(rd, nla_line);
  76        newline(rd);
  77
  78        return MNL_CB_OK;
  79}
  80
  81static int res_qp_line(struct rd *rd, const char *name, int idx,
  82                       struct nlattr **nla_line)
  83{
  84        uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn;
  85        uint8_t type, state, path_mig_state = 0;
  86        uint32_t port = 0, pid = 0;
  87        uint32_t pdn = 0;
  88        char *comm = NULL;
  89
  90        if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] ||
  91            !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] ||
  92            !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] ||
  93            !nla_line[RDMA_NLDEV_ATTR_RES_STATE])
  94                return MNL_CB_ERROR;
  95
  96        if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
  97                port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
  98
  99        if (port != rd->port_idx)
 100                goto out;
 101
 102        lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
 103        if (rd_is_filtered_attr(rd, "lqpn", lqpn,
 104                                nla_line[RDMA_NLDEV_ATTR_RES_LQPN]))
 105                goto out;
 106
 107        if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
 108                pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
 109        if (rd_is_filtered_attr(rd, "pdn", pdn,
 110                                nla_line[RDMA_NLDEV_ATTR_RES_PDN]))
 111                goto out;
 112
 113        if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN])
 114                rqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]);
 115        if (rd_is_filtered_attr(rd, "rqpn", rqpn,
 116                                nla_line[RDMA_NLDEV_ATTR_RES_RQPN]))
 117                goto out;
 118
 119        if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN])
 120                rq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]);
 121        if (rd_is_filtered_attr(rd, "rq-psn", rq_psn,
 122                                nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]))
 123                goto out;
 124
 125        sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
 126        if (rd_is_filtered_attr(rd, "sq-psn", sq_psn,
 127                                nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]))
 128                goto out;
 129
 130        if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE])
 131                path_mig_state = mnl_attr_get_u8(
 132                        nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]);
 133        if (rd_is_string_filtered_attr(
 134                    rd, "path-mig-state", path_mig_to_str(path_mig_state),
 135                    nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]))
 136                goto out;
 137
 138        type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
 139        if (rd_is_string_filtered_attr(rd, "type", qp_types_to_str(type),
 140                                       nla_line[RDMA_NLDEV_ATTR_RES_TYPE]))
 141                goto out;
 142
 143        state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
 144        if (rd_is_string_filtered_attr(rd, "state", qp_states_to_str(state),
 145                                       nla_line[RDMA_NLDEV_ATTR_RES_STATE]))
 146                goto out;
 147
 148        if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
 149                pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 150                comm = get_task_name(pid);
 151        }
 152
 153        if (rd_is_filtered_attr(rd, "pid", pid,
 154                                nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 155                goto out;
 156
 157        if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
 158                /* discard const from mnl_attr_get_str */
 159                comm = (char *)mnl_attr_get_str(
 160                        nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
 161
 162        open_json_object(NULL);
 163        print_link(rd, idx, name, port, nla_line);
 164        res_print_uint(rd, "lqpn", lqpn, nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
 165        print_rqpn(rd, rqpn, nla_line);
 166
 167        print_type(rd, type);
 168        print_state(rd, state);
 169
 170        print_rqpsn(rd, rq_psn, nla_line);
 171        res_print_uint(rd, "sq-psn", sq_psn,
 172                       nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
 173
 174        print_pathmig(rd, path_mig_state, nla_line);
 175        res_print_uint(rd, "pdn", pdn, nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
 176        res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 177        print_comm(rd, comm, nla_line);
 178
 179        print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
 180        newline(rd);
 181out:
 182        if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 183                free(comm);
 184        return MNL_CB_OK;
 185}
 186
 187int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
 188{
 189        struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 190        struct rd *rd = data;
 191        const char *name;
 192        uint32_t idx;
 193
 194        mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
 195        if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
 196                return MNL_CB_ERROR;
 197
 198        name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
 199        idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
 200
 201        return (rd->show_raw) ? res_qp_line_raw(rd, name, idx, tb) :
 202                res_qp_line(rd, name, idx, tb);
 203}
 204
 205int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 206{
 207        struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 208        struct nlattr *nla_table, *nla_entry;
 209        struct rd *rd = data;
 210        int ret = MNL_CB_OK;
 211        const char *name;
 212        uint32_t idx;
 213
 214        mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
 215        if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
 216            !tb[RDMA_NLDEV_ATTR_RES_QP])
 217                return MNL_CB_ERROR;
 218
 219        name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
 220        idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
 221        nla_table = tb[RDMA_NLDEV_ATTR_RES_QP];
 222
 223        mnl_attr_for_each_nested(nla_entry, nla_table) {
 224                struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 225
 226                ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
 227                if (ret != MNL_CB_OK)
 228                        break;
 229
 230                ret = (rd->show_raw) ? res_qp_line_raw(rd, name, idx, nla_line) :
 231                        res_qp_line(rd, name, idx, nla_line);
 232                if (ret != MNL_CB_OK)
 233                        break;
 234        }
 235        return ret;
 236}
 237