Fix build break in 64bit architectures
[platform/upstream/iproute2.git] / rdma / res.c
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
10 static 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
28 static 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
57 static int res_no_args_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
58 {
59         return MNL_CB_OK;
60 }
61
62 static 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
85 int _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
111 int _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
138 const 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
153 void 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])
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 ", str);
165 }
166
167 void print_dev(struct rd *rd, uint32_t idx, const char *name)
168 {
169         print_color_int(PRINT_ANY, COLOR_NONE, "ifindex", "ifindex %d ", idx);
170         print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "ifname %s ", name);
171 }
172
173 void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port,
174                 struct nlattr **nla_line)
175 {
176         print_color_uint(PRINT_JSON, COLOR_NONE, "ifindex", NULL, idx);
177         print_color_string(PRINT_ANY, COLOR_NONE, "ifname", "link %s/", name);
178         if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
179                 print_color_uint(PRINT_ANY, COLOR_NONE, "port", "%u ", port);
180 }
181
182 char *get_task_name(uint32_t pid)
183 {
184         char *comm;
185         FILE *f;
186
187         if (!pid)
188                 return NULL;
189
190         if (asprintf(&comm, "/proc/%d/comm", pid) < 0)
191                 return NULL;
192
193         f = fopen(comm, "r");
194         free(comm);
195         if (!f)
196                 return NULL;
197
198         if (fscanf(f, "%ms\n", &comm) != 1)
199                 comm = NULL;
200
201         fclose(f);
202
203         return comm;
204 }
205
206 void print_key(struct rd *rd, const char *name, uint64_t val,
207                struct nlattr *nlattr)
208 {
209         if (!nlattr)
210                 return;
211         print_color_string(PRINT_FP, COLOR_NONE, NULL, name, NULL);
212         print_color_hex(PRINT_ANY, COLOR_NONE, name, " 0x%" PRIx64 " ", val);
213 }
214
215 void res_print_uint(struct rd *rd, const char *name, uint64_t val,
216                     struct nlattr *nlattr)
217 {
218         if (!nlattr)
219                 return;
220         print_color_uint(PRINT_ANY, COLOR_NONE, name, name, val);
221         print_color_uint(PRINT_FP, COLOR_NONE, NULL, " %d ", val);
222 }
223
224 RES_FUNC(res_no_args,   RDMA_NLDEV_CMD_RES_GET, NULL, true, 0);
225
226 static int res_show(struct rd *rd)
227 {
228         const struct rd_cmd cmds[] = {
229                 { NULL,         res_no_args     },
230                 { "qp",         res_qp          },
231                 { "cm_id",      res_cm_id       },
232                 { "cq",         res_cq          },
233                 { "mr",         res_mr          },
234                 { "pd",         res_pd          },
235                 { 0 }
236         };
237
238         /*
239          * Special case to support "rdma res show DEV_NAME"
240          */
241         if (rd_argc(rd) == 1 && dev_map_lookup(rd, false))
242                 return rd_exec_dev(rd, _res_no_args);
243
244         return rd_exec_cmd(rd, cmds, "parameter");
245 }
246
247 int cmd_res(struct rd *rd)
248 {
249         const struct rd_cmd cmds[] = {
250                 { NULL,         res_show },
251                 { "show",       res_show },
252                 { "list",       res_show },
253                 { "help",       res_help },
254                 { 0 }
255         };
256
257         return rd_exec_cmd(rd, cmds, "resource command");
258 }