Skip to content

Commit 55376aa

Browse files
authored
Move key_global into RemoteAllocator (#608)
There was a mis-compilation in a Verona configuration that lead to two instances of key_global existing. This change moves it inside a struct that seems to fix the issue. The rest of the changes are limiting the use of key_global as both RemoteCache and RemoteAllocator must use the same configuration, so there is no need to take the key_global as a parameter.
1 parent 7b3a2b3 commit 55376aa

File tree

7 files changed

+42
-37
lines changed

7 files changed

+42
-37
lines changed

src/snmalloc/backend/globalconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ namespace snmalloc
108108
LocalEntropy entropy;
109109
entropy.init<Pal>();
110110
// Initialise key for remote deallocation lists
111-
key_global = FreeListKey(entropy.get_free_list_key());
111+
RemoteAllocator::key_global = FreeListKey(entropy.get_free_list_key());
112112

113113
// Need to randomise pagemap location. If requested and not a
114114
// StrictProvenance architecture, randomize its table's location within a

src/snmalloc/mem/corealloc.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ namespace snmalloc
462462
}
463463
};
464464

465-
return !(message_queue().can_dequeue(key_global, domesticate));
465+
return !(message_queue().can_dequeue(domesticate));
466466
}
467467

468468
/**
@@ -502,11 +502,11 @@ namespace snmalloc
502502
[](freelist::QueuePtr p) SNMALLOC_FAST_PATH_LAMBDA {
503503
return freelist::HeadPtr::unsafe_from(p.unsafe_ptr());
504504
};
505-
message_queue().dequeue(key_global, domesticate_first, domesticate, cb);
505+
message_queue().dequeue(domesticate_first, domesticate, cb);
506506
}
507507
else
508508
{
509-
message_queue().dequeue(key_global, domesticate, domesticate, cb);
509+
message_queue().dequeue(domesticate, domesticate, cb);
510510
}
511511

512512
if (need_post)
@@ -548,7 +548,7 @@ namespace snmalloc
548548
need_post = true;
549549
attached_cache->remote_dealloc_cache
550550
.template dealloc<sizeof(CoreAllocator)>(
551-
entry.get_remote()->trunc_id(), p.as_void(), key_global);
551+
entry.get_remote()->trunc_id(), p.as_void());
552552
}
553553
}
554554

@@ -643,7 +643,7 @@ namespace snmalloc
643643
bool sent_something =
644644
attached_cache->remote_dealloc_cache
645645
.post<sizeof(CoreAllocator), Config>(
646-
backend_state_ptr(), public_state()->trunc_id(), key_global);
646+
backend_state_ptr(), public_state()->trunc_id());
647647

648648
return sent_something;
649649
}
@@ -838,7 +838,8 @@ namespace snmalloc
838838
while (p_tame != nullptr)
839839
{
840840
bool need_post = true; // Always going to post, so ignore.
841-
auto n_tame = p_tame->atomic_read_next(key_global, domesticate);
841+
auto n_tame =
842+
p_tame->atomic_read_next(RemoteAllocator::key_global, domesticate);
842843
const PagemapEntry& entry =
843844
Config::Backend::get_metaentry(snmalloc::address_cast(p_tame));
844845
handle_dealloc_remote(entry, p_tame.as_void(), need_post);
@@ -891,7 +892,7 @@ namespace snmalloc
891892
c->remote_allocator = public_state();
892893

893894
// Set up remote cache.
894-
c->remote_dealloc_cache.init(entropy.get_free_list_key());
895+
c->remote_dealloc_cache.init();
895896
}
896897

897898
/**

src/snmalloc/mem/localalloc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ namespace snmalloc
279279
const PagemapEntry& entry =
280280
Config::Backend::template get_metaentry(address_cast(p));
281281
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
282-
entry.get_remote()->trunc_id(), p, key_global);
282+
entry.get_remote()->trunc_id(), p);
283283
post_remote_cache();
284284
return;
285285
}
@@ -670,7 +670,7 @@ namespace snmalloc
670670
if (local_cache.remote_dealloc_cache.reserve_space(entry))
671671
{
672672
local_cache.remote_dealloc_cache.template dealloc<sizeof(CoreAlloc)>(
673-
remote->trunc_id(), p_tame, key_global);
673+
remote->trunc_id(), p_tame);
674674
# ifdef SNMALLOC_TRACING
675675
message<1024>(
676676
"Remote dealloc fast {} ({})", p_raw, alloc_size(p_raw));

src/snmalloc/mem/localcache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace snmalloc
8686
}
8787

8888
return remote_dealloc_cache.post<allocator_size, Config>(
89-
local_state, remote_allocator->trunc_id(), key_global);
89+
local_state, remote_allocator->trunc_id());
9090
}
9191

9292
template<

src/snmalloc/mem/remoteallocator.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010

1111
namespace snmalloc
1212
{
13-
/**
14-
* Global key for all remote lists.
15-
*/
16-
inline static FreeListKey key_global(0xdeadbeef, 0xbeefdead, 0xdeadbeef);
17-
1813
/**
1914
*
2015
* A RemoteAllocator is the message queue of freed objects. It exposes a MPSC
@@ -44,6 +39,16 @@ namespace snmalloc
4439
*/
4540
struct alignas(REMOTE_MIN_ALIGN) RemoteAllocator
4641
{
42+
/**
43+
* Global key for all remote lists.
44+
*
45+
* Note that we use a single key for all remote free lists and queues.
46+
* This is so that we do not have to recode next pointers when sending
47+
* segments, and look up specific keys based on destination. This is
48+
* potentially more performant, but could make it easier to guess the key.
49+
*/
50+
inline static FreeListKey key_global{0xdeadbeef, 0xbeefdead, 0xdeadbeef};
51+
4752
using alloc_id_t = address_t;
4853

4954
// Store the message queue on a separate cacheline. It is mutable data that
@@ -83,11 +88,10 @@ namespace snmalloc
8388
}
8489

