[PATCH v2 2/6] eal/memory: remove per-list segment and memory limits

Bruce Richardson bruce.richardson at intel.com
Tue May 26 16:57:22 CEST 2026


On Fri, Mar 13, 2026 at 04:06:33PM +0000, Anatoly Burakov wrote:
> Initially, the dynamic memory mode has used multiple segment lists for
> backing of different memory types, with the motivation being that it should
> be easier for secondary processes to map many smaller segments than fewer
> but larger ones, but in practice this does not seem to make any difference
> for 64-bit platforms, as there's usually plenty of address space.
> 

I think it's worth clarifying here that each list corresponds to a VA
address space block. The term segment is also a little confusing here,
since the EAL memseg used in segment lists is now a page IIRC, but the
"smaller segments" for secondaries are blocks of VA space, right?

> To reduce the amount of complexity in how memory segment lists are handled,
> collapse the multi-list logic to always use single segment list.
> 
> That does not mean that all memory types will always get one segment - in
> some cases (e.g. 32-bit) we may not be able to allocate enough contiguous
> VA spaces to fit entire memory type into one list, in which case the number
> of memseg lists for that type will be more than one. It is more about
> lifting the upper limit on how many segment lists can a type have. If we
> end up blowing up our number of segment lists so much that we exceed a
> very generous default maximum memseg lists number then the user has bigger
> problems to address.
> 
> Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>

Acked-by: Bruce Richardson <bruce.richardson at intel.com>

Some comments inline below. Nothing major, just some style suggestions.

