]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/app/proc_info/main.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / dpdk / app / proc_info / main.c
1 /*
2 * BSD LICENSE
3 *
4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <errno.h>
38 #include <stdarg.h>
39 #include <inttypes.h>
40 #include <sys/queue.h>
41 #include <stdlib.h>
42 #include <getopt.h>
43
44 #include <rte_eal.h>
45 #include <rte_common.h>
46 #include <rte_debug.h>
47 #include <rte_ethdev.h>
48 #include <rte_malloc.h>
49 #include <rte_memory.h>
50 #include <rte_memzone.h>
51 #include <rte_launch.h>
52 #include <rte_tailq.h>
53 #include <rte_per_lcore.h>
54 #include <rte_lcore.h>
55 #include <rte_debug.h>
56 #include <rte_log.h>
57 #include <rte_atomic.h>
58 #include <rte_branch_prediction.h>
59 #include <rte_string_fns.h>
60
61 /* Maximum long option length for option parsing. */
62 #define MAX_LONG_OPT_SZ 64
63 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
64
65 /**< mask of enabled ports */
66 static uint32_t enabled_port_mask;
67 /**< Enable stats. */
68 static uint32_t enable_stats;
69 /**< Enable xstats. */
70 static uint32_t enable_xstats;
71 /**< Enable stats reset. */
72 static uint32_t reset_stats;
73 /**< Enable xstats reset. */
74 static uint32_t reset_xstats;
75 /**< Enable memory info. */
76 static uint32_t mem_info;
77
78 /**< display usage */
79 static void
80 proc_info_usage(const char *prgname)
81 {
82 printf("%s [EAL options] -- -p PORTMASK\n"
83 " -m to display DPDK memory zones, segments and TAILQ information\n"
84 " -p PORTMASK: hexadecimal bitmask of ports to retrieve stats for\n"
85 " --stats: to display port statistics, enabled by default\n"
86 " --xstats: to display extended port statistics, disabled by "
87 "default\n"
88 " --stats-reset: to reset port statistics\n"
89 " --xstats-reset: to reset port extended statistics\n",
90 prgname);
91 }
92
93 /*
94 * Parse the portmask provided at run time.
95 */
96 static int
97 parse_portmask(const char *portmask)
98 {
99 char *end = NULL;
100 unsigned long pm;
101
102 errno = 0;
103
104 /* parse hexadecimal string */
105 pm = strtoul(portmask, &end, 16);
106 if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') ||
107 (errno != 0)) {
108 printf("%s ERROR parsing the port mask\n", __func__);
109 return -1;
110 }
111
112 if (pm == 0)
113 return -1;
114
115 return pm;
116
117 }
118
119 /* Parse the argument given in the command line of the application */
120 static int
121 proc_info_parse_args(int argc, char **argv)
122 {
123 int opt;
124 int option_index;
125 char *prgname = argv[0];
126 static struct option long_option[] = {
127 {"stats", 0, NULL, 0},
128 {"stats-reset", 0, NULL, 0},
129 {"xstats", 0, NULL, 0},
130 {"xstats-reset", 0, NULL, 0},
131 {NULL, 0, 0, 0}
132 };
133
134 if (argc == 1)
135 proc_info_usage(prgname);
136
137 /* Parse command line */
138 while ((opt = getopt_long(argc, argv, "p:m",
139 long_option, &option_index)) != EOF) {
140 switch (opt) {
141 /* portmask */
142 case 'p':
143 enabled_port_mask = parse_portmask(optarg);
144 if (enabled_port_mask == 0) {
145 printf("invalid portmask\n");
146 proc_info_usage(prgname);
147 return -1;
148 }
149 break;
150 case 'm':
151 mem_info = 1;
152 break;
153 case 0:
154 /* Print stats */
155 if (!strncmp(long_option[option_index].name, "stats",
156 MAX_LONG_OPT_SZ))
157 enable_stats = 1;
158 /* Print xstats */
159 else if (!strncmp(long_option[option_index].name, "xstats",
160 MAX_LONG_OPT_SZ))
161 enable_xstats = 1;
162 /* Reset stats */
163 if (!strncmp(long_option[option_index].name, "stats-reset",
164 MAX_LONG_OPT_SZ))
165 reset_stats = 1;
166 /* Reset xstats */
167 else if (!strncmp(long_option[option_index].name, "xstats-reset",
168 MAX_LONG_OPT_SZ))
169 reset_xstats = 1;
170 break;
171
172 default:
173 proc_info_usage(prgname);
174 return -1;
175 }
176 }
177 return 0;
178 }
179
180 static void
181 meminfo_display(void)
182 {
183 printf("----------- MEMORY_SEGMENTS -----------\n");
184 rte_dump_physmem_layout(stdout);
185 printf("--------- END_MEMORY_SEGMENTS ---------\n");
186
187 printf("------------ MEMORY_ZONES -------------\n");
188 rte_memzone_dump(stdout);
189 printf("---------- END_MEMORY_ZONES -----------\n");
190
191 printf("------------- TAIL_QUEUES -------------\n");
192 rte_dump_tailq(stdout);
193 printf("---------- END_TAIL_QUEUES ------------\n");
194 }
195
196 static void
197 nic_stats_display(uint8_t port_id)
198 {
199 struct rte_eth_stats stats;
200 uint8_t i;
201
202 static const char *nic_stats_border = "########################";
203
204 rte_eth_stats_get(port_id, &stats);
205 printf("\n %s NIC statistics for port %-2d %s\n",
206 nic_stats_border, port_id, nic_stats_border);
207
208 printf(" RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64
209 " RX-bytes: %-10"PRIu64"\n", stats.ipackets, stats.ierrors,
210 stats.ibytes);
211 printf(" RX-nombuf: %-10"PRIu64"\n", stats.rx_nombuf);
212 printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64
213 " TX-bytes: %-10"PRIu64"\n", stats.opackets, stats.oerrors,
214 stats.obytes);
215
216 printf("\n");
217 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
218 printf(" Stats reg %2d RX-packets: %-10"PRIu64
219 " RX-errors: %-10"PRIu64
220 " RX-bytes: %-10"PRIu64"\n",
221 i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
222 }
223
224 printf("\n");
225 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
226 printf(" Stats reg %2d TX-packets: %-10"PRIu64
227 " TX-bytes: %-10"PRIu64"\n",
228 i, stats.q_opackets[i], stats.q_obytes[i]);
229 }
230
231 printf(" %s############################%s\n",
232 nic_stats_border, nic_stats_border);
233 }
234
235 static void
236 nic_stats_clear(uint8_t port_id)
237 {
238 printf("\n Clearing NIC stats for port %d\n", port_id);
239 rte_eth_stats_reset(port_id);
240 printf("\n NIC statistics for port %d cleared\n", port_id);
241 }
242
243 static void
244 nic_xstats_display(uint8_t port_id)
245 {
246 struct rte_eth_xstat_name *xstats_names;
247 struct rte_eth_xstat *xstats;
248 int len, ret, i;
249 static const char *nic_stats_border = "########################";
250
251 len = rte_eth_xstats_get_names(port_id, NULL, 0);
252 if (len < 0) {
253 printf("Cannot get xstats count\n");
254 return;
255 }
256 xstats = malloc(sizeof(xstats[0]) * len);
257 if (xstats == NULL) {
258 printf("Cannot allocate memory for xstats\n");
259 return;
260 }
261
262 xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len);
263 if (xstats_names == NULL) {
264 printf("Cannot allocate memory for xstat names\n");
265 free(xstats);
266 return;
267 }
268 if (len != rte_eth_xstats_get_names(
269 port_id, xstats_names, len)) {
270 printf("Cannot get xstat names\n");
271 goto err;
272 }
273
274 printf("###### NIC extended statistics for port %-2d #########\n",
275 port_id);
276 printf("%s############################\n",
277 nic_stats_border);
278 ret = rte_eth_xstats_get(port_id, xstats, len);
279 if (ret < 0 || ret > len) {
280 printf("Cannot get xstats\n");
281 goto err;
282 }
283
284 for (i = 0; i < len; i++)
285 printf("%s: %"PRIu64"\n",
286 xstats_names[i].name,
287 xstats[i].value);
288
289 printf("%s############################\n",
290 nic_stats_border);
291 err:
292 free(xstats);
293 free(xstats_names);
294 }
295
296 static void
297 nic_xstats_clear(uint8_t port_id)
298 {
299 printf("\n Clearing NIC xstats for port %d\n", port_id);
300 rte_eth_xstats_reset(port_id);
301 printf("\n NIC extended statistics for port %d cleared\n", port_id);
302 }
303
304 int
305 main(int argc, char **argv)
306 {
307 int ret;
308 int i;
309 char c_flag[] = "-c1";
310 char n_flag[] = "-n4";
311 char mp_flag[] = "--proc-type=secondary";
312 char *argp[argc + 3];
313 uint8_t nb_ports;
314
315 argp[0] = argv[0];
316 argp[1] = c_flag;
317 argp[2] = n_flag;
318 argp[3] = mp_flag;
319
320 for (i = 1; i < argc; i++)
321 argp[i + 3] = argv[i];
322
323 argc += 3;
324
325 ret = rte_eal_init(argc, argp);
326 if (ret < 0)
327 rte_panic("Cannot init EAL\n");
328
329 argc -= ret;
330 argv += (ret - 3);
331
332 if (!rte_eal_primary_proc_alive(NULL))
333 rte_exit(EXIT_FAILURE, "No primary DPDK process is running.\n");
334
335 /* parse app arguments */
336 ret = proc_info_parse_args(argc, argv);
337 if (ret < 0)
338 rte_exit(EXIT_FAILURE, "Invalid argument\n");
339
340 if (mem_info) {
341 meminfo_display();
342 return 0;
343 }
344
345 nb_ports = rte_eth_dev_count();
346 if (nb_ports == 0)
347 rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
348
349 /* If no port mask was specified*/
350 if (enabled_port_mask == 0)
351 enabled_port_mask = 0xffff;
352
353 for (i = 0; i < nb_ports; i++) {
354 if (enabled_port_mask & (1 << i)) {
355 if (enable_stats)
356 nic_stats_display(i);
357 else if (enable_xstats)
358 nic_xstats_display(i);
359 else if (reset_stats)
360 nic_stats_clear(i);
361 else if (reset_xstats)
362 nic_xstats_clear(i);
363 }
364 }
365
366 return 0;
367 }