diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c index 220daef290..8c11f98c92 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c +++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c @@ -610,14 +610,6 @@ free_seg(struct rte_memseg *ms, struct hugepage_info *hi, /* erase page data */ memset(ms->addr, 0, ms->len); - /* if we are not in single file segments mode, we're going to unmap the - * segment and thus drop the lock on original fd, so take out another - * shared lock before we do that. - */ - fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx); - if (fd < 0) - return -1; - if (mmap(ms->addr, ms->len, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) == MAP_FAILED) { @@ -625,6 +617,14 @@ free_seg(struct rte_memseg *ms, struct hugepage_info *hi, return -1; } + /* if we are not in single file segments mode, we're going to unmap the + * segment and thus drop the lock on original fd, but hugepage dir is + * now locked so we can take out another one without races. + */ + fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx); + if (fd < 0) + return -1; + if (internal_config.single_file_segments) { map_offset = seg_idx * ms->len; if (resize_hugefile(fd, path, list_idx, seg_idx, map_offset, @@ -735,12 +735,13 @@ alloc_seg_walk(const struct rte_memseg_list *msl, void *arg) &cur_msl->memseg_arr; tmp = rte_fbarray_get(arr, j); - if (free_seg(tmp, wa->hi, msl_idx, j)) { - RTE_LOG(ERR, EAL, "Cannot free page\n"); - continue; - } - rte_fbarray_set_free(arr, j); + + /* free_seg may attempt to create a file, which + * may fail. + */ + if (free_seg(tmp, wa->hi, msl_idx, j)) + RTE_LOG(DEBUG, EAL, "Cannot free page\n"); } /* clear the list */ if (wa->ms)