From: Radosław Zarzyński Date: Fri, 25 Aug 2023 19:01:07 +0000 (+0200) Subject: mempool: switch from thread local storage to cpu local storage X-Git-Tag: v19.3.0~407^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=111cee4f6cfcced799bd9876684b1d59fb4487bc;p=ceph.git mempool: switch from thread local storage to cpu local storage https://github.com/ceph/ceph/pull/53130#issuecomment-1692353725 Signed-off-by: Radosław Zarzyński --- diff --git a/src/common/mempool.cc b/src/common/mempool.cc index 79354f708216..a1b83c2e9f86 100644 --- a/src/common/mempool.cc +++ b/src/common/mempool.cc @@ -15,9 +15,11 @@ #include "include/mempool.h" #include "include/demangle.h" +#ifndef _GNU_SOURCE // Thread local variables should save index, not &shard[index], // because shard[] is defined in the class static thread_local size_t thread_shard_index = mempool::num_shards; +#endif // default to debug_mode off bool mempool::debug_mode = false; @@ -95,9 +97,21 @@ size_t mempool::pool_t::allocated_items() const void mempool::pool_t::adjust_count(ssize_t items, ssize_t bytes) { - thread_shard_index = (thread_shard_index == num_shards) ? pick_a_shard_int() : thread_shard_index; - shard[thread_shard_index].items += items; - shard[thread_shard_index].bytes += bytes; +#ifndef _GNU_SOURCE + // fallback for lack of sched_getcpu() + const size_t shard_index = []() { + if (thread_shard_index == num_shards) { + thread_shard_index = pick_a_shard_int(); + } + return thread_shard_index; + }(); +#else + // the expected path: we alway pick the shard for a cpu core + // a thread is executing on. + const size_t shard_index = pick_a_shard_int(); +#endif + shard[shard_index].items += items; + shard[shard_index].bytes += bytes; } void mempool::pool_t::get_stats( diff --git a/src/include/mempool.h b/src/include/mempool.h index 076c62afe191..23d7e80dc9eb 100644 --- a/src/include/mempool.h +++ b/src/include/mempool.h @@ -26,6 +26,10 @@ #include #include +#ifdef _GNU_SOURCE +# include +#endif + #include "common/Formatter.h" #include "common/ceph_atomic.h" #include "include/ceph_assert.h" @@ -265,11 +269,21 @@ public: void adjust_count(ssize_t items, ssize_t bytes); static size_t pick_a_shard_int() { +#ifndef _GNU_SOURCE // Dirt cheap, see: // https://fossies.org/dox/glibc-2.32/pthread__self_8c_source.html size_t me = (size_t)pthread_self(); size_t i = (me >> CEPH_PAGE_SHIFT) & ((1 << num_shard_bits) - 1); return i; +#else + // a thread local storage is actually just an approximation; + // what we truly want is a _cpu local storage_. + // + // on the architectures we care about sched_getcpu() is + // a syscall-handled-in-userspace (vdso!). it grabs the cpu + // id kernel exposes to a task on context switch. + return sched_getcpu() & ((1 << num_shard_bits) - 1); +#endif } shard_t* pick_a_shard() {