From 24f2e878c102c9c2444c54f0dd66eba2a20cd246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Mon, 2 Jan 2023 15:47:48 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D1=83=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B5=D1=81=D1=83=D1=89=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20Valgrind.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core.c | 29 +++++++++++++++++++---------- test/valgrind_suppress.txt | 8 ++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/core.c b/src/core.c index b23b3700..80ddb7c3 100644 --- a/src/core.c +++ b/src/core.c @@ -2221,11 +2221,11 @@ static __always_inline size_t pnl_size2bytes(size_t size) { #endif /* MDBX_PNL_PREALLOC_FOR_RADIXSORT */ STATIC_ASSERT(MDBX_ASSUME_MALLOC_OVERHEAD + (MDBX_PGL_LIMIT * (MDBX_PNL_PREALLOC_FOR_RADIXSORT + 1) + - MDBX_PNL_GRANULATE + 2) * + MDBX_PNL_GRANULATE + 3) * sizeof(pgno_t) < SIZE_MAX / 4 * 3); size_t bytes = - ceil_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + sizeof(pgno_t) * (size + 2), + ceil_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + sizeof(pgno_t) * (size + 3), MDBX_PNL_GRANULATE * sizeof(pgno_t)) - MDBX_ASSUME_MALLOC_OVERHEAD; return bytes; @@ -2233,8 +2233,8 @@ static __always_inline size_t pnl_size2bytes(size_t size) { static __always_inline pgno_t pnl_bytes2size(const size_t bytes) { size_t size = bytes / sizeof(pgno_t); - assert(size > 2 && size <= MDBX_PGL_LIMIT + /* alignment gap */ 65536); - size -= 2; + assert(size > 3 && size <= MDBX_PGL_LIMIT + /* alignment gap */ 65536); + size -= 3; #if MDBX_PNL_PREALLOC_FOR_RADIXSORT size >>= 1; #endif /* MDBX_PNL_PREALLOC_FOR_RADIXSORT */ @@ -2454,9 +2454,9 @@ __hot static size_t pnl_merge(MDBX_PNL dst, const MDBX_PNL src) { const size_t src_len = MDBX_PNL_GETSIZE(src); const size_t dst_len = MDBX_PNL_GETSIZE(dst); size_t total = dst_len; + assert(MDBX_PNL_ALLOCLEN(dst) >= total); if (likely(src_len > 0)) { total += src_len; - assert(MDBX_PNL_ALLOCLEN(dst) >= total); if (!MDBX_DEBUG && total < (MDBX_HAVE_CMOV ? 21 : 12)) goto avoid_call_libc_for_short_cases; if (dst_len == 0 || @@ -2572,9 +2572,19 @@ __hot __noinline static size_t pnl_search_nochk(const MDBX_PNL pnl, static __inline size_t pnl_search(const MDBX_PNL pnl, pgno_t pgno, size_t limit) { assert(pnl_check_allocated(pnl, limit)); + if (MDBX_HAVE_CMOV) { + /* cmov-ускоренный бинарный поиск может читать (но не использовать) один + * элемент за концом данных, этот элемент в пределах выделенного участка + * памяти, но не инициализирован. */ + VALGRIND_MAKE_MEM_DEFINED(MDBX_PNL_END(pnl), sizeof(pgno_t)); + } assert(pgno < limit); (void)limit; - return pnl_search_nochk(pnl, pgno); + size_t n = pnl_search_nochk(pnl, pgno); + if (MDBX_HAVE_CMOV) { + VALGRIND_MAKE_MEM_UNDEFINED(MDBX_PNL_END(pnl), sizeof(pgno_t)); + } + return n; } static __inline size_t search_spilled(const MDBX_txn *txn, pgno_t pgno) { @@ -3788,7 +3798,8 @@ static MDBX_page *page_malloc(MDBX_txn *txn, size_t num) { if (likely(num == 1 && np)) { eASSERT(env, env->me_dp_reserve_len > 0); MDBX_ASAN_UNPOISON_MEMORY_REGION(np, size); - VALGRIND_MEMPOOL_ALLOC(env, np, size); + VALGRIND_MEMPOOL_ALLOC(env, ptr_disp(np, -(ptrdiff_t)sizeof(size_t)), + size + sizeof(size_t)); VALGRIND_MAKE_MEM_DEFINED(&mp_next(np), sizeof(MDBX_page *)); env->me_dp_reserve = mp_next(np); env->me_dp_reserve_len -= 1; @@ -3832,7 +3843,7 @@ static void dpage_free(MDBX_env *env, MDBX_page *dp, size_t npages) { MDBX_ASAN_POISON_MEMORY_REGION(dp, env->me_psize); MDBX_ASAN_UNPOISON_MEMORY_REGION(&mp_next(dp), sizeof(MDBX_page *)); mp_next(dp) = env->me_dp_reserve; - VALGRIND_MEMPOOL_FREE(env, dp); + VALGRIND_MEMPOOL_FREE(env, ptr_disp(dp, -(ptrdiff_t)sizeof(size_t))); env->me_dp_reserve = dp; env->me_dp_reserve_len += 1; } else { @@ -15294,7 +15305,6 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) { VALGRIND_MAKE_MEM_DEFINED(&mp_next(dp), sizeof(MDBX_page *)); env->me_dp_reserve = mp_next(dp); void *const ptr = ptr_disp(dp, -(ptrdiff_t)sizeof(size_t)); - VALGRIND_MEMPOOL_FREE(env, ptr); osal_free(ptr); } VALGRIND_DESTROY_MEMPOOL(env); @@ -24669,7 +24679,6 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option, VALGRIND_MAKE_MEM_DEFINED(&mp_next(dp), sizeof(MDBX_page *)); env->me_dp_reserve = mp_next(dp); void *const ptr = ptr_disp(dp, -(ptrdiff_t)sizeof(size_t)); - VALGRIND_MEMPOOL_FREE(env, ptr); osal_free(ptr); env->me_dp_reserve_len -= 1; } diff --git a/test/valgrind_suppress.txt b/test/valgrind_suppress.txt index 3d0d1be4..5bc50077 100644 --- a/test/valgrind_suppress.txt +++ b/test/valgrind_suppress.txt @@ -38,6 +38,14 @@ ... fun:meta_sync* } +{ + msync-spill + Memcheck:Param + msync(start) + fun:msync + ... + fun:txn_spill* +} # memcmp() inside iov_write() as workaround for https://libmdbx.dqdkfa.ru/dead-github/issues/269 {