From c8ebf034d0bcdfe9a716d1697b02b307e4ee4514 Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 17 Sep 2019 14:31:37 -0400 Subject: [PATCH] port: mmap offset alignment on Windows On Windows the mmap offset is not aligned to the page size but to the allocator granularity which is usually bigger than the page size. Add a new internal function to the mmap compat code to get the proper offset alignment size for each platform. See the "dwFileOffsetLow" section for more details : https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile Change-Id: Ic26dc53862719892738a88b3dcea6a15901a0c94 Signed-off-by: Michael Jeanson Reviewed-on: https://review.lttng.org/c/babeltrace/+/2107 Reviewed-by: Simon Marchi Tested-by: jenkins --- src/common/mmap-align.h | 24 +++-------------------- src/compat/mman.c | 13 ++++++++++++ src/compat/mman.h | 17 ++++++++++++++++ src/plugins/ctf/fs-src/data-stream-file.c | 6 +++--- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/common/mmap-align.h b/src/common/mmap-align.h index 033d6c4a..c42cdeb3 100644 --- a/src/common/mmap-align.h +++ b/src/common/mmap-align.h @@ -46,29 +46,11 @@ struct mmap_align { size_t length; /* virtual mmap length */ }; -#ifdef __WIN32__ -#include - -/* - * On windows the memory mapping offset must be aligned to the memory - * allocator allocation granularity and not the page size. - */ -static inline -off_t get_page_aligned_offset(off_t offset, size_t page_size) -{ - SYSTEM_INFO sysinfo; - - GetNativeSystemInfo(&sysinfo); - - return ALIGN_FLOOR(offset, sysinfo.dwAllocationGranularity); -} -#else static inline -off_t get_page_aligned_offset(off_t offset, size_t page_size) +off_t get_page_aligned_offset(off_t offset, int log_level) { - return ALIGN_FLOOR(offset, page_size); + return ALIGN_FLOOR(offset, bt_mmap_get_offset_align_size(log_level)); } -#endif static inline struct mmap_align *mmap_align(size_t length, int prot, @@ -84,7 +66,7 @@ struct mmap_align *mmap_align(size_t length, int prot, if (!mma) return MAP_FAILED; mma->length = length; - page_aligned_offset = get_page_aligned_offset(offset, page_size); + page_aligned_offset = get_page_aligned_offset(offset, log_level); /* * Page aligned length needs to contain the requested range. * E.g., for a small range that fits within a single page, we might diff --git a/src/compat/mman.c b/src/compat/mman.c index 1a7638c9..d2019d2b 100644 --- a/src/compat/mman.c +++ b/src/compat/mman.c @@ -300,4 +300,17 @@ end: return ret; } +BT_HIDDEN +size_t bt_mmap_get_offset_align_size(int log_level) +{ + SYSTEM_INFO sysinfo; + + GetNativeSystemInfo(&sysinfo); + BT_LOG_WRITE_CUR_LVL(BT_LOG_DEBUG, log_level, BT_LOG_TAG, + "Allocator granularity is %lu.", + sysinfo.dwAllocationGranularity); + + return sysinfo.dwAllocationGranularity; +} + #endif diff --git a/src/compat/mman.h b/src/compat/mman.h index bdab9d19..4ed889ac 100644 --- a/src/compat/mman.h +++ b/src/compat/mman.h @@ -50,9 +50,16 @@ void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd, int bt_munmap(void *addr, size_t length); +/* + * On Windows the memory mapping offset must be aligned to the memory + * allocator allocation granularity and not the page size. + */ +size_t bt_mmap_get_offset_align_size(int log_level); + #else /* __MINGW32__ */ #include +#include "common/common.h" static inline void *bt_mmap(void *addr, size_t length, int prot, int flags, int fd, @@ -66,6 +73,16 @@ int bt_munmap(void *addr, size_t length) { return munmap(addr, length); } + +/* + * On other platforms the memory mapping offset must be aligned to the + * page size. + */ +static inline +size_t bt_mmap_get_offset_align_size(int log_level) +{ + return bt_common_get_page_size(log_level); +} #endif /* __MINGW32__ */ #ifndef MAP_ANONYMOUS diff --git a/src/plugins/ctf/fs-src/data-stream-file.c b/src/plugins/ctf/fs-src/data-stream-file.c index 6ddb8a34..924a2be7 100644 --- a/src/plugins/ctf/fs-src/data-stream-file.c +++ b/src/plugins/ctf/fs-src/data-stream-file.c @@ -251,7 +251,7 @@ enum bt_msg_iter_medium_status medop_seek(enum bt_msg_iter_seek_whence whence, map_requested_offset: offset_in_mapping = offset % - bt_common_get_page_size(ds_file->log_level); + bt_mmap_get_offset_align_size(ds_file->log_level); ds_file->mmap_offset = offset - offset_in_mapping; ds_file->request_offset = offset_in_mapping; @@ -642,7 +642,7 @@ struct ctf_fs_ds_file *ctf_fs_ds_file_create( bt_logging_level log_level) { int ret; - const size_t page_size = bt_common_get_page_size(log_level); + const size_t offset_align = bt_mmap_get_offset_align_size(log_level); struct ctf_fs_ds_file *ds_file = g_new0(struct ctf_fs_ds_file, 1); if (!ds_file) { @@ -672,7 +672,7 @@ struct ctf_fs_ds_file *ctf_fs_ds_file_create( goto error; } - ds_file->mmap_max_len = page_size * 2048; + ds_file->mmap_max_len = offset_align * 2048; goto end; -- 2.34.1