X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_options.c;h=d4ab5e2356584351422c51e67b5c8a67a28dcd04;hb=8d53e9f3c6001dcb2865f6e894da5b54e1418f88;hp=f6dfbc73ad0173bea8972208b2e9270d3738e1ed;hpb=e2bea7436061ca2e7e14bfcfdc5870f2555c3965;p=deb_dpdk.git diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c index f6dfbc73..d4ab5e23 100644 --- a/lib/librte_eal/common/eal_common_options.c +++ b/lib/librte_eal/common/eal_common_options.c @@ -216,6 +216,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg) internal_cfg->create_uio_dev = 0; internal_cfg->iova_mode = RTE_IOVA_DC; internal_cfg->user_mbuf_pool_ops_name = NULL; + CPU_ZERO(&internal_cfg->ctrl_cpuset); internal_cfg->init_complete = 0; } @@ -417,21 +418,44 @@ eal_service_cores_parsed(void) } static int -eal_parse_coremask(const char *coremask) +update_lcore_config(int *cores) { struct rte_config *cfg = rte_eal_get_configuration(); - int i, j, idx = 0; + unsigned int count = 0; + unsigned int i; + int ret = 0; + + for (i = 0; i < RTE_MAX_LCORE; i++) { + if (cores[i] != -1) { + if (!lcore_config[i].detected) { + RTE_LOG(ERR, EAL, "lcore %u unavailable\n", i); + ret = -1; + continue; + } + cfg->lcore_role[i] = ROLE_RTE; + count++; + } else { + cfg->lcore_role[i] = ROLE_OFF; + } + lcore_config[i].core_index = cores[i]; + } + if (!ret) + cfg->lcore_count = count; + return ret; +} + +static int +eal_parse_coremask(const char *coremask, int *cores) +{ unsigned count = 0; - char c; + int i, j, idx; int val; + char c; - if (eal_service_cores_parsed()) - RTE_LOG(WARNING, EAL, - "Service cores parsed before dataplane cores. " - "Please ensure -c is before -s or -S\n"); + for (idx = 0; idx < RTE_MAX_LCORE; idx++) + cores[idx] = -1; + idx = 0; - if (coremask == NULL) - return -1; /* Remove all blank characters ahead and after . * Remove 0x/0X if exists. */ @@ -456,32 +480,16 @@ eal_parse_coremask(const char *coremask) for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) { if ((1 << j) & val) { - if (!lcore_config[idx].detected) { - RTE_LOG(ERR, EAL, "lcore %u " - "unavailable\n", idx); - return -1; - } - - cfg->lcore_role[idx] = ROLE_RTE; - lcore_config[idx].core_index = count; + cores[idx] = count; count++; - } else { - cfg->lcore_role[idx] = ROLE_OFF; - lcore_config[idx].core_index = -1; } } } for (; i >= 0; i--) if (coremask[i] != '0') return -1; - for (; idx < RTE_MAX_LCORE; idx++) { - cfg->lcore_role[idx] = ROLE_OFF; - lcore_config[idx].core_index = -1; - } if (count == 0) return -1; - /* Update the count of enabled logical cores of the EAL configuration */ - cfg->lcore_count = count; return 0; } @@ -562,34 +570,19 @@ eal_parse_service_corelist(const char *corelist) } static int -eal_parse_corelist(const char *corelist) +eal_parse_corelist(const char *corelist, int *cores) { - struct rte_config *cfg = rte_eal_get_configuration(); - int i, idx = 0; unsigned count = 0; char *end = NULL; int min, max; + int idx; - if (eal_service_cores_parsed()) - RTE_LOG(WARNING, EAL, - "Service cores parsed before dataplane cores. " - "Please ensure -l is before -s or -S\n"); - - if (corelist == NULL) - return -1; + for (idx = 0; idx < RTE_MAX_LCORE; idx++) + cores[idx] = -1; - /* Remove all blank characters ahead and after */ + /* Remove all blank characters ahead */ while (isblank(*corelist)) corelist++; - i = strlen(corelist); - while ((i > 0) && isblank(corelist[i - 1])) - i--; - - /* Reset config */ - for (idx = 0; idx < RTE_MAX_LCORE; idx++) { - cfg->lcore_role[idx] = ROLE_OFF; - lcore_config[idx].core_index = -1; - } /* Get list of cores */ min = RTE_MAX_LCORE; @@ -600,10 +593,10 @@ eal_parse_corelist(const char *corelist) return -1; errno = 0; idx = strtol(corelist, &end, 10); - if (idx < 0 || idx >= (int)cfg->lcore_count) - return -1; if (errno || end == NULL) return -1; + if (idx < 0 || idx >= RTE_MAX_LCORE) + return -1; while (isblank(*end)) end++; if (*end == '-') { @@ -613,9 +606,8 @@ eal_parse_corelist(const char *corelist) if (min == RTE_MAX_LCORE) min = idx; for (idx = min; idx <= max; idx++) { - if (cfg->lcore_role[idx] != ROLE_RTE) { - cfg->lcore_role[idx] = ROLE_RTE; - lcore_config[idx].core_index = count; + if (cores[idx] == -1) { + cores[idx] = count; count++; } } @@ -627,10 +619,6 @@ eal_parse_corelist(const char *corelist) if (count == 0) return -1; - - /* Update the count of enabled logical cores of the EAL configuration */ - cfg->lcore_count = count; - return 0; } @@ -1106,13 +1094,81 @@ eal_parse_iova_mode(const char *name) return 0; } +/* caller is responsible for freeing the returned string */ +static char * +available_cores(void) +{ + char *str = NULL; + int previous; + int sequence; + char *tmp; + int idx; + + /* find the first available cpu */ + for (idx = 0; idx < RTE_MAX_LCORE; idx++) { + if (!lcore_config[idx].detected) + continue; + break; + } + if (idx >= RTE_MAX_LCORE) + return NULL; + + /* first sequence */ + if (asprintf(&str, "%d", idx) < 0) + return NULL; + previous = idx; + sequence = 0; + + for (idx++ ; idx < RTE_MAX_LCORE; idx++) { + if (!lcore_config[idx].detected) + continue; + + if (idx == previous + 1) { + previous = idx; + sequence = 1; + continue; + } + + /* finish current sequence */ + if (sequence) { + if (asprintf(&tmp, "%s-%d", str, previous) < 0) { + free(str); + return NULL; + } + free(str); + str = tmp; + } + + /* new sequence */ + if (asprintf(&tmp, "%s,%d", str, idx) < 0) { + free(str); + return NULL; + } + free(str); + str = tmp; + previous = idx; + sequence = 0; + } + + /* finish last sequence */ + if (sequence) { + if (asprintf(&tmp, "%s-%d", str, previous) < 0) { + free(str); + return NULL; + } + free(str); + str = tmp; + } + + return str; +} + int eal_parse_common_option(int opt, const char *optarg, struct internal_config *conf) { static int b_used; static int w_used; - struct rte_config *cfg = rte_eal_get_configuration(); switch (opt) { /* blacklist */ @@ -1136,9 +1192,23 @@ eal_parse_common_option(int opt, const char *optarg, w_used = 1; break; /* coremask */ - case 'c': - if (eal_parse_coremask(optarg) < 0) { - RTE_LOG(ERR, EAL, "invalid coremask\n"); + case 'c': { + int lcore_indexes[RTE_MAX_LCORE]; + + if (eal_service_cores_parsed()) + RTE_LOG(WARNING, EAL, + "Service cores parsed before dataplane cores. Please ensure -c is before -s or -S\n"); + if (eal_parse_coremask(optarg, lcore_indexes) < 0) { + RTE_LOG(ERR, EAL, "invalid coremask syntax\n"); + return -1; + } + if (update_lcore_config(lcore_indexes) < 0) { + char *available = available_cores(); + + RTE_LOG(ERR, EAL, + "invalid coremask, please check specified cores are part of %s\n", + available); + free(available); return -1; } @@ -1152,12 +1222,26 @@ eal_parse_common_option(int opt, const char *optarg, core_parsed = LCORE_OPT_MSK; break; + } /* corelist */ - case 'l': - if (eal_parse_corelist(optarg) < 0) { + case 'l': { + int lcore_indexes[RTE_MAX_LCORE]; + + if (eal_service_cores_parsed()) + RTE_LOG(WARNING, EAL, + "Service cores parsed before dataplane cores. Please ensure -l is before -s or -S\n"); + + if (eal_parse_corelist(optarg, lcore_indexes) < 0) { + RTE_LOG(ERR, EAL, "invalid core list syntax\n"); + return -1; + } + if (update_lcore_config(lcore_indexes) < 0) { + char *available = available_cores(); + RTE_LOG(ERR, EAL, - "invalid core list, please check core numbers are in [0, %u] range\n", - cfg->lcore_count-1); + "invalid core list, please check specified cores are part of %s\n", + available); + free(available); return -1; } @@ -1171,6 +1255,7 @@ eal_parse_common_option(int opt, const char *optarg, core_parsed = LCORE_OPT_LST; break; + } /* service coremask */ case 's': if (eal_parse_service_coremask(optarg) < 0) { @@ -1342,10 +1427,9 @@ eal_auto_detect_cores(struct rte_config *cfg) unsigned int lcore_id; unsigned int removed = 0; rte_cpuset_t affinity_set; - pthread_t tid = pthread_self(); - if (pthread_getaffinity_np(tid, sizeof(rte_cpuset_t), - &affinity_set) < 0) + if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t), + &affinity_set)) CPU_ZERO(&affinity_set); for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { @@ -1359,6 +1443,31 @@ eal_auto_detect_cores(struct rte_config *cfg) cfg->lcore_count -= removed; } +static void +compute_ctrl_threads_cpuset(struct internal_config *internal_cfg) +{ + rte_cpuset_t *cpuset = &internal_cfg->ctrl_cpuset; + rte_cpuset_t default_set; + unsigned int lcore_id; + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (eal_cpu_detected(lcore_id) && + rte_lcore_has_role(lcore_id, ROLE_OFF)) { + CPU_SET(lcore_id, cpuset); + } + } + + if (pthread_getaffinity_np(pthread_self(), sizeof(rte_cpuset_t), + &default_set)) + CPU_ZERO(&default_set); + + RTE_CPU_AND(cpuset, cpuset, &default_set); + + /* if no detected CPU is off, use master core */ + if (!CPU_COUNT(cpuset)) + CPU_SET(rte_get_master_lcore(), cpuset); +} + int eal_cleanup_config(struct internal_config *internal_cfg) { @@ -1392,6 +1501,8 @@ eal_adjust_config(struct internal_config *internal_cfg) lcore_config[cfg->master_lcore].core_role = ROLE_RTE; } + compute_ctrl_threads_cpuset(internal_cfg); + /* 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++)