4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
38 #include <sys/types.h>
40 #include <sys/queue.h>
45 #include <rte_common.h>
46 #include <rte_byteorder.h>
48 #include <rte_memory.h>
49 #include <rte_memcpy.h>
50 #include <rte_memzone.h>
51 #include <rte_tailq.h>
53 #include <rte_per_lcore.h>
54 #include <rte_launch.h>
55 #include <rte_atomic.h>
56 #include <rte_cycles.h>
57 #include <rte_prefetch.h>
58 #include <rte_lcore.h>
59 #include <rte_per_lcore.h>
60 #include <rte_branch_prediction.h>
61 #include <rte_interrupts.h>
63 #include <rte_random.h>
64 #include <rte_debug.h>
65 #include <rte_ether.h>
66 #include <rte_ethdev.h>
68 #include <rte_mempool.h>
74 #include <rte_string_fns.h>
75 #include <rte_cfgfile.h>
79 struct app_params app;
81 static const char usage[] =
82 "Usage: %s EAL_OPTIONS-- -p PORT_MASK [-f CONFIG_FILE]\n";
85 app_print_usage(char *prgname)
87 printf(usage, prgname);
91 app_core_type_id_to_string(enum app_core_type id)
94 case APP_CORE_NONE: return "NONE";
95 case APP_CORE_MASTER: return "MASTER";
96 case APP_CORE_RX: return "RX";
97 case APP_CORE_TX: return "TX";
98 case APP_CORE_PT: return "PT";
99 case APP_CORE_FC: return "FC";
100 case APP_CORE_FW: return "FW";
101 case APP_CORE_RT: return "RT";
102 case APP_CORE_TM: return "TM";
103 case APP_CORE_IPV4_FRAG: return "IPV4_FRAG";
104 case APP_CORE_IPV4_RAS: return "IPV4_RAS";
105 default: return NULL;
110 app_core_type_string_to_id(const char *string, enum app_core_type *id)
112 if (strcmp(string, "NONE") == 0) {
116 if (strcmp(string, "MASTER") == 0) {
117 *id = APP_CORE_MASTER;
120 if (strcmp(string, "RX") == 0) {
124 if (strcmp(string, "TX") == 0) {
128 if (strcmp(string, "PT") == 0) {
132 if (strcmp(string, "FC") == 0) {
136 if (strcmp(string, "FW") == 0) {
140 if (strcmp(string, "RT") == 0) {
144 if (strcmp(string, "TM") == 0) {
148 if (strcmp(string, "IPV4_FRAG") == 0) {
149 *id = APP_CORE_IPV4_FRAG;
152 if (strcmp(string, "IPV4_RAS") == 0) {
153 *id = APP_CORE_IPV4_RAS;
161 app_get_core_mask(void)
163 uint64_t core_mask = 0;
166 for (i = 0; i < RTE_MAX_LCORE; i++) {
167 if (rte_lcore_is_enabled(i) == 0)
170 core_mask |= 1LLU << i;
177 app_install_coremask(uint64_t core_mask)
181 for (n_cores = 0, i = 0; i < RTE_MAX_LCORE; i++)
182 if (app.cores[i].core_type != APP_CORE_NONE)
185 if (n_cores != app.n_cores) {
186 rte_panic("Number of cores in COREMASK should be %u instead "
187 "of %u\n", n_cores, app.n_cores);
191 for (i = 0; i < RTE_MAX_LCORE; i++) {
194 if (app.cores[i].core_type == APP_CORE_NONE)
197 core_id = __builtin_ctzll(core_mask);
198 core_mask &= ~(1LLU << core_id);
200 app.cores[i].core_id = core_id;
206 app_install_cfgfile(const char *file_name)
208 struct rte_cfgfile *file;
211 memset(app.cores, 0, sizeof(app.cores));
213 if (file_name[0] == '\0')
216 file = rte_cfgfile_load(file_name, 0);
218 rte_panic("Config file %s not found\n", file_name);
222 n_cores = (uint32_t) rte_cfgfile_num_sections(file, "core",
224 if (n_cores < app.n_cores) {
225 rte_panic("Config file parse error: not enough cores specified "
226 "(%u cores missing)\n", app.n_cores - n_cores);
229 if (n_cores > app.n_cores) {
230 rte_panic("Config file parse error: too many cores specified "
231 "(%u cores too many)\n", n_cores - app.n_cores);
235 for (i = 0; i < n_cores; i++) {
236 struct app_core_params *p = &app.cores[i];
237 char section_name[16];
242 rte_snprintf(section_name, sizeof(section_name), "core %u", i);
243 if (!rte_cfgfile_has_section(file, section_name)) {
244 rte_panic("Config file parse error: core IDs are not "
245 "sequential (core %u missing)\n", i);
250 entry = rte_cfgfile_get_entry(file, section_name, "type");
252 rte_panic("Config file parse error: core %u type not "
256 if ((app_core_type_string_to_id(entry, &p->core_type) != 0) ||
257 (p->core_type == APP_CORE_NONE)) {
258 rte_panic("Config file parse error: core %u type "
264 entry = rte_cfgfile_get_entry(file, section_name, "queues in");
266 rte_panic("Config file parse error: core %u queues in "
271 for (j = 0; (j < APP_MAX_SWQ_PER_CORE) && (entry != NULL);
275 p->swq_in[j] = (uint32_t) strtol(entry, &next, 10);
281 if ((j != APP_MAX_SWQ_PER_CORE) || (*entry != '\0')) {
282 rte_panic("Config file parse error: core %u queues in "
288 entry = rte_cfgfile_get_entry(file, section_name, "queues out");
290 rte_panic("Config file parse error: core %u queues out "
295 for (j = 0; (j < APP_MAX_SWQ_PER_CORE) && (entry != NULL);
299 p->swq_out[j] = (uint32_t) strtol(entry, &next, 10);
304 if ((j != APP_MAX_SWQ_PER_CORE) || (*entry != '\0')) {
305 rte_panic("Config file parse error: core %u queues out "
311 rte_cfgfile_close(file);
316 void app_cores_config_print(void)
320 for (i = 0; i < RTE_MAX_LCORE; i++) {
321 struct app_core_params *p = &app.cores[i];
324 if (app.cores[i].core_type == APP_CORE_NONE)
327 printf("---> core %u: id = %u type = %6s [", i, p->core_id,
328 app_core_type_id_to_string(p->core_type));
329 for (j = 0; j < APP_MAX_SWQ_PER_CORE; j++)
330 printf("%2d ", (int) p->swq_in[j]);
333 for (j = 0; j < APP_MAX_SWQ_PER_CORE; j++)
334 printf("%2d ", (int) p->swq_out[j]);
341 app_install_port_mask(const char *arg)
350 port_mask = strtoul(arg, &end, 16);
351 if ((end == NULL) || (*end != '\0'))
358 for (i = 0; i < 64; i++) {
359 if ((port_mask & (1LLU << i)) == 0)
362 if (app.n_ports >= APP_MAX_PORTS)
365 app.ports[app.n_ports] = i;
369 if (!rte_is_power_of_2(app.n_ports))
376 app_parse_args(int argc, char **argv)
381 char *prgname = argv[0];
382 static struct option lgopts[] = {
385 uint64_t core_mask = app_get_core_mask();
387 app.n_cores = __builtin_popcountll(core_mask);
390 while ((opt = getopt_long(argc, argvopt, "p:f:", lgopts,
391 &option_index)) != EOF) {
394 if (app_install_port_mask(optarg) != 0)
395 rte_panic("PORT_MASK should specify a number "
396 "of ports that is power of 2 less or "
397 "equal to %u\n", APP_MAX_PORTS);
401 app_install_cfgfile(optarg);
409 app_install_coremask(core_mask);
411 app_cores_config_print();
414 argv[optind - 1] = prgname;
417 optind = 0; /* reset getopt lib */