Message ID | 1422274391-18907-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | New |
Headers | show |
skip this patch. Did not account one more comment about ftuncate error. Maxim. On 01/26/2015 03:13 PM, Maxim Uvarov wrote: > In case of hugepages munmap requires size aligned to page. > > Signed-off-by: Maxim Uvarov <maxim.uvarov@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);
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);
In case of hugepages munmap requires size aligned to page. Signed-off-by: Maxim Uvarov <maxim.uvarov@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(-)