> ---
>  config/rte_config.h                           |   2 -
>  .../prog_guide/env_abstraction_layer.rst      |   4 -
>  lib/eal/common/eal_common_dynmem.c            | 110 +++++-------------
>  lib/eal/common/eal_common_memory.c            |   6 +-
>  lib/eal/common/eal_filesystem.h               |  13 +++
>  lib/eal/common/eal_private.h                  |   6 +-
>  lib/eal/freebsd/eal_memory.c                  |  75 ++++--------
>  lib/eal/linux/eal_memalloc.c                  |   4 +-
>  lib/eal/linux/eal_memory.c                    |  88 ++++++--------
>  9 files changed, 107 insertions(+), 201 deletions(-)
> 
> diff --git a/config/rte_config.h b/config/rte_config.h
> index a2609fa403..0447cdf2ad 100644
> --- a/config/rte_config.h
> +++ b/config/rte_config.h
> @@ -43,8 +43,6 @@
>  #define RTE_MAX_HEAPS 32
>  #define RTE_MAX_LCORE_VAR 131072
>  #define RTE_MAX_MEMSEG_LISTS 128
> -#define RTE_MAX_MEMSEG_PER_LIST 8192
> -#define RTE_MAX_MEM_MB_PER_LIST 32768
>  #define RTE_MAX_MEMSEG_PER_TYPE 32768
>  #define RTE_MAX_MEM_MB_PER_TYPE 65536
>  #define RTE_MAX_TAILQ 32
> diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst
> index d716895c1d..04368a3950 100644
> --- a/doc/guides/prog_guide/env_abstraction_layer.rst
> +++ b/doc/guides/prog_guide/env_abstraction_layer.rst
> @@ -204,10 +204,6 @@ of virtual memory being preallocated at startup by editing the following config
>  variables:
>  
>  * ``RTE_MAX_MEMSEG_LISTS`` controls how many segment lists can DPDK have
> -* ``RTE_MAX_MEM_MB_PER_LIST`` controls how much megabytes of memory each
> -  segment list can address
> -* ``RTE_MAX_MEMSEG_PER_LIST`` controls how many segments each segment list
> -  can have
>  * ``RTE_MAX_MEMSEG_PER_TYPE`` controls how many segments each memory type
>    can have (where "type" is defined as "page size + NUMA node" combination)
>  * ``RTE_MAX_MEM_MB_PER_TYPE`` controls how much megabytes of memory each
> diff --git a/lib/eal/common/eal_common_dynmem.c b/lib/eal/common/eal_common_dynmem.c
> index 8f51d6dd4a..ef0270cc30 100644
> --- a/lib/eal/common/eal_common_dynmem.c
> +++ b/lib/eal/common/eal_common_dynmem.c
> @@ -24,11 +24,10 @@ eal_dynmem_memseg_lists_init(void)
>  	struct memtype {
>  		uint64_t page_sz;
>  		int socket_id;
> -	} *memtypes = NULL;
> +	} 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, max_mem_per_type;
> -	unsigned int max_seglists_per_type;
>  	unsigned int n_memtypes, cur_type;
>  	struct internal_config *internal_conf =
>  		eal_get_internal_configuration();
> @@ -45,8 +44,7 @@ eal_dynmem_memseg_lists_init(void)
>  	 *
>  	 * deciding amount of memory going towards each memory type is a
>  	 * balancing act between maximum segments per type, maximum memory per
> -	 * type, and number of detected NUMA nodes. the goal is to make sure
> -	 * each memory type gets at least one memseg list.
> +	 * type, and number of detected NUMA nodes.
>  	 *
>  	 * the total amount of memory is limited by RTE_MAX_MEM_MB value.
>  	 *
> @@ -57,26 +55,18 @@ eal_dynmem_memseg_lists_init(void)
>  	 * smaller page sizes, it can take hundreds of thousands of segments to
>  	 * reach the above specified per-type memory limits.
>  	 *
> -	 * additionally, each type may have multiple memseg lists associated
> -	 * with it, each limited by either RTE_MAX_MEM_MB_PER_LIST for bigger
> -	 * page sizes, or RTE_MAX_MEMSEG_PER_LIST segments for smaller ones.
> -	 *
> -	 * the number of memseg lists per type is decided based on the above
> -	 * limits, and also taking number of detected NUMA nodes, to make sure
> -	 * that we don't run out of memseg lists before we populate all NUMA
> -	 * nodes with memory.
> -	 *
> -	 * we do this in three stages. first, we collect the number of types.
> -	 * then, we figure out memory constraints and populate the list of
> -	 * would-be memseg lists. then, we go ahead and allocate the memseg
> -	 * lists.
> +	 * 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.
>  	 */
>  
> -	/* create space for mem types */
> +	/* maximum number of memtypes we're ever going to get */
>  	n_memtypes = internal_conf->num_hugepage_sizes * rte_socket_count();
> -	memtypes = calloc(n_memtypes, sizeof(*memtypes));
> -	if (memtypes == NULL) {
> -		EAL_LOG(ERR, "Cannot allocate space for memory types");
> +
> +	/* can we fit all memtypes into the memseg lists? */
> +	if (n_memtypes > RTE_MAX_MEMSEG_LISTS) {
> +		EAL_LOG(ERR, "Too many memory types detected: %u. Please increase "
> +			"RTE_MAX_MEMSEG_LISTS in configuration.", n_memtypes);
>  		return -1;

Don't split log messages across lines. Go over the 100 char limit if
necessary to avoid splits.

>  	}
>  
> @@ -113,91 +103,49 @@ eal_dynmem_memseg_lists_init(void)
>  	max_mem = (uint64_t)RTE_MAX_MEM_MB << 20;
>  	max_mem_per_type = RTE_MIN((uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20,
>  			max_mem / n_memtypes);
> -	/*
> -	 * limit maximum number of segment lists per type to ensure there's
> -	 * space for memseg lists for all NUMA nodes with all page sizes
> -	 */
> -	max_seglists_per_type = RTE_MAX_MEMSEG_LISTS / n_memtypes;
> -
> -	if (max_seglists_per_type == 0) {
> -		EAL_LOG(ERR, "Cannot accommodate all memory types, please increase RTE_MAX_MEMSEG_LISTS");
> -		goto out;
> -	}
>  
>  	/* go through all mem types and create segment lists */
>  	msl_idx = 0;
>  	for (cur_type = 0; cur_type < n_memtypes; cur_type++) {
> -		unsigned int cur_seglist, n_seglists, n_segs;
> -		unsigned int max_segs_per_type, max_segs_per_list;
> +		unsigned int n_segs;
>  		struct memtype *type = &memtypes[cur_type];
> -		uint64_t max_mem_per_list, pagesz;
> +		uint64_t pagesz;
>  		int socket_id;
>  
>  		pagesz = type->page_sz;
>  		socket_id = type->socket_id;
>  
>  		/*
> -		 * we need to create segment lists for this type. we must take
> +		 * we need to create a segment list for this type. we must take
>  		 * into account the following things:
>  		 *
> -		 * 1. total amount of memory we can use for this memory type
> -		 * 2. total amount of memory per memseg list allowed
> +		 * 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
> -		 * 5. number of segments allowed per memseg list
> -		 * 6. number of memseg lists we are allowed to take up
>  		 */
> +		n_segs = max_mem_per_type / pagesz;
> +		n_segs = RTE_MIN(n_segs, (unsigned int)RTE_MAX_MEMSEG_PER_TYPE);
>  
> -		/* calculate how much segments we will need in total */
> -		max_segs_per_type = max_mem_per_type / pagesz;
> -		/* limit number of segments to maximum allowed per type */
> -		max_segs_per_type = RTE_MIN(max_segs_per_type,
> -				(unsigned int)RTE_MAX_MEMSEG_PER_TYPE);
> -		/* limit number of segments to maximum allowed per list */
> -		max_segs_per_list = RTE_MIN(max_segs_per_type,
> -				(unsigned int)RTE_MAX_MEMSEG_PER_LIST);
> +		EAL_LOG(DEBUG, "Creating segment list: "
> +				"n_segs:%u socket_id:%i hugepage_sz:%" PRIu64,
> +			n_segs, socket_id, pagesz);
>  

Again, better not to split this message.

> -		/* calculate how much memory we can have per segment list */
> -		max_mem_per_list = RTE_MIN(max_segs_per_list * pagesz,
> -				(uint64_t)RTE_MAX_MEM_MB_PER_LIST << 20);
> +		msl = &mcfg->memsegs[msl_idx];
>  
> -		/* calculate how many segments each segment list will have */
> -		n_segs = RTE_MIN(max_segs_per_list, max_mem_per_list / pagesz);
> +		if (eal_memseg_list_init(msl, pagesz, n_segs, socket_id,
> +				msl_idx, true))

This can actually fit on one line.

> +			goto out;
>  
> -		/* calculate how many segment lists we can have */
> -		n_seglists = RTE_MIN(max_segs_per_type / n_segs,
> -				max_mem_per_type / max_mem_per_list);
> -
> -		/* limit number of segment lists according to our maximum */
> -		n_seglists = RTE_MIN(n_seglists, max_seglists_per_type);
> -
> -		EAL_LOG(DEBUG, "Creating %i segment lists: "
> -				"n_segs:%i socket_id:%i hugepage_sz:%" PRIu64,
> -			n_seglists, n_segs, socket_id, pagesz);
> -
> -		/* create all segment lists */
> -		for (cur_seglist = 0; cur_seglist < n_seglists; cur_seglist++) {
> -			if (msl_idx >= RTE_MAX_MEMSEG_LISTS) {
> -				EAL_LOG(ERR,
> -					"No more space in memseg lists, please increase RTE_MAX_MEMSEG_LISTS");
> -				goto out;
> -			}
> -			msl = &mcfg->memsegs[msl_idx++];
> -
> -			if (eal_memseg_list_init(msl, pagesz, n_segs,
> -					socket_id, cur_seglist, true))
> -				goto out;
> -
> -			if (eal_memseg_list_alloc(msl, 0)) {
> -				EAL_LOG(ERR, "Cannot allocate VA space for memseg list");
> -				goto out;
> -			}
> +		if (eal_memseg_list_alloc(msl, 0)) {
> +			EAL_LOG(ERR, "Cannot allocate VA space for memseg list");
> +			goto out;
>  		}
> +		msl_idx++;
>  	}
>  	/* we're successful */
>  	ret = 0;
>  out:
> -	free(memtypes);
>  	return ret;
>  }
>  
> diff --git a/lib/eal/common/eal_common_memory.c b/lib/eal/common/eal_common_memory.c
> index dccf9406c5..b9388021ff 100644
> --- a/lib/eal/common/eal_common_memory.c
> +++ b/lib/eal/common/eal_common_memory.c
> @@ -228,12 +228,12 @@ eal_memseg_list_init_named(struct rte_memseg_list *msl, const char *name,
>  
>  int
>  eal_memseg_list_init(struct rte_memseg_list *msl, uint64_t page_sz,
> -		int n_segs, int socket_id, int type_msl_idx, bool heap)
> +		int n_segs, int socket_id, int msl_idx, bool heap)
>  {
>  	char name[RTE_FBARRAY_NAME_LEN];
>  
> -	snprintf(name, sizeof(name), MEMSEG_LIST_FMT, page_sz >> 10, socket_id,
> -		 type_msl_idx);
> +	snprintf(name, sizeof(name), MEMSEG_LIST_FMT,
> +			page_sz >> 10, socket_id, msl_idx);
>  

Fits on single line.

>  	return eal_memseg_list_init_named(
>  		msl, name, page_sz, n_segs, socket_id, heap);
> diff --git a/lib/eal/common/eal_filesystem.h b/lib/eal/common/eal_filesystem.h
> index 6b99d22160..2d22b52e76 100644
> --- a/lib/eal/common/eal_filesystem.h
> +++ b/lib/eal/common/eal_filesystem.h
> @@ -114,6 +114,19 @@ eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id
>  		return buffer;
>  }
>  
> +#define HUGEFILE_FMT_LIST_SEG "%s/%smap_%u_%u"
> +static inline __rte_warn_unused_result const char *
> +eal_get_hugefile_list_seg_path(char *buffer, size_t buflen,
> +		const char *hugedir, unsigned int list_idx, unsigned int seg_idx)
> +{
> +	if (snprintf(buffer, buflen, HUGEFILE_FMT_LIST_SEG,
> +			hugedir, eal_get_hugefile_prefix(), list_idx, seg_idx)
> +			>= (int)buflen)

Can fit in two lines not three, e.g. move up the ">= (int)buflen".

> +		return NULL;
> +	else
> +		return buffer;

While I know it's a copy of the previous function in the file, the "else"
is really unnecessary.

> +}
> +
>  /** define the default filename prefix for the %s values above */
>  #define HUGEFILE_PREFIX_DEFAULT "rte"
>  
> diff --git a/lib/eal/common/eal_private.h b/lib/eal/common/eal_private.h
> index e032dd10c9..70f7b46699 100644
> --- a/lib/eal/common/eal_private.h
> +++ b/lib/eal/common/eal_private.h
> @@ -299,14 +299,14 @@ eal_memseg_list_init_named(struct rte_memseg_list *msl, const char *name,
>   * Initialize memory segment list and create its backing storage
>   * with a name corresponding to MSL parameters.
>   *
> - * @param type_msl_idx
> - *  Index of the MSL among other MSLs of the same socket and page size.
> + * @param msl_idx
> + *  Index of the MSL in memsegs array.
>   *
>   * @see eal_memseg_list_init_named for remaining parameters description.
>   */
>  int
>  eal_memseg_list_init(struct rte_memseg_list *msl, uint64_t page_sz,
> -	int n_segs, int socket_id, int type_msl_idx, bool heap);
> +		int n_segs, int socket_id, int msl_idx, bool heap);
>  
>  /**
>   * Reserve VA space for a memory segment list
> diff --git a/lib/eal/freebsd/eal_memory.c b/lib/eal/freebsd/eal_memory.c
> index cd608db9f9..3eb5d193ec 100644
> --- a/lib/eal/freebsd/eal_memory.c
> +++ b/lib/eal/freebsd/eal_memory.c
> @@ -190,8 +190,8 @@ rte_eal_hugepage_init(void)
>  				break;
>  			}
>  			if (msl_idx == RTE_MAX_MEMSEG_LISTS) {
> -				EAL_LOG(ERR, "Could not find space for memseg. Please increase RTE_MAX_MEMSEG_PER_LIST "
> -					"RTE_MAX_MEMSEG_PER_TYPE and/or RTE_MAX_MEM_MB_PER_TYPE in configuration.");
> +				EAL_LOG(ERR,
> +					"Could not find suitable space for memseg in existing memseg lists");
>  				return -1;
>  			}
>  			arr = &msl->memseg_arr;
> @@ -320,23 +320,6 @@ rte_eal_using_phys_addrs(void)
>  	return 0;
>  }
>  
> -static uint64_t
> -get_mem_amount(uint64_t page_sz, uint64_t max_mem)
> -{
> -	uint64_t area_sz, max_pages;
> -
> -	/* limit to RTE_MAX_MEMSEG_PER_LIST pages or RTE_MAX_MEM_MB_PER_LIST */
> -	max_pages = RTE_MAX_MEMSEG_PER_LIST;
> -	max_mem = RTE_MIN((uint64_t)RTE_MAX_MEM_MB_PER_LIST << 20, max_mem);
> -
> -	area_sz = RTE_MIN(page_sz * max_pages, max_mem);
> -
> -	/* make sure the list isn't smaller than the page size */
> -	area_sz = RTE_MAX(area_sz, page_sz);
> -
> -	return RTE_ALIGN(area_sz, page_sz);
> -}
> -
>  static int
>  memseg_list_alloc(struct rte_memseg_list *msl)
>  {
> @@ -380,9 +363,10 @@ memseg_primary_init(void)
>  			hpi_idx++) {
>  		uint64_t max_type_mem, total_type_mem = 0;
>  		uint64_t avail_mem;
> -		int type_msl_idx, max_segs, avail_segs, total_segs = 0;
> +		unsigned int avail_segs;
>  		struct hugepage_info *hpi;
>  		uint64_t hugepage_sz;
> +		unsigned int n_segs;
>  
>  		hpi = &internal_conf->hugepage_info[hpi_idx];
>  		hugepage_sz = hpi->hugepage_sz;
> @@ -396,7 +380,6 @@ memseg_primary_init(void)
>  		/* first, calculate theoretical limits according to config */
>  		max_type_mem = RTE_MIN(max_mem - total_mem,
>  			(uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20);
> -		max_segs = RTE_MAX_MEMSEG_PER_TYPE;
>  
>  		/* now, limit all of that to whatever will actually be
>  		 * available to us, because without dynamic allocation support,
> @@ -412,42 +395,30 @@ memseg_primary_init(void)
>  		avail_mem = avail_segs * hugepage_sz;
>  
>  		max_type_mem = RTE_MIN(avail_mem, max_type_mem);
> -		max_segs = RTE_MIN(avail_segs, max_segs);
> -
> -		type_msl_idx = 0;
> -		while (total_type_mem < max_type_mem &&
> -				total_segs < max_segs) {
> -			uint64_t cur_max_mem, cur_mem;
> -			unsigned int n_segs;
> -
> -			if (msl_idx >= RTE_MAX_MEMSEG_LISTS) {
> -				EAL_LOG(ERR,
> -					"No more space in memseg lists, please increase RTE_MAX_MEMSEG_LISTS");
> -				return -1;
> -			}
> -
> -			msl = &mcfg->memsegs[msl_idx++];
> -
> -			cur_max_mem = max_type_mem - total_type_mem;
> -
> -			cur_mem = get_mem_amount(hugepage_sz,
> -					cur_max_mem);
> -			n_segs = cur_mem / hugepage_sz;
> +		n_segs = max_type_mem / hugepage_sz;
> +		if (n_segs == 0)
> +			continue;
> +
> +		if (msl_idx >= RTE_MAX_MEMSEG_LISTS) {
> +			EAL_LOG(ERR,
> +				"No more space in memseg lists, please increase RTE_MAX_MEMSEG_LISTS");

Not sure it's worth splitting this across two lines. You only save 3 or 4
chars. :-)

> +			return -1;
> +		}
>  
> -			if (eal_memseg_list_init(msl, hugepage_sz, n_segs,
> -					0, type_msl_idx, false))
> -				return -1;
> +		msl = &mcfg->memsegs[msl_idx];
>  
> -			total_segs += msl->memseg_arr.len;
> -			total_type_mem = total_segs * hugepage_sz;
> -			type_msl_idx++;
> +		if (eal_memseg_list_init(msl, hugepage_sz, n_segs,
> +				0, msl_idx, false))

Fits on one line.

> +			return -1;
>  
> -			if (memseg_list_alloc(msl)) {
> -				EAL_LOG(ERR, "Cannot allocate VA space for memseg list");
> -				return -1;
> -			}
> +		total_type_mem = n_segs * hugepage_sz;
> +		if (memseg_list_alloc(msl)) {
> +			EAL_LOG(ERR, "Cannot allocate VA space for memseg list");
> +			return -1;
>  		}
> +
>  		total_mem += total_type_mem;
> +		msl_idx++;
>  	}
>  	return 0;
>  }
> diff --git a/lib/eal/linux/eal_memalloc.c b/lib/eal/linux/eal_memalloc.c
> index a39bc31c7b..2227b1c52b 100644
> --- a/lib/eal/linux/eal_memalloc.c
> +++ b/lib/eal/linux/eal_memalloc.c
> @@ -282,8 +282,8 @@ get_seg_fd(char *path, int buflen, struct hugepage_info *hi,
>  		huge_path = eal_get_hugefile_path(path, buflen, hi->hugedir, list_idx);
>  	} else {
>  		out_fd = &fd_list[list_idx].fds[seg_idx];
> -		huge_path = eal_get_hugefile_path(path, buflen, hi->hugedir,
> -				list_idx * RTE_MAX_MEMSEG_PER_LIST + seg_idx);
> +		huge_path = eal_get_hugefile_list_seg_path(path, buflen,
> +				hi->hugedir, list_idx, seg_idx);
>  	}
>  	if (huge_path == NULL) {
>  		EAL_LOG(DEBUG, "%s(): hugefile path truncated: '%s'",
> diff --git a/lib/eal/linux/eal_memory.c b/lib/eal/linux/eal_memory.c
> index bf783e3c76..691d8eb3cc 100644
> --- a/lib/eal/linux/eal_memory.c
> +++ b/lib/eal/linux/eal_memory.c
> @@ -740,8 +740,8 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end)
>  		break;
>  	}
>  	if (msl_idx == RTE_MAX_MEMSEG_LISTS) {
> -		EAL_LOG(ERR, "Could not find space for memseg. Please increase RTE_MAX_MEMSEG_PER_LIST "
> -			"RTE_MAX_MEMSEG_PER_TYPE and/or RTE_MAX_MEM_MB_PER_TYPE in configuration.");
> +		EAL_LOG(ERR,
> +			"Could not find suitable space for memseg in existing memseg lists");
>  		return -1;
>  	}
>  
> @@ -822,23 +822,6 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end)
>  	return seg_len;
>  }
>  
> -static uint64_t
> -get_mem_amount(uint64_t page_sz, uint64_t max_mem)
> -{
> -	uint64_t area_sz, max_pages;
> -
> -	/* limit to RTE_MAX_MEMSEG_PER_LIST pages or RTE_MAX_MEM_MB_PER_LIST */
> -	max_pages = RTE_MAX_MEMSEG_PER_LIST;
> -	max_mem = RTE_MIN((uint64_t)RTE_MAX_MEM_MB_PER_LIST << 20, max_mem);
> -
> -	area_sz = RTE_MIN(page_sz * max_pages, max_mem);
> -
> -	/* make sure the list isn't smaller than the page size */
> -	area_sz = RTE_MAX(area_sz, page_sz);
> -
> -	return RTE_ALIGN(area_sz, page_sz);
> -}
> -
>  static int
>  memseg_list_free(struct rte_memseg_list *msl)
>  {
> @@ -1831,7 +1814,6 @@ memseg_primary_init_32(void)
>  			uint64_t max_pagesz_mem, cur_pagesz_mem = 0;
>  			uint64_t hugepage_sz;
>  			struct hugepage_info *hpi;
> -			int type_msl_idx, max_segs, total_segs = 0;
>  
>  			hpi = &internal_conf->hugepage_info[hpi_idx];
>  			hugepage_sz = hpi->hugepage_sz;
> @@ -1840,62 +1822,60 @@ memseg_primary_init_32(void)
>  			if (hpi->num_pages[socket_id] == 0)
>  				continue;
>  
> -			max_segs = RTE_MAX_MEMSEG_PER_TYPE;
>  			max_pagesz_mem = max_socket_mem - cur_socket_mem;
>  
>  			/* make it multiple of page size */
>  			max_pagesz_mem = RTE_ALIGN_FLOOR(max_pagesz_mem,
>  					hugepage_sz);
>  
> +			if (max_pagesz_mem == 0)
> +				continue;
> +
>  			EAL_LOG(DEBUG, "Attempting to preallocate "
>  					"%" PRIu64 "M on socket %i",
>  					max_pagesz_mem >> 20, socket_id);
>  
> -			type_msl_idx = 0;
> -			while (cur_pagesz_mem < max_pagesz_mem &&
> -					total_segs < max_segs) {
> -				uint64_t cur_mem;
> +			while (cur_pagesz_mem < max_pagesz_mem) {
> +				uint64_t rem_mem;
>  				unsigned int n_segs;
>  
> -				if (msl_idx >= RTE_MAX_MEMSEG_LISTS) {
> -					EAL_LOG(ERR,
> -						"No more space in memseg lists, please increase RTE_MAX_MEMSEG_LISTS");
> -					return -1;
> -				}
> +				rem_mem = max_pagesz_mem - cur_pagesz_mem;
> +				n_segs = rem_mem / hugepage_sz;
>  
> -				msl = &mcfg->memsegs[msl_idx];
> +				while (n_segs > 0) {
> +					if (msl_idx >= RTE_MAX_MEMSEG_LISTS) {
> +						EAL_LOG(ERR,
> +							"No more space in memseg lists, please increase RTE_MAX_MEMSEG_LISTS");
> +						return -1;
> +					}
>  
> -				cur_mem = get_mem_amount(hugepage_sz,
> -						max_pagesz_mem);
> -				n_segs = cur_mem / hugepage_sz;
> +					msl = &mcfg->memsegs[msl_idx];
>  
> -				if (eal_memseg_list_init(msl, hugepage_sz,
> -						n_segs, socket_id, type_msl_idx,
> -						true)) {
> -					/* failing to allocate a memseg list is
> -					 * a serious error.
> -					 */
> -					EAL_LOG(ERR, "Cannot allocate memseg list");
> -					return -1;
> -				}
> +					if (eal_memseg_list_init(msl, hugepage_sz,
> +							n_segs, socket_id, msl_idx, true) < 0) {
> +						/* failing to allocate a memseg list is a serious error. */
> +						EAL_LOG(ERR, "Cannot allocate memseg list");
> +						return -1;
> +					}
> +
> +					if (eal_memseg_list_alloc(msl, 0) == 0)
> +						break;
>  
> -				if (eal_memseg_list_alloc(msl, 0)) {
> -					/* if we couldn't allocate VA space, we
> -					 * can try with smaller page sizes.
> -					 */
> -					EAL_LOG(ERR, "Cannot allocate VA space for memseg list, retrying with different page size");
> -					/* deallocate memseg list */
>  					if (memseg_list_free(msl))
>  						return -1;
> -					break;
> +
> +					EAL_LOG(DEBUG,
> +						"Cannot allocate VA space for memseg list, retrying with smaller chunk");
> +					n_segs /= 2;
>  				}
>  
> -				total_segs += msl->memseg_arr.len;
> -				cur_pagesz_mem = total_segs * hugepage_sz;
> -				type_msl_idx++;
> +				if (n_segs == 0)
> +					break;
> +
> +				cur_pagesz_mem += (uint64_t)n_segs * hugepage_sz;
> +				cur_socket_mem += (uint64_t)n_segs * hugepage_sz;
>  				msl_idx++;
>  			}
> -			cur_socket_mem += cur_pagesz_mem;
>  		}
>  		if (cur_socket_mem == 0) {
>  			EAL_LOG(ERR, "Cannot allocate VA space on socket %u",
> -- 
> 2.47.3
> 


More information about the dev mailing list