Under legacy mode, if the number of continuous memsegs greater than RTE_MAX_MEMSEG_PER_LIST, eal init will failed even though another memseg list is empty, because only one memseg list used to check in remap_needed_hugepages. Fix this by add a argment indicate how many pages mapped in remap_segment, remap_segment try to mapped most pages it can, if exceed it's capbility, remap_needed_hugepages will continue to map other left pages.
For example: hugepage configure: cat /sys/devices/system/node/node*/hugepages/hugepages-2048kB/nr_hugepages 10241 10239 startup log: EAL: Detected memory type: socket_id:0 hugepage_sz:2097152 EAL: Detected memory type: socket_id:1 hugepage_sz:2097152 EAL: Creating 4 segment lists: n_segs:8192 socket_id:0 hugepage_sz:2097152 EAL: Creating 4 segment lists: n_segs:8192 socket_id:1 hugepage_sz:2097152 EAL: Requesting 13370 pages of size 2MB from socket 0 EAL: Requesting 7110 pages of size 2MB from socket 1 EAL: Attempting to map 14220M on socket 1 EAL: Allocated 14220M on socket 1 EAL: Attempting to map 26740M on socket 0 EAL: Could not find space for memseg. Please increase 32768 and/or 65536 in configuration. EAL: Couldn't remap hugepage files into memseg lists EAL: FATAL: Cannot init memory EAL: Cannot init memory Signed-off-by: Fengnan Chang <changfeng...@bytedance.com> Signed-off-by: Lin Li <lilint...@bytedance.com> --- lib/eal/linux/eal_memory.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/eal/linux/eal_memory.c b/lib/eal/linux/eal_memory.c index 60fc8cc6ca..b2e6453fbe 100644 --- a/lib/eal/linux/eal_memory.c +++ b/lib/eal/linux/eal_memory.c @@ -657,12 +657,12 @@ unmap_unneeded_hugepages(struct hugepage_file *hugepg_tbl, } static int -remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end) +remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end, int *mapped_seg_len) { struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; struct rte_memseg_list *msl; struct rte_fbarray *arr; - int cur_page, seg_len; + int cur_page, seg_len, cur_len; unsigned int msl_idx; int ms_idx; uint64_t page_sz; @@ -692,8 +692,9 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end) /* leave space for a hole if array is not empty */ empty = arr->count == 0; + cur_len = RTE_MIN((unsigned int)seg_len, arr->len - arr->count - (empty ? 0 : 1)); ms_idx = rte_fbarray_find_next_n_free(arr, 0, - seg_len + (empty ? 0 : 1)); + cur_len + (empty ? 0 : 1)); /* memseg list is full? */ if (ms_idx < 0) @@ -704,12 +705,12 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end) */ if (!empty) ms_idx++; + *mapped_seg_len = cur_len; break; } if (msl_idx == RTE_MAX_MEMSEG_LISTS) { - RTE_LOG(ERR, EAL, "Could not find space for memseg. Please increase %s and/or %s in configuration.\n", - RTE_STR(RTE_MAX_MEMSEG_PER_TYPE), - RTE_STR(RTE_MAX_MEM_MB_PER_TYPE)); + RTE_LOG(ERR, EAL, "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.\n"); return -1; } @@ -725,6 +726,8 @@ remap_segment(struct hugepage_file *hugepages, int seg_start, int seg_end) void *addr; int fd; + if (cur_page - seg_start == *mapped_seg_len) + break; fd = open(hfile->filepath, O_RDWR); if (fd < 0) { RTE_LOG(ERR, EAL, "Could not open '%s': %s\n", @@ -986,7 +989,7 @@ prealloc_segments(struct hugepage_file *hugepages, int n_pages) static int remap_needed_hugepages(struct hugepage_file *hugepages, int n_pages) { - int cur_page, seg_start_page, new_memseg, ret; + int cur_page, seg_start_page, new_memseg, ret, mapped_seg_len = 0; seg_start_page = 0; for (cur_page = 0; cur_page < n_pages; cur_page++) { @@ -1023,21 +1026,27 @@ remap_needed_hugepages(struct hugepage_file *hugepages, int n_pages) /* if this isn't the first time, remap segment */ if (cur_page != 0) { ret = remap_segment(hugepages, seg_start_page, - cur_page); + cur_page, &mapped_seg_len); if (ret != 0) return -1; } + cur_page = seg_start_page + mapped_seg_len; /* remember where we started */ seg_start_page = cur_page; + mapped_seg_len = 0; } /* continuation of previous memseg */ } /* we were stopped, but we didn't remap the last segment, do it now */ if (cur_page != 0) { - ret = remap_segment(hugepages, seg_start_page, - cur_page); - if (ret != 0) - return -1; + while (seg_start_page < n_pages) { + ret = remap_segment(hugepages, seg_start_page, + cur_page, &mapped_seg_len); + if (ret != 0) + return -1; + seg_start_page = seg_start_page + mapped_seg_len; + mapped_seg_len = 0; + } } return 0; } -- 2.37.1 (Apple Git-137.1)