From f39044124ec0a524ad0dc16aa2bb4a5f701ebeb3 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Sat, 20 Jul 2019 16:10:15 +0300 Subject: [PATCH] mdbx: clarify/rework invalidate_mmap_noncoherent_cache() for MIPS. Change-Id: I70c279c2ba67191c7cb93cd8875082eb9c8e58b7 --- src/mdbx.c | 16 +++++++++++++--- src/osal.h | 37 +++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/mdbx.c b/src/mdbx.c index 3bae1077..aff16a4b 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -4639,6 +4639,9 @@ static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep) { mdbx_debug("Write error: %s", mdbx_strerror(rc)); return rc; } +#if MDBX_CPU_CACHE_MMAP_NONCOHERENT == 1 + mdbx_invalidate_mmap_noncoherent_cache(env->me_map + wpos, wsize); +#endif n = 0; } if (i > pagecount) @@ -4654,7 +4657,13 @@ static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep) { n++; } - mdbx_invalidate_cache(env->me_map, pgno2bytes(env, txn->mt_next_pgno)); +#if MDBX_CPU_CACHE_MMAP_NONCOHERENT > 1 + /* Linux kernels older than version 2.6.11 ignore the addr and nbytes + * arguments, making this function fairly expensive. Therefore, the whole + * cache is always flushed. */ + mdbx_invalidate_mmap_noncoherent_cache(env->me_map, + pgno2bytes(env, txn->mt_next_pgno)); +#endif for (i = keep; ++i <= pagecount;) { dp = dl[i].ptr; @@ -5524,7 +5533,7 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, (uint8_t *)target - env->me_map); goto fail; } - mdbx_invalidate_cache(target, sizeof(MDBX_meta)); + mdbx_invalidate_mmap_noncoherent_cache(target, sizeof(MDBX_meta)); } /* LY: step#3 - sync meta-pages. */ @@ -6269,7 +6278,8 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) { if (err) return err; - mdbx_invalidate_cache(env->me_map, pgno2bytes(env, NUM_METAS)); + mdbx_invalidate_mmap_noncoherent_cache(env->me_map, + pgno2bytes(env, NUM_METAS)); mdbx_ensure(env, undo_txnid == mdbx_meta_txnid_fluid(env, head)); mdbx_ensure(env, 0 == mdbx_meta_eq_mask(env)); continue; diff --git a/src/osal.h b/src/osal.h index ee5f1a05..3a9b0d69 100644 --- a/src/osal.h +++ b/src/osal.h @@ -407,28 +407,41 @@ static __inline void mdbx_memory_barrier(void) { #define mdbx_coherent_barrier() mdbx_memory_barrier() #endif -#if defined(__mips) || defined(__mips__) || defined(__mips64) || \ - defined(__mips64) || defined(_M_MRX000) || defined(_MIPS_) -/* Only MIPS has explicit cache control */ +#if __has_include() +#include +#elif defined(__mips) || defined(__mips__) || defined(__mips64) || \ + defined(__mips64__) || defined(_M_MRX000) || defined(_MIPS_) || \ + defined(__MWERKS__) || defined(__sgi) +/* MIPS should have explicit cache control */ #include #endif -static __inline void mdbx_invalidate_cache(void *addr, size_t nbytes) { - mdbx_coherent_barrier(); +#ifndef MDBX_CPU_CACHE_MMAP_NONCOHERENT #if defined(__mips) || defined(__mips__) || defined(__mips64) || \ - defined(__mips64) || defined(_M_MRX000) || defined(_MIPS_) -#if defined(DCACHE) + defined(__mips64__) || defined(_M_MRX000) || defined(_MIPS_) || \ + defined(__MWERKS__) || defined(__sgi) +/* MIPS has cache coherency issues. */ +#define MDBX_CPU_CACHE_MMAP_NONCOHERENT 1 +#else +/* LY: assume no relevant mmap/dcache issues. */ +#define MDBX_CPU_CACHE_MMAP_NONCOHERENT 0 +#endif +#endif /* ndef MDBX_CPU_CACHE_MMAP_NONCOHERENT */ + +static __inline void mdbx_invalidate_mmap_noncoherent_cache(void *addr, + size_t nbytes) { +#if MDBX_CPU_CACHE_MMAP_NONCOHERENT +#ifdef DCACHE /* MIPS has cache coherency issues. * Note: for any nbytes >= on-chip cache size, entire is flushed. */ cacheflush(addr, nbytes, DCACHE); #else -#error "Sorry, cacheflush() for MIPS not implemented" -#endif /* __mips__ */ -#else - /* LY: assume no relevant mmap/dcache issues. */ +#error "Oops, cacheflush() not available" +#endif /* DCACHE */ +#else /* MDBX_CPU_CACHE_MMAP_NONCOHERENT */ (void)addr; (void)nbytes; -#endif +#endif /* MDBX_CPU_CACHE_MMAP_NONCOHERENT */ } /*----------------------------------------------------------------------------*/