In case of hugepages munmap requires size aligned to page. Signed-off-by: Maxim Uvarov <maxim.uva...@linaro.org> --- v5: - fix alloc_hp_size define (somehow arm gcc finds that it can be uninitialized; - remove goto and make if cases more readable;
platform/linux-generic/odp_shared_memory.c | 73 +++++++++++++++++++----------- test/validation/odp_shm.c | 4 ++ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/platform/linux-generic/odp_shared_memory.c b/platform/linux-generic/odp_shared_memory.c index 23a9ceb..4689c5d 100644 --- a/platform/linux-generic/odp_shared_memory.c +++ b/platform/linux-generic/odp_shared_memory.c @@ -179,27 +179,32 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, int map_flag = MAP_SHARED; /* If already exists: O_EXCL: error, O_TRUNC: truncate to zero */ int oflag = O_RDWR | O_CREAT | O_TRUNC; - uint64_t alloc_size = size + align; + uint64_t alloc_size; uint64_t page_sz, huge_sz; + int ret; +#ifdef MAP_HUGETLB + int need_huge_page = 0; + uint64_t alloc_hp_size; +#endif - huge_sz = odp_sys_huge_page_size(); page_sz = odp_sys_page_size(); + alloc_size = size + align; + +#ifdef MAP_HUGETLB + huge_sz = odp_sys_huge_page_size(); + need_huge_page = (huge_sz && alloc_size > page_sz); + /* munmap for huge pages requires sizes round up by page */ + alloc_hp_size = (size + align + (huge_sz - 1)) & (-huge_sz); +#endif if (flags & ODP_SHM_PROC) { /* Creates a file to /dev/shm */ fd = shm_open(name, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd == -1) { ODP_DBG("odp_shm_reserve: shm_open failed\n"); return ODP_SHM_INVALID; } - - if (ftruncate(fd, alloc_size) == -1) { - ODP_DBG("odp_shm_reserve: ftruncate failed\n"); - return ODP_SHM_INVALID; - } - } else { map_flag |= MAP_ANONYMOUS; } @@ -230,32 +235,47 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, block = &odp_shm_tbl->block[i]; block->hdl = to_handle(i); - block->huge = 0; addr = MAP_FAILED; #ifdef MAP_HUGETLB /* Try first huge pages */ - if (huge_sz && alloc_size > page_sz) { - addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, - map_flag | MAP_HUGETLB, fd, 0); + if (need_huge_page) { + ret = 0; + if (flags & ODP_SHM_PROC) + ret = ftruncate(fd, alloc_hp_size); + + if (ret == 0) { + addr = mmap(NULL, alloc_hp_size, PROT_READ | PROT_WRITE, + map_flag | MAP_HUGETLB, fd, 0); + if (addr == MAP_FAILED) { + ODP_DBG("odp_shm_reserve: mmap HP failed\n"); + } else { + block->alloc_size = alloc_hp_size; + block->huge = 1; + block->page_sz = huge_sz; + } + } } #endif /* Use normal pages for small or failed huge page allocations */ if (addr == MAP_FAILED) { - addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, - map_flag, fd, 0); - block->page_sz = page_sz; - } else { - block->huge = 1; - block->page_sz = huge_sz; - } - - if (addr == MAP_FAILED) { - /* Alloc failed */ - odp_spinlock_unlock(&odp_shm_tbl->lock); - ODP_DBG("odp_shm_reserve: mmap failed\n"); - return ODP_SHM_INVALID; + ret = 0; + if (flags & ODP_SHM_PROC) + ret = ftruncate(fd, alloc_size); + if (ret == 0) { + addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, + map_flag, fd, 0); + if (addr == MAP_FAILED) { + odp_spinlock_unlock(&odp_shm_tbl->lock); + ODP_DBG("odp_shm_reserve: mmap failed\n"); + return ODP_SHM_INVALID; + } else { + block->alloc_size = alloc_size; + block->huge = 0; + block->page_sz = page_sz; + } + } } block->addr_orig = addr; @@ -267,7 +287,6 @@ odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, block->name[ODP_SHM_NAME_LEN - 1] = 0; block->size = size; block->align = align; - block->alloc_size = alloc_size; block->flags = flags; block->fd = fd; block->addr = addr; diff --git a/test/validation/odp_shm.c b/test/validation/odp_shm.c index c26925b..4b1a38e 100644 --- a/test/validation/odp_shm.c +++ b/test/validation/odp_shm.c @@ -32,7 +32,11 @@ static void *run_shm_thread(void *arg) CU_ASSERT(0 == info.flags); CU_ASSERT(test_shared_data == info.addr); CU_ASSERT(sizeof(test_shared_data_t) <= info.size); +#ifdef MAP_HUGETLB + CU_ASSERT(odp_sys_huge_page_size() == info.page_size); +#else CU_ASSERT(odp_sys_page_size() == info.page_size); +#endif odp_shm_print_all(); fflush(stdout); -- 1.8.5.1.163.gd7aced9 _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org http://lists.linaro.org/mailman/listinfo/lng-odp