/* Parse the argument given in the command line of the application */ int app_parse_args(int argc, char **argv) { int opt, ret; char **argvopt; int option_index; char *prgname = argv[0]; static struct option lgopts[] = { //aniadido {"record", 1, 0, 0}, //normal {"rx", 1, 0, 0}, {"tx", 1, 0, 0}, {"rsz", 1, 0, 0}, {"bsz", 1, 0, 0}, {"pos-lb", 1, 0, 0}, {NULL, 0, 0, 0} }; uint32_t arg_rx = 0; uint32_t arg_tx = 0; uint32_t arg_rsz = 0; uint32_t arg_bsz = 0; uint32_t arg_pos_lb = 0; argvopt = argv; while ((opt = getopt_long(argc, argvopt, "", lgopts, &option_index)) != EOF) { switch (opt) { /* long options */ case 0: if (!strcmp(lgopts[option_index].name, "rx")) { arg_rx = 1; ret = parse_arg_rx(optarg); if (ret) { printf("Incorrect value for --rx argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "tx")) { arg_tx = 1; ret = parse_arg_tx(optarg); if (ret) { printf("Incorrect value for --tx argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "w")) { ret = parse_arg_w(optarg); if (ret) { printf("Incorrect value for --w argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "record")) { strcpy(record_File,optarg); printf("Record value set to %s\n", record_File); } if (!strcmp(lgopts[option_index].name, "rsz")) { arg_rsz = 1; ret = parse_arg_rsz(optarg); if (ret) { printf("Incorrect value for --rsz argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "bsz")) { arg_bsz = 1; ret = parse_arg_bsz(optarg); if (ret) { printf("Incorrect value for --bsz argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "pos-lb")) { arg_pos_lb = 1; ret = parse_arg_pos_lb(optarg); if (ret) { printf("Incorrect value for --pos-lb argument (%d)\n", ret); return -1; } } break; default: return -1; } } /* Check that all mandatory arguments are provided */ if ((arg_rx == 0) || (arg_tx == 0) ){ printf("Not all mandatory arguments are present\n"); return -1; } /* Assign default values for the optional arguments not provided */ if (arg_rsz == 0) { app.nic_rx_ring_size = APP_DEFAULT_NIC_RX_RING_SIZE; app.nic_tx_ring_size = APP_DEFAULT_NIC_TX_RING_SIZE; app.ring_rx_size = APP_DEFAULT_RING_RX_SIZE; app.ring_tx_size = APP_DEFAULT_RING_TX_SIZE; } if (arg_bsz == 0) { app.burst_size_io_rx_read = APP_DEFAULT_BURST_SIZE_IO_RX_READ; app.burst_size_io_rx_write = APP_DEFAULT_BURST_SIZE_IO_RX_WRITE; app.burst_size_io_tx_read = APP_DEFAULT_BURST_SIZE_IO_TX_READ; app.burst_size_io_tx_write = APP_DEFAULT_BURST_SIZE_IO_TX_WRITE; app.burst_size_worker_read = APP_DEFAULT_BURST_SIZE_WORKER_READ; app.burst_size_worker_write = APP_DEFAULT_BURST_SIZE_WORKER_WRITE; } if (arg_pos_lb == 0) { app.pos_lb = APP_DEFAULT_IO_RX_LB_POS; } if (optind >= 0) argv[optind - 1] = prgname; ret = optind - 1; optind = 0; /* reset getopt lib */ return ret; }
/* Parse the argument given in the command line of the application */ int app_parse_args(int argc, const char *argv[]) { int opt, ret; char **argvopt; int option_index; const char *prgname = argv[0]; static const struct option lgopts[] = { {"rx", 1, 0, 0}, {"tx", 1, 0, 0}, {"w", 1, 0, 0}, {"rsz", 1, 0, 0}, {"bsz", 1, 0, 0}, {"no-cache", 0, 0, 0}, {"core-assign", 1, 0, 0}, {"kvstype", 1, 0, 0}, #ifdef __SSE4_2__ {"hashtype", 1, 0, 0}, #endif /* __SSE4_2__ */ {"fifoness", 1, 0, 0}, {"show-core-config", 0, 0, 0}, {NULL, 0, 0, 0} }; uint32_t arg_p = 0; uint32_t arg_w = 0; uint32_t arg_rx = 0; uint32_t arg_tx = 0; uint32_t arg_rsz = 0; uint32_t arg_bsz = 0; uint64_t portmask = 0; char *end = NULL; struct app_lcore_params *lp, *htlp; unsigned lcore, htcore, lcore_count, i, wk_lcore_count = 0; unsigned rx_lcore_start, tx_lcore_start, wk_lcore_start; int rx_lcore_inc, tx_lcore_inc, wk_lcore_inc; uint8_t portid, port_count, count, n; bool show_core_assign = false; argvopt = (char **)argv; while ((opt = getopt_long(argc, argvopt, "p:w:", lgopts, &option_index)) != EOF) { switch (opt) { case 'p': if (optarg[0] == '\0') { printf("Require value for -p argument\n"); return -1; } portmask = (uint64_t)strtoull(optarg, &end, 16); if (end == NULL || *end != '\0') { printf("Non-numerical value for -p argument\n"); return -1; } if (portmask == 0) { printf("Incorrect value for -p argument\n"); return -1; } arg_p = 1; break; case 'w': if (optarg[0] == '\0') { printf("Require value for -w argument\n"); return -1; } wk_lcore_count = (unsigned)strtoul(optarg, &end, 10); if (end == NULL || *end != '\0') { printf("Non-numerical value for -w argument\n"); return -1; } if (wk_lcore_count == 0) { printf("Incorrect value for -w argument\n"); return -1; } break; /* long options */ case 0: if (!strcmp(lgopts[option_index].name, "rx")) { arg_rx = 1; ret = parse_arg_rx(optarg); if (ret) { printf("Incorrect value for --rx argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "tx")) { arg_tx = 1; ret = parse_arg_tx(optarg); if (ret) { printf("Incorrect value for --tx argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "w")) { arg_w = 1; ret = parse_arg_w(optarg); if (ret) { printf("Incorrect value for --w argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "rsz")) { arg_rsz = 1; ret = parse_arg_rsz(optarg); if (ret) { printf("Incorrect value for --rsz argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "bsz")) { arg_bsz = 1; ret = parse_arg_bsz(optarg); if (ret) { printf("Incorrect value for --bsz argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "core-assign")) { ret = parse_arg_core_assign(optarg); if (ret) { printf("Incorrect value for --core-assign argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "no-cache")) { app.no_cache = 1; } if (!strcmp(lgopts[option_index].name, "kvstype")) { ret = parse_arg_kvstype(optarg); if (ret) { printf("Incorrect value for --ksvtype argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "hashtype")) { ret = parse_arg_hashtype(optarg); if (ret) { printf("Incorrect value for --hashtype argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "fifoness")) { ret = parse_arg_fifoness(optarg); if (ret) { printf("Incorrect value for --fifoness argument (%d)\n", ret); return -1; } } if (!strcmp(lgopts[option_index].name, "show-core-config")) { show_core_assign = true; } break; default: printf("Incorrect option\n"); return -1; } } /* Check that all mandatory arguments are provided */ if ((arg_rx == 0 || arg_tx == 0 || arg_w == 0) && arg_p == 0) { lagopus_exit_error(EXIT_FAILURE, "Not all mandatory arguments are present\n"); } port_count = 0; if (arg_p != 0) { /** * Assign lcore for each thread automatically. */ for (i = 0; i < 32; i++) { if ((portmask & (uint64_t)(1ULL << i)) != 0) { port_count++; } } if (port_count == 0) { lagopus_exit_error(EXIT_FAILURE, "error: port is not specified. use -p HEXNUM or --rx, --tx.\n"); } } for (lcore_count = 0, lcore = 0; lcore < RTE_MAX_LCORE; lcore++) { if (lcore == rte_get_master_lcore()) { continue; } if (!rte_lcore_is_enabled(lcore)) { continue; } lp = &app.lcore_params[lcore]; lp->socket_id = lcore_config[lcore].socket_id; lp->core_id = lcore_config[lcore].core_id; /* add lcore id except for hyper-threading core. */ for (htcore = 0; htcore < lcore; htcore++) { if (!rte_lcore_is_enabled(htcore)) { continue; } htlp = &app.lcore_params[htcore]; if (app.core_assign == CORE_ASSIGN_PERFORMANCE) { if (lp->socket_id == htlp->socket_id && lp->core_id == htlp->core_id) { break; } } } if (htcore == lcore) { lcores[lcore_count++] = lcore; } } if (lcore_count == 0) { lagopus_exit_error( EXIT_FAILURE, "Not enough active core " "(need at least 2 active core%s)\n", app.core_assign == CORE_ASSIGN_PERFORMANCE ? " except for HTT core" : ""); } if (app.core_assign == CORE_ASSIGN_MINIMUM) { lcore_count = 1; } if (lcore_count == 1) { /* * I/O and worker shares single lcore. */ rx_lcore_start = 0; tx_lcore_start = 0; wk_lcore_start = 0; rx_lcore_inc = 0; tx_lcore_inc = 0; wk_lcore_inc = 0; } else if (port_count * 4 <= lcore_count) { /* * each ports rx has own lcore. * each ports tx has own lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = rx_lcore_start + port_count; wk_lcore_start = tx_lcore_start + port_count; rx_lcore_inc = 1; tx_lcore_inc = 1; wk_lcore_inc = 1; } else if (port_count * 2 <= lcore_count) { /* * each ports (rx/tx) has own lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = 0; wk_lcore_start = rx_lcore_start + port_count; rx_lcore_inc = 1; tx_lcore_inc = 1; wk_lcore_inc = 1; } else if (port_count <= lcore_count) { /* * odd ports and even ports (rx/tx) shared lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = 0; wk_lcore_start = rx_lcore_start + (port_count + 1) / 2; rx_lcore_inc = 2; tx_lcore_inc = 2; wk_lcore_inc = 1; } else if (port_count <= lcore_count * 2) { /* * four ports (rx/tx) shared lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = 0; wk_lcore_start = rx_lcore_start + (port_count + 3) / 4; rx_lcore_inc = 4; tx_lcore_inc = 4; wk_lcore_inc = 1; } else if (lcore_count >= 4) { /* * rx for all ports has own lcore. * tx for all ports has own lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = 1; wk_lcore_start = 2; rx_lcore_inc = 0; tx_lcore_inc = 0; wk_lcore_inc = 1; } else { /* * I/O has own lcore. * all other lcores are assigned as worker. */ rx_lcore_start = 0; tx_lcore_start = 0; wk_lcore_start = 1; rx_lcore_inc = 0; tx_lcore_inc = 0; wk_lcore_inc = 1; } /* assign core automatically */ if (arg_rx == 0) { lcore = rx_lcore_start; count = rx_lcore_inc; for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { if ((portmask & (uint64_t)(1ULL << portid)) == 0) { continue; } if (assign_rx_lcore(portid, lcore) != 0) { return -5; } if (--count == 0) { lcore++; count = rx_lcore_inc; } } } if (arg_tx == 0) { lcore = tx_lcore_start; count = tx_lcore_inc; for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { if ((portmask & (uint64_t)(1ULL << portid)) == 0) { continue; } if (assign_tx_lcore(portid, lcore) != 0) { return -5; } if (--count == 0) { lcore++; count = tx_lcore_inc; } } } if (arg_w == 0) { if (wk_lcore_count == 0) { wk_lcore_count = lcore_count - wk_lcore_start; } for (lcore = wk_lcore_start; lcore < wk_lcore_start + wk_lcore_count; lcore++) { lp = &app.lcore_params[lcores[lcore]]; if (lp->type == e_APP_LCORE_IO) { /* core is shared by I/O and worker. */ lp->type = e_APP_LCORE_IO_WORKER; } else { lp->type = e_APP_LCORE_WORKER; } if (wk_lcore_inc != 1) { break; } } } /* Assign default values for the optional arguments not provided */ if (arg_rsz == 0) { app.nic_rx_ring_size = APP_DEFAULT_NIC_RX_RING_SIZE; app.nic_tx_ring_size = APP_DEFAULT_NIC_TX_RING_SIZE; app.ring_rx_size = APP_DEFAULT_RING_RX_SIZE; app.ring_tx_size = APP_DEFAULT_RING_TX_SIZE; } if (arg_bsz == 0) { app.burst_size_io_rx_read = APP_DEFAULT_BURST_SIZE_IO_RX_READ; app.burst_size_io_rx_write = APP_DEFAULT_BURST_SIZE_IO_RX_WRITE; app.burst_size_io_tx_read = APP_DEFAULT_BURST_SIZE_IO_TX_READ; app.burst_size_io_tx_write = APP_DEFAULT_BURST_SIZE_IO_TX_WRITE; app.burst_size_worker_read = APP_DEFAULT_BURST_SIZE_WORKER_READ; app.burst_size_worker_write = APP_DEFAULT_BURST_SIZE_WORKER_WRITE; } /* Check cross-consistency of arguments */ if (app_check_every_rx_port_is_tx_enabled() < 0) { lagopus_msg_error("At least one RX port is not enabled for TX.\n"); return -2; } if (show_core_assign == true) { printf("core assign:\n"); for (lcore = 0; lcore < RTE_MAX_LCORE; lcore++) { if (lcore_config[lcore].detected != true) { continue; } lp = &app.lcore_params[lcore]; printf(" lcore %d:\n", lcore); if (lp->type == e_APP_LCORE_IO) { printf(" type: I/O\n"); } else if (lp->type == e_APP_LCORE_WORKER) { printf(" type: WORKER\n"); } else if (lp->type == e_APP_LCORE_IO_WORKER) { printf(" type: I/O WORKER\n"); } else { printf(" type: not used\n"); } for (n = 0; n < lp->io.rx.n_nic_queues; n++) { printf(" RX port %d (queue %d)\n", lp->io.rx.nic_queues[n].port, lp->io.rx.nic_queues[n].queue); } for (n = 0; n < lp->io.tx.n_nic_ports; n++) { printf(" TX port %d\n", lp->io.tx.nic_ports[n]); } } exit(0); } if (optind >= 0) { argv[optind - 1] = prgname; } ret = optind - 1; optind = 0; /* reset getopt lib */ return ret; }