When need_hole is false, memseg searches will only be done for a single
element. If the search starts at beginning of the list, an element that
was previously reserved as a hole may be wrongly claimed.

To avoid this, begin the search following the last used entry. This way,
we ignore all pre-existing holes.

Signed-off-by: Jake Freeland <jf...@freebsd.org>
---
 lib/eal/freebsd/eal_memory.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/lib/eal/freebsd/eal_memory.c b/lib/eal/freebsd/eal_memory.c
index be3bde2cb9..b159e9ef4e 100644
--- a/lib/eal/freebsd/eal_memory.c
+++ b/lib/eal/freebsd/eal_memory.c
@@ -143,6 +143,7 @@ rte_eal_hugepage_init(void)
 
                        for (msl_idx = 0; msl_idx < RTE_MAX_MEMSEG_LISTS;
                                        msl_idx++) {
+                               int start_idx, num_elems;
                                bool empty, need_hole;
                                msl = &mcfg->memsegs[msl_idx];
                                arr = &msl->memseg_arr;
@@ -157,10 +158,24 @@ rte_eal_hugepage_init(void)
                                 * adjacent to current one.
                                 */
                                need_hole = !empty && !is_adjacent;
+                               if (need_hole) {
+                                       start_idx = 0;
+                                       /* we need 1, plus hole */
+                                       num_elems = 2;
+                               } else {
+                                       /* begin our search after the last used
+                                        * element in the list, skipping over
+                                        * any previously placed holes
+                                        */
+                                       start_idx = 
rte_fbarray_find_prev_n_used(
+                                                       arr, arr->len - 1, 1) + 
1;
+                                       if (start_idx < 0)
+                                               start_idx = 0;
+                                       num_elems = 1;
+                               }
 
-                               /* we need 1, plus hole if not adjacent */
                                ms_idx = rte_fbarray_find_next_n_free(arr,
-                                               0, 1 + (need_hole ? 1 : 0));
+                                               start_idx, num_elems);
 
                                /* memseg list is full? */
                                if (ms_idx < 0)
-- 
2.47.2

Reply via email to