8590
template<typename Domesticator_head>
86-
inline bool
87-
can_dequeue(const FreeListKey& key, Domesticator_head domesticate_head)
91+
inline bool can_dequeue(Domesticator_head domesticate_head)
8892
{
8993
return domesticate_head(front.load())
90-
->atomic_read_next(key, domesticate_head) == nullptr;
94+
->atomic_read_next(key_global, domesticate_head) == nullptr;
9195
}
9296

9397
/**
@@ -101,11 +105,10 @@ namespace snmalloc
101105
void enqueue(
102106
freelist::HeadPtr first,
103107
freelist::HeadPtr last,
104-
const FreeListKey& key,
105108
Domesticator_head domesticate_head)
106109
{
107110
invariant();
108-
freelist::Object::atomic_store_null(last, key);
111+
freelist::Object::atomic_store_null(last, key_global);
109112

110113
// Exchange needs to be acq_rel.
111114
// * It needs to be a release, so nullptr in next is visible.
@@ -116,7 +119,8 @@ namespace snmalloc
116119

117120
if (SNMALLOC_LIKELY(prev != nullptr))
118121
{
119-
freelist::Object::atomic_store_next(domesticate_head(prev), first, key);
122+
freelist::Object::atomic_store_next(
123+
domesticate_head(prev), first, key_global);
120124
return;
121125
}
122126

@@ -136,7 +140,6 @@ namespace snmalloc
136140
typename Domesticator_queue,
137141
typename Cb>
138142
void dequeue(
139-
const FreeListKey& key,
140143
Domesticator_head domesticate_head,
141144
Domesticator_queue domesticate_queue,
142145
Cb cb)
@@ -150,7 +153,8 @@ namespace snmalloc
150153

151154
while (address_cast(curr) != address_cast(b))
152155
{
153-
freelist::HeadPtr next = curr->atomic_read_next(key, domesticate_queue);
156+
freelist::HeadPtr next =
157+
curr->atomic_read_next(key_global, domesticate_queue);
154158
// We have observed a non-linearisable effect of the queue.
155159
// Just go back to allocating normally.
156160
if (SNMALLOC_UNLIKELY(next == nullptr))

src/snmalloc/mem/remotecache.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,23 @@ namespace snmalloc
6666
}
6767

6868
template<size_t allocator_size>
69-
SNMALLOC_FAST_PATH void dealloc(
70-
RemoteAllocator::alloc_id_t target_id,
71-
capptr::Alloc<void> p,
72-
const FreeListKey& key)
69+
SNMALLOC_FAST_PATH void
70+
dealloc(RemoteAllocator::alloc_id_t target_id, capptr::Alloc<void> p)
7371
{
7472
SNMALLOC_ASSERT(initialised);
7573
auto r = p.template as_reinterpret<freelist::Object::T<>>();
7674

77-
list[get_slot<allocator_size>(target_id, 0)].add(r, key);
75+
list[get_slot<allocator_size>(target_id, 0)].add(
76+
r, RemoteAllocator::key_global);
7877
}
7978

8079
template<size_t allocator_size, typename Config>
8180
bool post(
82-
typename Config::LocalState* local_state,
83-
RemoteAllocator::alloc_id_t id,
84-
const FreeListKey& key)
81+
typename Config::LocalState* local_state, RemoteAllocator::alloc_id_t id)
8582
{
83+
// Use same key as the remote allocator, so segments can be
84+
// posted to a remote allocator without reencoding.
85+
const auto& key = RemoteAllocator::key_global;
8686
SNMALLOC_ASSERT(initialised);
8787
size_t post_round = 0;
8888
bool sent_something = false;
@@ -118,11 +118,11 @@ namespace snmalloc
118118
auto domesticate_nop = [](freelist::QueuePtr p) {
119119
return freelist::HeadPtr::unsafe_from(p.unsafe_ptr());
120120
};
121-
remote->enqueue(first, last, key, domesticate_nop);
121+
remote->enqueue(first, last, domesticate_nop);
122122
}
123123
else
124124
{
125-
remote->enqueue(first, last, key, domesticate);
125+
remote->enqueue(first, last, domesticate);
126126
}
127127
sent_something = true;
128128
}
@@ -166,7 +166,7 @@ namespace snmalloc
166166
* Must be called before anything else to ensure actually initialised
167167
* not just zero init.
168168
*/
169-
void init(const FreeListKey& key)
169+
void init()
170170
{
171171
#ifndef NDEBUG
172172
initialised = true;
@@ -175,7 +175,7 @@ namespace snmalloc
175175
{
176176
// We do not need to initialise with a particular slab, so pass
177177
// a null address.
178-
l.init(0, key);
178+
l.init(0, RemoteAllocator::key_global);
179179
}
180180
capacity = REMOTE_CACHE;
181181
}

src/test/func/domestication/domestication.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ int main()
138138

139139
LocalEntropy entropy;
140140
entropy.init<DefaultPal>();
141-
key_global = FreeListKey(entropy.get_free_list_key());
141+
RemoteAllocator::key_global = FreeListKey(entropy.get_free_list_key());
142142

143143
auto alloc1 = new Alloc();
144144

0 commit comments

Comments
 (0)