cxgbe: get descriptor limits
[dpdk.git] / app / proc_info / main.c
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 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_config.h>
46 #include <rte_common.h>
47 #include <rte_debug.h>
48 #include <rte_ethdev.h>
49 #include <rte_malloc.h>
50 #include <rte_memory.h>
51 #include <rte_memzone.h>
52 #include <rte_launch.h>
53 #include <rte_tailq.h>
54 #include <rte_per_lcore.h>
55 #include <rte_lcore.h>
56 #include <rte_debug.h>
57 #include <rte_log.h>
58 #include <rte_atomic.h>
59 #include <rte_branch_prediction.h>
60 #include <rte_string_fns.h>
61
62 /* Maximum long option length for option parsing. */
63 #define MAX_LONG_OPT_SZ 64
64 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
65
66 /**< mask of enabled ports */
67 static uint32_t enabled_port_mask;
68 /**< Enable stats. */
69 static uint32_t enable_stats;
70 /**< Enable xstats. */
71 static uint32_t enable_xstats;
72 /**< Enable stats reset. */
73 static uint32_t reset_stats;
74 /**< Enable xstats reset. */
75 static uint32_t reset_xstats;
76 /**< Enable memory info. */
77 static uint32_t mem_info;
78
79 /**< display usage */
80 static void
81 proc_info_usage(const char *prgname)
82 {
83         printf("%s [EAL options] -- -p PORTMASK\n"
84                 "  -m to display DPDK memory zones, segments and TAILQ information\n"
85                 "  -p PORTMASK: hexadecimal bitmask of ports to retrieve stats for\n"
86                 "  --stats: to display port statistics, enabled by default\n"
87                 "  --xstats: to display extended port statistics, disabled by "
88                         "default\n"
89                 "  --stats-reset: to reset port statistics\n"
90                 "  --xstats-reset: to reset port extended statistics\n",
91                 prgname);
92 }
93
94 /*
95  * Parse the portmask provided at run time.
96  */
97 static int
98 parse_portmask(const char *portmask)
99 {
100         char *end = NULL;
101         unsigned long pm;
102
103         errno = 0;
104
105         /* parse hexadecimal string */
106         pm = strtoul(portmask, &end, 16);
107         if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') ||
108                 (errno != 0)) {
109                 printf("%s ERROR parsing the port mask\n", __func__);
110                 return -1;
111         }
112
113         if (pm == 0)
114                 return -1;
115
116         return pm;
117
118 }
119
120 /* Parse the argument given in the command line of the application */
121 static int
122 proc_info_parse_args(int argc, char **argv)
123 {
124         int opt;
125         int option_index;
126         char *prgname = argv[0];
127         static struct option long_option[] = {
128                 {"stats", 0, NULL, 0},
129                 {"stats-reset", 0, NULL, 0},
130                 {"xstats", 0, NULL, 0},
131                 {"xstats-reset", 0, NULL, 0},
132                 {NULL, 0, 0, 0}
133         };
134
135         if (argc == 1)
136                 proc_info_usage(prgname);
137
138         /* Parse command line */
139         while ((opt = getopt_long(argc, argv, "p:m",
140                         long_option, &option_index)) != EOF) {
141                 switch (opt) {
142                 /* portmask */
143                 case 'p':
144                         enabled_port_mask = parse_portmask(optarg);
145                         if (enabled_port_mask == 0) {
146                                 printf("invalid portmask\n");
147                                 proc_info_usage(prgname);
148                                 return -1;
149                         }
150                         break;
151                 case 'm':
152                         mem_info = 1;
153                         break;
154                 case 0:
155                         /* Print stats */
156                         if (!strncmp(long_option[option_index].name, "stats",
157                                         MAX_LONG_OPT_SZ))
158                                 enable_stats = 1;
159                         /* Print xstats */
160                         else if (!strncmp(long_option[option_index].name, "xstats",
161                                         MAX_LONG_OPT_SZ))
162                                 enable_xstats = 1;
163                         /* Reset stats */
164                         if (!strncmp(long_option[option_index].name, "stats-reset",
165                                         MAX_LONG_OPT_SZ))
166                                 reset_stats = 1;
167                         /* Reset xstats */
168                         else if (!strncmp(long_option[option_index].name, "xstats-reset",
169                                         MAX_LONG_OPT_SZ))
170                                 reset_xstats = 1;
171                         break;
172
173                 default:
174                         proc_info_usage(prgname);
175                         return -1;
176                 }
177         }
178         return 0;
179 }
180
181 static void
182 meminfo_display(void)
183 {
184         printf("----------- MEMORY_SEGMENTS -----------\n");
185         rte_dump_physmem_layout(stdout);
186         printf("--------- END_MEMORY_SEGMENTS ---------\n");
187
188         printf("------------ MEMORY_ZONES -------------\n");
189         rte_memzone_dump(stdout);
190         printf("---------- END_MEMORY_ZONES -----------\n");
191
192         printf("------------- TAIL_QUEUES -------------\n");
193         rte_dump_tailq(stdout);
194         printf("---------- END_TAIL_QUEUES ------------\n");
195 }
196
197 static void
198 nic_stats_display(uint8_t port_id)
199 {
200         struct rte_eth_stats stats;
201         uint8_t i;
202
203         static const char *nic_stats_border = "########################";
204
205         rte_eth_stats_get(port_id, &stats);
206         printf("\n  %s NIC statistics for port %-2d %s\n",
207                    nic_stats_border, port_id, nic_stats_border);
208
209         printf("  RX-packets: %-10"PRIu64"  RX-errors:  %-10"PRIu64
210                "  RX-bytes:  %-10"PRIu64"\n", stats.ipackets, stats.ierrors,
211                stats.ibytes);
212         printf("  RX-nombuf:  %-10"PRIu64"\n", stats.rx_nombuf);
213         printf("  TX-packets: %-10"PRIu64"  TX-errors:  %-10"PRIu64
214                "  TX-bytes:  %-10"PRIu64"\n", stats.opackets, stats.oerrors,
215                stats.obytes);
216
217         printf("\n");
218         for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
219                 printf("  Stats reg %2d RX-packets: %-10"PRIu64
220                        "  RX-errors: %-10"PRIu64
221                        "  RX-bytes: %-10"PRIu64"\n",
222                        i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]);
223         }
224
225         printf("\n");
226         for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
227                 printf("  Stats reg %2d TX-packets: %-10"PRIu64
228                        "  TX-bytes: %-10"PRIu64"\n",
229                        i, stats.q_opackets[i], stats.q_obytes[i]);
230         }
231
232         printf("  %s############################%s\n",
233                    nic_stats_border, nic_stats_border);
234 }
235
236 static void
237 nic_stats_clear(uint8_t port_id)
238 {
239         printf("\n Clearing NIC stats for port %d\n", port_id);
240         rte_eth_stats_reset(port_id);
241         printf("\n  NIC statistics for port %d cleared\n", port_id);
242 }
243
244 static void
245 nic_xstats_display(uint8_t port_id)
246 {
247         struct rte_eth_xstats *xstats;
248         int len, ret, i;
249         static const char *nic_stats_border = "########################";
250
251         len = rte_eth_xstats_get(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         printf("###### NIC extended statistics for port %-2d #########\n",
263                            port_id);
264         printf("%s############################\n",
265                            nic_stats_border);
266         ret = rte_eth_xstats_get(port_id, xstats, len);
267         if (ret < 0 || ret > len) {
268                 printf("Cannot get xstats\n");
269                 free(xstats);
270                 return;
271         }
272
273         for (i = 0; i < len; i++)
274                 printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value);
275
276         printf("%s############################\n",
277                            nic_stats_border);
278         free(xstats);
279 }
280
281 static void
282 nic_xstats_clear(uint8_t port_id)
283 {
284         printf("\n Clearing NIC xstats for port %d\n", port_id);
285         rte_eth_xstats_reset(port_id);
286         printf("\n  NIC extended statistics for port %d cleared\n", port_id);
287 }
288
289 int
290 main(int argc, char **argv)
291 {
292         int ret;
293         int i;
294         char c_flag[] = "-c1";
295         char n_flag[] = "-n4";
296         char mp_flag[] = "--proc-type=secondary";
297         char *argp[argc + 3];
298         uint8_t nb_ports;
299
300         argp[0] = argv[0];
301         argp[1] = c_flag;
302         argp[2] = n_flag;
303         argp[3] = mp_flag;
304
305         for (i = 1; i < argc; i++)
306                 argp[i + 3] = argv[i];
307
308         argc += 3;
309
310         ret = rte_eal_init(argc, argp);
311         if (ret < 0)
312                 rte_panic("Cannot init EAL\n");
313
314         argc -= ret;
315         argv += (ret - 3);
316
317         /* parse app arguments */
318         ret = proc_info_parse_args(argc, argv);
319         if (ret < 0)
320                 rte_exit(EXIT_FAILURE, "Invalid argument\n");
321
322         if (mem_info) {
323                 meminfo_display();
324                 return 0;
325         }
326
327         nb_ports = rte_eth_dev_count();
328         if (nb_ports == 0)
329                 rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n");
330
331
332         if (nb_ports > RTE_MAX_ETHPORTS)
333                 nb_ports = RTE_MAX_ETHPORTS;
334
335         /* If no port mask was specified*/
336         if (enabled_port_mask == 0)
337                 enabled_port_mask = 0xffff;
338
339         for (i = 0; i < nb_ports; i++) {
340                 if (enabled_port_mask & (1 << i)) {
341                         if (enable_stats)
342                                 nic_stats_display(i);
343                         else if (enable_xstats)
344                                 nic_xstats_display(i);
345                         else if (reset_stats)
346                                 nic_stats_clear(i);
347                         else if (reset_xstats)
348                                 nic_xstats_clear(i);
349                 }
350         }
351
352         return 0;
353 }