Skip to content

Commit 111cee4

Browse files
rzarzynskicyx1231st
authored andcommitted
mempool: switch from thread local storage to cpu local storage
ceph#53130 (comment) Signed-off-by: Radosław Zarzyński <[email protected]>
1 parent 07614d5 commit 111cee4

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/common/mempool.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
#include "include/mempool.h"
1616
#include "include/demangle.h"
1717

18+
#ifndef _GNU_SOURCE
1819
// Thread local variables should save index, not &shard[index],
1920
// because shard[] is defined in the class
2021
static thread_local size_t thread_shard_index = mempool::num_shards;
22+
#endif
2123

2224
// default to debug_mode off
2325
bool mempool::debug_mode = false;
@@ -95,9 +97,21 @@ size_t mempool::pool_t::allocated_items() const
9597

9698
void mempool::pool_t::adjust_count(ssize_t items, ssize_t bytes)
9799
{
98-
thread_shard_index = (thread_shard_index == num_shards) ? pick_a_shard_int() : thread_shard_index;
99-
shard[thread_shard_index].items += items;
100-
shard[thread_shard_index].bytes += bytes;
100+
#ifndef _GNU_SOURCE
101+
// fallback for lack of sched_getcpu()
102+
const size_t shard_index = []() {
103+
if (thread_shard_index == num_shards) {
104+
thread_shard_index = pick_a_shard_int();
105+
}
106+
return thread_shard_index;
107+
}();
108+
#else
109+
// the expected path: we alway pick the shard for a cpu core
110+
// a thread is executing on.
111+
const size_t shard_index = pick_a_shard_int();
112+
#endif
113+
shard[shard_index].items += items;
114+
shard[shard_index].bytes += bytes;
101115
}
102116

103117
void mempool::pool_t::get_stats(

src/include/mempool.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include <boost/container/flat_set.hpp>
2727
#include <boost/container/flat_map.hpp>
2828

29+
#ifdef _GNU_SOURCE
30+
# include <sched.h>
31+
#endif
32+
2933
#include "common/Formatter.h"
3034
#include "common/ceph_atomic.h"
3135
#include "include/ceph_assert.h"
@@ -265,11 +269,21 @@ class pool_t {
265269
void adjust_count(ssize_t items, ssize_t bytes);
266270

267271
static size_t pick_a_shard_int() {
272+
#ifndef _GNU_SOURCE
268273
// Dirt cheap, see:
269274
// https://fossies.org/dox/glibc-2.32/pthread__self_8c_source.html
270275
size_t me = (size_t)pthread_self();
271276
size_t i = (me >> CEPH_PAGE_SHIFT) & ((1 << num_shard_bits) - 1);
272277
return i;
278+
#else
279+
// a thread local storage is actually just an approximation;
280+
// what we truly want is a _cpu local storage_.
281+
//
282+
// on the architectures we care about sched_getcpu() is
283+
// a syscall-handled-in-userspace (vdso!). it grabs the cpu
284+
// id kernel exposes to a task on context switch.
285+
return sched_getcpu() & ((1 << num_shard_bits) - 1);
286+
#endif
273287
}
274288

275289
shard_t* pick_a_shard() {

0 commit comments

Comments
 (0)