Currently, VA space allocation is regulated by two constants picked up from config - max memseg per list, and max memory per list. In preparation for these limits being dynamic, add a per-page-size limit value in config, populate that value from these defaults at init time, and adjust the code to only refer to the mem limits from internal config.
Signed-off-by: Anatoly Burakov <[email protected]> --- lib/eal/common/eal_common_dynmem.c | 22 ++++++++-------------- lib/eal/common/eal_common_options.c | 20 ++++++++++++++++++++ lib/eal/common/eal_internal_cfg.h | 2 ++ lib/eal/common/eal_options.h | 1 + lib/eal/freebsd/eal.c | 6 ++++++ lib/eal/linux/eal.c | 6 ++++++ lib/eal/linux/eal_memory.c | 3 +++ lib/eal/windows/eal.c | 6 ++++++ 8 files changed, 52 insertions(+), 14 deletions(-) diff --git a/lib/eal/common/eal_common_dynmem.c b/lib/eal/common/eal_common_dynmem.c index c163bf4967..c33fbdea6d 100644 --- a/lib/eal/common/eal_common_dynmem.c +++ b/lib/eal/common/eal_common_dynmem.c @@ -24,13 +24,13 @@ eal_dynmem_memseg_lists_init(void) struct memtype { uint64_t page_sz; int socket_id; + unsigned int hpi_idx; unsigned int n_segs; size_t mem_sz; size_t va_offset; } memtypes[RTE_MAX_MEMSEG_LISTS] = {0}; int i, hpi_idx, msl_idx, ret = -1; /* fail unless told to succeed */ struct rte_memseg_list *msl; - uint64_t max_mem_per_type; size_t mem_va_len, mem_va_page_sz; unsigned int n_memtypes, cur_type; void *mem_va_addr = NULL; @@ -51,15 +51,9 @@ eal_dynmem_memseg_lists_init(void) * balancing act between maximum segments per type, maximum memory per * type, and number of detected NUMA nodes. * - * the total amount of memory per type is limited by - * RTE_MAX_MEM_MB_PER_TYPE. additionally, maximum number of segments per - * type is also limited by RTE_MAX_MEMSEG_PER_TYPE. this is because for - * smaller page sizes, it can take hundreds of thousands of segments to - * reach the above specified per-type memory limits. - * - * each memory type is allotted a single memseg list. the size of that - * list is calculated here to respect the per-type memory and segment - * limits that apply. + * the total amount of memory per type is limited by per-page-size + * memory values in internal config. each memory type is allotted one + * memseg list. */ /* maximum number of memtypes we're ever going to get */ @@ -92,6 +86,7 @@ eal_dynmem_memseg_lists_init(void) #endif memtypes[cur_type].page_sz = hugepage_sz; memtypes[cur_type].socket_id = socket_id; + memtypes[cur_type].hpi_idx = hpi_idx; EAL_LOG(DEBUG, "Detected memory type: " "socket_id:%u hugepage_sz:%" PRIu64, @@ -101,8 +96,6 @@ eal_dynmem_memseg_lists_init(void) /* number of memtypes could have been lower due to no NUMA support */ n_memtypes = cur_type; - /* set up limits for types */ - max_mem_per_type = (uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20; mem_va_len = 0; mem_va_page_sz = 0; @@ -110,9 +103,12 @@ eal_dynmem_memseg_lists_init(void) for (cur_type = 0; cur_type < n_memtypes; cur_type++) { unsigned int n_segs; struct memtype *type = &memtypes[cur_type]; + uint64_t max_mem_per_type; uint64_t pagesz; pagesz = type->page_sz; + max_mem_per_type = + internal_conf->hugepage_mem_sz_limits[type->hpi_idx]; /* * we need to create a segment list for this type. we must take @@ -121,10 +117,8 @@ eal_dynmem_memseg_lists_init(void) * 1. total amount of memory to use for this memory type * 2. total amount of memory allowed per type * 3. number of segments needed to fit the amount of memory - * 4. number of segments allowed per type */ n_segs = max_mem_per_type / pagesz; - n_segs = RTE_MIN(n_segs, (unsigned int)RTE_MAX_MEMSEG_PER_TYPE); type->n_segs = n_segs; type->mem_sz = (size_t)pagesz * type->n_segs; mem_va_page_sz = RTE_MAX(mem_va_page_sz, (size_t)pagesz); diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index aad676a004..bbc4427524 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -510,6 +510,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg) memset(&internal_cfg->hugepage_info[i], 0, sizeof(internal_cfg->hugepage_info[0])); internal_cfg->hugepage_info[i].lock_descriptor = -1; + internal_cfg->hugepage_mem_sz_limits[i] = 0; } internal_cfg->base_virtaddr = 0; @@ -2359,6 +2360,25 @@ eal_adjust_config(struct internal_config *internal_cfg) return 0; } +int +eal_apply_hugepage_mem_sz_limits(struct internal_config *internal_cfg) +{ + unsigned int i; + + for (i = 0; i < internal_cfg->num_hugepage_sizes; i++) { + const uint64_t pagesz = internal_cfg->hugepage_info[i].hugepage_sz; + uint64_t limit; + + /* assign default limits */ + limit = RTE_MIN((uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20, + (uint64_t)RTE_MAX_MEMSEG_PER_TYPE * pagesz); + + internal_cfg->hugepage_mem_sz_limits[i] = limit; + } + + return 0; +} + RTE_EXPORT_SYMBOL(rte_vect_get_max_simd_bitwidth) uint16_t rte_vect_get_max_simd_bitwidth(void) diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h index 95d327a613..0bf192c6e5 100644 --- a/lib/eal/common/eal_internal_cfg.h +++ b/lib/eal/common/eal_internal_cfg.h @@ -96,6 +96,8 @@ struct internal_config { /**< user defined mbuf pool ops name */ unsigned num_hugepage_sizes; /**< how many sizes on this system */ struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES]; + uint64_t hugepage_mem_sz_limits[MAX_HUGEPAGE_SIZES]; + /**< default max memory per hugepage size */ enum rte_iova_mode iova_mode ; /**< Set IOVA mode on this system */ rte_cpuset_t ctrl_cpuset; /**< cpuset for ctrl threads */ volatile unsigned int init_complete; diff --git a/lib/eal/common/eal_options.h b/lib/eal/common/eal_options.h index f5e7905609..82cc8be8db 100644 --- a/lib/eal/common/eal_options.h +++ b/lib/eal/common/eal_options.h @@ -12,6 +12,7 @@ struct rte_tel_data; int eal_parse_log_options(void); int eal_parse_args(void); int eal_option_device_parse(void); +int eal_apply_hugepage_mem_sz_limits(struct internal_config *internal_cfg); int eal_adjust_config(struct internal_config *internal_cfg); int eal_cleanup_config(struct internal_config *internal_cfg); enum rte_proc_type_t eal_proc_type_detect(void); diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c index 60f5e676a8..8b1ba5b99b 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c @@ -585,6 +585,12 @@ rte_eal_init(int argc, char **argv) rte_errno = EACCES; goto err_out; } + if (internal_conf->process_type == RTE_PROC_PRIMARY && + eal_apply_hugepage_mem_sz_limits(internal_conf) < 0) { + rte_eal_init_alert("Cannot apply hugepage memory limits."); + rte_errno = EINVAL; + goto err_out; + } } if (internal_conf->memory == 0 && internal_conf->force_numa == 0) { diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c index d848de03d8..fc2e9b8c0e 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c @@ -748,6 +748,12 @@ rte_eal_init(int argc, char **argv) rte_errno = EACCES; goto err_out; } + if (internal_conf->process_type == RTE_PROC_PRIMARY && + eal_apply_hugepage_mem_sz_limits(internal_conf) < 0) { + rte_eal_init_alert("Cannot apply hugepage memory limits."); + rte_errno = EINVAL; + goto err_out; + } } if (internal_conf->memory == 0 && internal_conf->force_numa == 0) { diff --git a/lib/eal/linux/eal_memory.c b/lib/eal/linux/eal_memory.c index 55779badec..1ed4f69e3e 100644 --- a/lib/eal/linux/eal_memory.c +++ b/lib/eal/linux/eal_memory.c @@ -1813,6 +1813,7 @@ memseg_primary_init_32(void) for (hpi_idx = 0; hpi_idx < hp_sizes; hpi_idx++) { uint64_t max_pagesz_mem, cur_pagesz_mem = 0; uint64_t hugepage_sz; + uint64_t pagesz_mem_limit; struct hugepage_info *hpi; hpi = &internal_conf->hugepage_info[hpi_idx]; @@ -1823,6 +1824,8 @@ memseg_primary_init_32(void) continue; max_pagesz_mem = max_socket_mem - cur_socket_mem; + pagesz_mem_limit = internal_conf->hugepage_mem_sz_limits[hpi_idx]; + max_pagesz_mem = RTE_MIN(max_pagesz_mem, pagesz_mem_limit); /* make it multiple of page size */ max_pagesz_mem = RTE_ALIGN_FLOOR(max_pagesz_mem, diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index f06375a624..6dacae7235 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -229,6 +229,12 @@ rte_eal_init(int argc, char **argv) rte_errno = EACCES; goto err_out; } + if (!internal_conf->no_hugetlbfs && + eal_apply_hugepage_mem_sz_limits(internal_conf) < 0) { + rte_eal_init_alert("Cannot apply hugepage memory limits"); + rte_errno = EINVAL; + goto err_out; + } if (internal_conf->memory == 0 && !internal_conf->force_numa) { if (internal_conf->no_hugetlbfs) -- 2.47.3

