int eal_adjust_config(struct internal_config *internal_cfg) { int i; struct rte_config *cfg = rte_eal_get_configuration(); if (internal_config.process_type == RTE_PROC_AUTO) internal_config.process_type = eal_proc_type_detect(); /* default master lcore is the first one */ if (!master_lcore_parsed) cfg->master_lcore = rte_get_next_lcore(-1, 0, 0); /* if no memory amounts were requested, this will result in 0 and * will be overridden later, right after eal_hugepage_info_init() */ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) internal_cfg->memory += internal_cfg->socket_mem[i]; return 0; }
/* Sets up rte_config structure with the pointer to shared memory config.*/ static void rte_config_init(void) { rte_config.process_type = (internal_config.process_type == RTE_PROC_AUTO) ? eal_proc_type_detect() : /* for auto, detect the type */ internal_config.process_type; /* otherwise use what's already set */ switch (rte_config.process_type){ case RTE_PROC_PRIMARY: rte_eal_config_create(); break; case RTE_PROC_SECONDARY: rte_eal_config_attach(); rte_eal_mcfg_wait_complete(rte_config.mem_config); rte_eal_config_reattach(); break; case RTE_PROC_AUTO: case RTE_PROC_INVALID: rte_panic("Invalid process type\n"); } }
/* Parse the argument given in the command line of the application */ static int eal_parse_args(int argc, char **argv) { int opt, ret, i; char **argvopt; int option_index; int coremask_ok = 0; char *prgname = argv[0]; static struct option lgopts[] = { {OPT_NO_HUGE, 0, 0, 0}, {OPT_NO_PCI, 0, 0, 0}, {OPT_NO_HPET, 0, 0, 0}, {OPT_VMWARE_TSC_MAP, 0, 0, 0}, {OPT_HUGE_DIR, 1, 0, 0}, {OPT_NO_SHCONF, 0, 0, 0}, {OPT_PROC_TYPE, 1, 0, 0}, {OPT_FILE_PREFIX, 1, 0, 0}, {OPT_SOCKET_MEM, 1, 0, 0}, {OPT_PCI_WHITELIST, 1, 0, 0}, {OPT_PCI_BLACKLIST, 1, 0, 0}, {OPT_VDEV, 1, 0, 0}, {OPT_SYSLOG, 1, NULL, 0}, {OPT_VFIO_INTR, 1, NULL, 0}, {OPT_BASE_VIRTADDR, 1, 0, 0}, {OPT_XEN_DOM0, 0, 0, 0}, {OPT_CREATE_UIO_DEV, 1, NULL, 0}, {0, 0, 0, 0} }; struct shared_driver *solib; argvopt = argv; internal_config.memory = 0; internal_config.force_nrank = 0; internal_config.force_nchannel = 0; internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT; internal_config.hugepage_dir = NULL; internal_config.force_sockets = 0; internal_config.syslog_facility = LOG_DAEMON; internal_config.xen_dom0_support = 0; /* if set to NONE, interrupt mode is determined automatically */ internal_config.vfio_intr_mode = RTE_INTR_MODE_NONE; #ifdef RTE_LIBEAL_USE_HPET internal_config.no_hpet = 0; #else internal_config.no_hpet = 1; #endif /* zero out the NUMA config */ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) internal_config.socket_mem[i] = 0; /* zero out hugedir descriptors */ for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) internal_config.hugepage_info[i].lock_descriptor = -1; internal_config.vmware_tsc_map = 0; internal_config.base_virtaddr = 0; while ((opt = getopt_long(argc, argvopt, "b:w:c:d:m:n:r:v", lgopts, &option_index)) != EOF) { switch (opt) { /* blacklist */ case 'b': if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, optarg) < 0) { eal_usage(prgname); return (-1); } break; /* whitelist */ case 'w': if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg) < 0) { eal_usage(prgname); return -1; } break; /* coremask */ case 'c': if (eal_parse_coremask(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid coremask\n"); eal_usage(prgname); return -1; } coremask_ok = 1; break; /* force loading of external driver */ case 'd': solib = malloc(sizeof(*solib)); if (solib == NULL) { RTE_LOG(ERR, EAL, "malloc(solib) failed\n"); return -1; } memset(solib, 0, sizeof(*solib)); strncpy(solib->name, optarg, PATH_MAX-1); solib->name[PATH_MAX-1] = 0; TAILQ_INSERT_TAIL(&solib_list, solib, next); break; /* size of memory */ case 'm': internal_config.memory = atoi(optarg); internal_config.memory *= 1024ULL; internal_config.memory *= 1024ULL; break; /* force number of channels */ case 'n': internal_config.force_nchannel = atoi(optarg); if (internal_config.force_nchannel == 0 || internal_config.force_nchannel > 4) { RTE_LOG(ERR, EAL, "invalid channel number\n"); eal_usage(prgname); return -1; } break; /* force number of ranks */ case 'r': internal_config.force_nrank = atoi(optarg); if (internal_config.force_nrank == 0 || internal_config.force_nrank > 16) { RTE_LOG(ERR, EAL, "invalid rank number\n"); eal_usage(prgname); return -1; } break; case 'v': /* since message is explicitly requested by user, we * write message at highest log level so it can always be seen * even if info or warning messages are disabled */ RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version()); break; /* long options */ case 0: if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) { internal_config.no_hugetlbfs = 1; } if (!strcmp(lgopts[option_index].name, OPT_XEN_DOM0)) { #ifdef RTE_LIBRTE_XEN_DOM0 internal_config.xen_dom0_support = 1; #else RTE_LOG(ERR, EAL, "Can't support DPDK app " "running on Dom0, please configure" " RTE_LIBRTE_XEN_DOM0=y\n"); return -1; #endif } else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) { internal_config.no_pci = 1; } else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) { internal_config.no_hpet = 1; } else if (!strcmp(lgopts[option_index].name, OPT_VMWARE_TSC_MAP)) { internal_config.vmware_tsc_map = 1; } else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) { internal_config.no_shconf = 1; } else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) { internal_config.hugepage_dir = optarg; } else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) { internal_config.process_type = eal_parse_proc_type(optarg); } else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) { internal_config.hugefile_prefix = optarg; } else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) { if (eal_parse_socket_mem(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" OPT_SOCKET_MEM "\n"); eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) { printf("The --use-device option is deprecated, please use\n" "--whitelist or --vdev instead.\n"); eal_usage(prgname); return -1; } else if (!strcmp(lgopts[option_index].name, OPT_PCI_BLACKLIST)) { if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, optarg) < 0) { eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_PCI_WHITELIST)) { if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg) < 0) { eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_VDEV)) { if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, optarg) < 0) { eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) { if (eal_parse_syslog(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" OPT_SYSLOG "\n"); eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_BASE_VIRTADDR)) { if (eal_parse_base_virtaddr(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameter for --" OPT_BASE_VIRTADDR "\n"); eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_VFIO_INTR)) { if (eal_parse_vfio_intr(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" OPT_VFIO_INTR "\n"); eal_usage(prgname); return -1; } } else if (!strcmp(lgopts[option_index].name, OPT_CREATE_UIO_DEV)) { internal_config.create_uio_dev = 1; } break; default: eal_usage(prgname); return -1; } } /* sanity checks */ if (!coremask_ok) { RTE_LOG(ERR, EAL, "coremask not specified\n"); eal_usage(prgname); return -1; } if (internal_config.process_type == RTE_PROC_AUTO){ internal_config.process_type = eal_proc_type_detect(); } if (internal_config.process_type == RTE_PROC_INVALID){ RTE_LOG(ERR, EAL, "Invalid process type specified\n"); eal_usage(prgname); return -1; } if (internal_config.process_type == RTE_PROC_PRIMARY && internal_config.force_nchannel == 0) { RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n"); eal_usage(prgname); return -1; } if (index(internal_config.hugefile_prefix,'%') != NULL){ RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n"); eal_usage(prgname); return -1; } if (internal_config.memory > 0 && internal_config.force_sockets == 1) { RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified " "at the same time\n"); eal_usage(prgname); return -1; } /* --no-huge doesn't make sense with either -m or --socket-mem */ if (internal_config.no_hugetlbfs && (internal_config.memory > 0 || internal_config.force_sockets == 1)) { RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified " "together with --no-huge!\n"); eal_usage(prgname); return -1; } /* --xen-dom0 doesn't make sense with --socket-mem */ if (internal_config.xen_dom0_support && internal_config.force_sockets == 1) { RTE_LOG(ERR, EAL, "Options --socket-mem cannot be specified " "together with --xen_dom0!\n"); eal_usage(prgname); return -1; } if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 && rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) { RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist " "[-w] options cannot be used at the same time\n"); eal_usage(prgname); return -1; } if (optind >= 0) argv[optind-1] = prgname; /* if no memory amounts were requested, this will result in 0 and * will be overriden later, right after eal_hugepage_info_init() */ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) internal_config.memory += internal_config.socket_mem[i]; ret = optind-1; optind = 0; /* reset getopt lib */ return ret; }
/*----------------------------------------------------------------------------*/ int SetNetEnv(char *dev_name_list, char *port_stat_list) { int eidx = 0; int i, j; int set_all_inf = (strncmp(dev_name_list, ALL_STRING, sizeof(ALL_STRING))==0); TRACE_CONFIG("Loading interface setting\n"); CONFIG.eths = (struct eth_table *) calloc(MAX_DEVICES, sizeof(struct eth_table)); if (!CONFIG.eths) { TRACE_ERROR("Can't allocate space for CONFIG.eths\n"); exit(EXIT_FAILURE); } if (current_iomodule_func == &ps_module_func) { #ifndef DISABLE_PSIO struct ifreq ifr; /* calculate num_devices now! */ num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(EXIT_FAILURE); } /* Create socket */ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { TRACE_ERROR("socket"); exit(EXIT_FAILURE); } /* To Do: Parse dev_name_list rather than use strstr */ for (i = 0; i < num_devices; i++) { strcpy(ifr.ifr_name, devices[i].name); /* getting interface information */ if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (!set_all_inf && strstr(dev_name_list, ifr.ifr_name) == NULL) continue; /* Setting informations */ eidx = CONFIG.eths_num++; strcpy(CONFIG.eths[eidx].dev_name, ifr.ifr_name); CONFIG.eths[eidx].ifindex = devices[i].ifindex; /* getting address */ if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin; } if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) { for (j = 0; j < ETH_ALEN; j ++) { CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j]; } } /* Net MASK */ if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].netmask = *(uint32_t *)&sin; } /* add to attached devices */ for (j = 0; j < num_devices_attached; j++) { if (devices_attached[j] == devices[i].ifindex) { break; } } devices_attached[num_devices_attached] = devices[i].ifindex; num_devices_attached++; } else { perror("SIOCGIFFLAGS"); } } num_queues = GetNumQueues(); if (num_queues <= 0) { TRACE_CONFIG("Failed to find NIC queues!\n"); close(sock); return -1; } if (num_queues > num_cpus) { TRACE_CONFIG("Too many NIC queues available.\n"); close(sock); return -1; } close(sock); #endif /* !PSIO_MODULE */ } else if (current_iomodule_func == &dpdk_module_func) { #ifndef DISABLE_DPDK int cpu = CONFIG.num_cores; mpz_t _cpumask; char cpumaskbuf[32] = ""; char mem_channels[8] = ""; char socket_mem_str[32] = ""; // int i; int ret, socket_mem; static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; /* STEP 1: first determine CPU mask */ mpz_init(_cpumask); if (!mpz_cmp(_cpumask, CONFIG._cpumask)) { /* get the cpu mask */ for (ret = 0; ret < cpu; ret++) mpz_setbit(_cpumask, ret); gmp_sprintf(cpumaskbuf, "%ZX", _cpumask); } else gmp_sprintf(cpumaskbuf, "%ZX", CONFIG._cpumask); mpz_clear(_cpumask); /* STEP 2: determine memory channels per socket */ /* get the mem channels per socket */ if (CONFIG.num_mem_ch == 0) { TRACE_ERROR("DPDK module requires # of memory channels " "per socket parameter!\n"); exit(EXIT_FAILURE); } sprintf(mem_channels, "%d", CONFIG.num_mem_ch); /* STEP 3: determine socket memory */ /* get socket memory threshold (in MB) */ socket_mem = RTE_ALIGN_CEIL((unsigned long)ceil((CONFIG.num_cores * (CONFIG.rcvbuf_size + CONFIG.sndbuf_size + sizeof(struct tcp_stream) + sizeof(struct tcp_recv_vars) + sizeof(struct tcp_send_vars) + sizeof(struct fragment_ctx)) * CONFIG.max_concurrency)/RTE_SOCKET_MEM_SHIFT), RTE_CACHE_LINE_SIZE); /* initialize the rte env, what a waste of implementation effort! */ int argc = 6;//8; char *argv[RTE_ARGC_MAX] = {"", "-c", cpumaskbuf, "-n", mem_channels, #if 0 "--socket-mem", socket_mem_str, #endif "--proc-type=auto" }; ret = probe_all_rte_devices(argv, &argc, dev_name_list); /* STEP 4: build up socket mem parameter */ sprintf(socket_mem_str, "%d", socket_mem); #if 0 char *smsptr = socket_mem_str + strlen(socket_mem_str); for (i = 1; i < ret + 1; i++) { sprintf(smsptr, ",%d", socket_mem); smsptr += strlen(smsptr); } TRACE_DBG("socket_mem: %s\n", socket_mem_str); #endif /* * re-set getopt extern variable optind. * this issue was a bitch to debug * rte_eal_init() internally uses getopt() syscall * mtcp applications that also use an `external' getopt * will cause a violent crash if optind is not reset to zero * prior to calling the func below... * see man getopt(3) for more details */ optind = 0; #ifdef DEBUG /* print argv's */ for (i = 0; i < argc; i++) TRACE_INFO("argv[%d]: %s\n", i, argv[i]); #endif /* initialize the dpdk eal env */ ret = rte_eal_init(argc, argv); if (ret < 0) { TRACE_ERROR("Invalid EAL args!\n"); exit(EXIT_FAILURE); } /* give me the count of 'detected' ethernet ports */ #if RTE_VERSION < RTE_VERSION_NUM(18, 5, 0, 0) num_devices = rte_eth_dev_count(); #else num_devices = rte_eth_dev_count_avail(); #endif if (num_devices == 0) { TRACE_ERROR("No Ethernet port!\n"); exit(EXIT_FAILURE); } /* get mac addr entries of 'detected' dpdk ports */ for (ret = 0; ret < num_devices; ret++) rte_eth_macaddr_get(ret, &ports_eth_addr[ret]); num_queues = MIN(CONFIG.num_cores, MAX_CPUS); struct ifaddrs *ifap; struct ifaddrs *iter_if; char *seek; if (getifaddrs(&ifap) != 0) { perror("getifaddrs: "); exit(EXIT_FAILURE); } iter_if = ifap; do { if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET && !set_all_inf && (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL && /* check if the interface was not aliased */ *(seek + strlen(iter_if->ifa_name)) != ':') { struct ifreq ifr; /* Setting informations */ eidx = CONFIG.eths_num++; strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name); strcpy(ifr.ifr_name, iter_if->ifa_name); /* Create socket */ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { perror("socket"); exit(EXIT_FAILURE); } /* getting address */ if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin; } if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) { for (j = 0; j < ETH_ALEN; j ++) { CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j]; } } /* Net MASK */ if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].netmask = *(uint32_t *)&sin; } close(sock); for (j = 0; j < num_devices; j++) { if (!memcmp(&CONFIG.eths[eidx].haddr[0], &ports_eth_addr[j], ETH_ALEN)) CONFIG.eths[eidx].ifindex = j; } /* add to attached devices */ for (j = 0; j < num_devices_attached; j++) { if (devices_attached[j] == CONFIG.eths[eidx].ifindex) { break; } } devices_attached[num_devices_attached] = CONFIG.eths[eidx].ifindex; num_devices_attached++; fprintf(stderr, "Total number of attached devices: %d\n", num_devices_attached); fprintf(stderr, "Interface name: %s\n", iter_if->ifa_name); } iter_if = iter_if->ifa_next; } while (iter_if != NULL); freeifaddrs(ifap); #if 0 /* * XXX: It seems that there is a bug in the RTE SDK. * The dynamically allocated rte_argv params are left * as dangling pointers. Freeing them causes program * to crash. */ /* free up all resources */ for (; rte_argc >= 9; rte_argc--) { if (rte_argv[rte_argc] != NULL) { fprintf(stderr, "Cleaning up rte_argv[%d]: %s (%p)\n", rte_argc, rte_argv[rte_argc], rte_argv[rte_argc]); free(rte_argv[rte_argc]); rte_argv[rte_argc] = NULL; } } #endif /* check if process is primary or secondary */ CONFIG.multi_process_is_master = (eal_proc_type_detect() == RTE_PROC_PRIMARY) ? 1 : 0; #endif /* !DISABLE_DPDK */ } else if (current_iomodule_func == &netmap_module_func) { #ifndef DISABLE_NETMAP struct ifaddrs *ifap; struct ifaddrs *iter_if; char *seek; num_queues = MIN(CONFIG.num_cores, MAX_CPUS); if (getifaddrs(&ifap) != 0) { perror("getifaddrs: "); exit(EXIT_FAILURE); } iter_if = ifap; do { if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET && !set_all_inf && (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL && /* check if the interface was not aliased */ *(seek + strlen(iter_if->ifa_name)) != ':') { struct ifreq ifr; /* Setting informations */ eidx = CONFIG.eths_num++; strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name); strcpy(ifr.ifr_name, iter_if->ifa_name); /* Create socket */ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { perror("socket"); exit(EXIT_FAILURE); } /* getting address */ if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin; } if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) { for (j = 0; j < ETH_ALEN; j ++) { CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j]; } } /* Net MASK */ if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].netmask = *(uint32_t *)&sin; } close(sock); #if 0 for (j = 0; j < num_devices; j++) { if (!memcmp(&CONFIG.eths[eidx].haddr[0], &ports_eth_addr[j], ETH_ALEN)) CONFIG.eths[eidx].ifindex = ifr.ifr_ifindex; #endif CONFIG.eths[eidx].ifindex = eidx; TRACE_INFO("Ifindex of interface %s is: %d\n", ifr.ifr_name, CONFIG.eths[eidx].ifindex); #if 0 } #endif /* add to attached devices */ for (j = 0; j < num_devices_attached; j++) { if (devices_attached[j] == CONFIG.eths[eidx].ifindex) { break; } } devices_attached[num_devices_attached] = if_nametoindex(ifr.ifr_name); num_devices_attached++; fprintf(stderr, "Total number of attached devices: %d\n", num_devices_attached); fprintf(stderr, "Interface name: %s\n", iter_if->ifa_name); } iter_if = iter_if->ifa_next; } while (iter_if != NULL); freeifaddrs(ifap); #endif /* !DISABLE_NETMAP */ } else if (current_iomodule_func == &onvm_module_func) { #ifdef ENABLE_ONVM int cpu = CONFIG.num_cores; mpz_t cpumask; char cpumaskbuf[32]; char mem_channels[8]; char service[6]; char instance[6]; int ret; mpz_init(cpumask); /* get the cpu mask */ for (ret = 0; ret < cpu; ret++) mpz_setbit(cpumask, ret); gmp_sprintf(cpumaskbuf, "%ZX", cpumask); mpz_clear(cpumask); /* get the mem channels per socket */ if (CONFIG.num_mem_ch == 0) { TRACE_ERROR("DPDK module requires # of memory channels " "per socket parameter!\n"); exit(EXIT_FAILURE); } sprintf(mem_channels, "%d", CONFIG.num_mem_ch); sprintf(service, "%d", CONFIG.onvm_serv); sprintf(instance, "%d", CONFIG.onvm_inst); /* initialize the rte env first, what a waste of implementation effort! */ char *argv[] = {"", "-c", cpumaskbuf, "-n", mem_channels, "--proc-type=secondary", "--", "-r", service, instance, "" }; const int argc = 10; /* * re-set getopt extern variable optind. * this issue was a bitch to debug * rte_eal_init() internally uses getopt() syscall * mtcp applications that also use an `external' getopt * will cause a violent crash if optind is not reset to zero * prior to calling the func below... * see man getopt(3) for more details */ optind = 0; /* initialize the dpdk eal env */ ret = onvm_nflib_init(argc, argv, "mtcp_nf", &CONFIG.nf_info); if (ret < 0) { TRACE_ERROR("Invalid EAL args!\n"); exit(EXIT_FAILURE); } /* give me the count of 'detected' ethernet ports */ num_devices = ports->num_ports; if (num_devices == 0) { TRACE_ERROR("No Ethernet port!\n"); exit(EXIT_FAILURE); } num_queues = MIN(CONFIG.num_cores, MAX_CPUS); struct ifaddrs *ifap; struct ifaddrs *iter_if; char *seek; if (getifaddrs(&ifap) != 0) { perror("getifaddrs: "); exit(EXIT_FAILURE); } iter_if = ifap; do { if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET && !set_all_inf && (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL && /* check if the interface was not aliased */ *(seek + strlen(iter_if->ifa_name)) != ':') { struct ifreq ifr; /* Setting informations */ eidx = CONFIG.eths_num++; strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name); strcpy(ifr.ifr_name, iter_if->ifa_name); /* Create socket */ int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { perror("socket"); } /* getting address */ if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin; } for (j = 0; j < ETH_ALEN; j ++) { CONFIG.eths[eidx].haddr[j] = ports->mac[eidx].addr_bytes[j]; }; /* Net MASK */ if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) { struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; CONFIG.eths[eidx].netmask = *(uint32_t *)&sin; } close(sock); CONFIG.eths[eidx].ifindex = ports->id[eidx]; devices_attached[num_devices_attached] = CONFIG.eths[eidx].ifindex; num_devices_attached++; fprintf(stderr, "Total number of attached devices: %d\n", num_devices_attached); fprintf(stderr, "Interface name: %s\n", iter_if->ifa_name); } iter_if = iter_if->ifa_next; } while (iter_if != NULL); freeifaddrs(ifap); #endif /* ENABLE_ONVM */ } CONFIG.nif_to_eidx = (int*)calloc(MAX_DEVICES, sizeof(int)); if (!CONFIG.nif_to_eidx) { exit(EXIT_FAILURE); } for (i = 0; i < MAX_DEVICES; ++i) { CONFIG.nif_to_eidx[i] = -1; } for (i = 0; i < CONFIG.eths_num; ++i) { j = CONFIG.eths[i].ifindex; if (j >= MAX_DEVICES) { TRACE_ERROR("ifindex of eths_%d exceed the limit: %d\n", i, j); exit(EXIT_FAILURE); } /* the physic port index of the i-th port listed in the config file is j*/ CONFIG.nif_to_eidx[j] = i; /* finally set the port stats option `on' */ if (strcmp(CONFIG.eths[i].dev_name, port_stat_list) == 0) CONFIG.eths[i].stat_print = TRUE; } return 0; }
/* Parse the argument given in the command line of the application */ static int eal_parse_args(int argc, char **argv) { int opt, ret, i; char **argvopt; int option_index; int coremask_ok = 0; ssize_t blacklist_index = 0;; char *prgname = argv[0]; static struct option lgopts[] = { {OPT_NO_HUGE, 0, 0, 0}, {OPT_NO_PCI, 0, 0, 0}, {OPT_NO_HPET, 0, 0, 0}, {OPT_HUGE_DIR, 1, 0, 0}, {OPT_NO_SHCONF, 0, 0, 0}, {OPT_PROC_TYPE, 1, 0, 0}, {OPT_FILE_PREFIX, 1, 0, 0}, {OPT_SOCKET_MEM, 1, 0, 0}, {0, 0, 0, 0} }; argvopt = argv; internal_config.memory = 0; internal_config.force_nrank = 0; internal_config.force_nchannel = 0; internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT; internal_config.hugepage_dir = NULL; internal_config.force_sockets = 0; #ifdef RTE_LIBEAL_USE_HPET internal_config.no_hpet = 0; #else internal_config.no_hpet = 1; #endif /* zero out the NUMA config */ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) internal_config.socket_mem[i] = 0; /* zero out hugedir descriptors */ for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) internal_config.hugepage_info[i].lock_descriptor = 0; while ((opt = getopt_long(argc, argvopt, "b:c:m:n:r:v", lgopts, &option_index)) != EOF) { switch (opt) { /* blacklist */ case 'b': if ((blacklist_index = eal_parse_blacklist_opt(optarg, blacklist_index)) < 0) { eal_usage(prgname); return (-1); } break; /* coremask */ case 'c': if (eal_parse_coremask(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid coremask\n"); eal_usage(prgname); return -1; } coremask_ok = 1; break; /* size of memory */ case 'm': internal_config.memory = atoi(optarg); internal_config.memory *= 1024ULL; internal_config.memory *= 1024ULL; break; /* force number of channels */ case 'n': internal_config.force_nchannel = atoi(optarg); if (internal_config.force_nchannel == 0 || internal_config.force_nchannel > 4) { RTE_LOG(ERR, EAL, "invalid channel number\n"); eal_usage(prgname); return -1; } break; /* force number of ranks */ case 'r': internal_config.force_nrank = atoi(optarg); if (internal_config.force_nrank == 0 || internal_config.force_nrank > 16) { RTE_LOG(ERR, EAL, "invalid rank number\n"); eal_usage(prgname); return -1; } break; case 'v': /* since message is explicitly requested by user, we * write message at highest log level so it can always be seen * even if info or warning messages are disabled */ RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version()); break; /* long options */ case 0: if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) { internal_config.no_hugetlbfs = 1; } else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) { internal_config.no_pci = 1; } else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) { internal_config.no_hpet = 1; } else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) { internal_config.no_shconf = 1; } else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) { internal_config.hugepage_dir = optarg; } else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) { internal_config.process_type = eal_parse_proc_type(optarg); } else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) { internal_config.hugefile_prefix = optarg; } else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) { if (eal_parse_socket_mem(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" OPT_SOCKET_MEM "\n"); eal_usage(prgname); return -1; } } break; default: eal_usage(prgname); return -1; } } /* sanity checks */ if (!coremask_ok) { RTE_LOG(ERR, EAL, "coremask not specified\n"); eal_usage(prgname); return -1; } if (internal_config.process_type == RTE_PROC_AUTO){ internal_config.process_type = eal_proc_type_detect(); } if (internal_config.process_type == RTE_PROC_INVALID){ RTE_LOG(ERR, EAL, "Invalid process type specified\n"); eal_usage(prgname); return -1; } if (internal_config.process_type == RTE_PROC_PRIMARY && internal_config.force_nchannel == 0) { RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n"); eal_usage(prgname); return -1; } if (index(internal_config.hugefile_prefix,'%') != NULL){ RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n"); eal_usage(prgname); return -1; } if (internal_config.memory > 0 && internal_config.force_sockets == 1) { RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified " "at the same time\n"); eal_usage(prgname); return -1; } /* --no-huge doesn't make sense with either -m or --socket-mem */ if (internal_config.no_hugetlbfs && (internal_config.memory > 0 || internal_config.force_sockets == 1)) { RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified " "together with --no-huge!\n"); eal_usage(prgname); return -1; } if (blacklist_index > 0) rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index); if (optind >= 0) argv[optind-1] = prgname; /* if no memory amounts were requested, this will result in 0 and * will be overriden later, right after eal_hugepage_info_init() */ for (i = 0; i < RTE_MAX_NUMA_NODES; i++) internal_config.memory += internal_config.socket_mem[i]; ret = optind-1; optind = 0; /* reset getopt lib */ return ret; }