Skip to content

Commit ee7c187

Browse files
authored
Merge pull request ceph#58766 from athanatos/sjust/wip-66294-collection-race
crimson: access coll_map under alien tp with a lock Reviewed-by: Yingxin Cheng <[email protected]> Reviewed-by: Matan Breizman <[email protected]>
2 parents d812176 + 8389471 commit ee7c187

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

src/crimson/os/alienstore/alien_store.cc

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,12 @@ seastar::future<> AlienStore::stop()
128128
return seastar::now();
129129
}
130130
return tp->submit([this] {
131-
for (auto [cid, ch]: coll_map) {
132-
static_cast<AlienCollection*>(ch.get())->collection.reset();
131+
{
132+
std::lock_guard l(coll_map_lock);
133+
for (auto [cid, ch]: coll_map) {
134+
static_cast<AlienCollection*>(ch.get())->collection.reset();
135+
}
136+
coll_map.clear();
133137
}
134138
store.reset();
135139
cct.reset();
@@ -233,48 +237,22 @@ seastar::future<CollectionRef> AlienStore::create_new_collection(const coll_t& c
233237
logger().debug("{}", __func__);
234238
assert(tp);
235239
return tp->submit([this, cid] {
236-
return store->create_new_collection(cid);
237-
}).then([this, cid] (ObjectStore::CollectionHandle c) {
238-
CollectionRef ch;
239-
auto cp = coll_map.find(c->cid);
240-
if (cp == coll_map.end()) {
241-
ch = new AlienCollection(c);
242-
coll_map[c->cid] = ch;
243-
} else {
244-
ch = cp->second;
245-
auto ach = static_cast<AlienCollection*>(ch.get());
246-
if (ach->collection != c) {
247-
ach->collection = c;
248-
}
249-
}
250-
return seastar::make_ready_future<CollectionRef>(ch);
240+
ObjectStore::CollectionHandle c = store->create_new_collection(cid);
241+
return get_alien_coll_ref(std::move(c));
251242
});
252-
253243
}
254244

255245
seastar::future<CollectionRef> AlienStore::open_collection(const coll_t& cid)
256246
{
257247
logger().debug("{}", __func__);
258248
assert(tp);
259249
return tp->submit([this, cid] {
260-
return store->open_collection(cid);
261-
}).then([this] (ObjectStore::CollectionHandle c) {
250+
ObjectStore::CollectionHandle c = store->open_collection(cid);
262251
if (!c) {
263-
return seastar::make_ready_future<CollectionRef>();
264-
}
265-
CollectionRef ch;
266-
auto cp = coll_map.find(c->cid);
267-
if (cp == coll_map.end()){
268-
ch = new AlienCollection(c);
269-
coll_map[c->cid] = ch;
252+
return CollectionRef{};
270253
} else {
271-
ch = cp->second;
272-
auto ach = static_cast<AlienCollection*>(ch.get());
273-
if (ach->collection != c){
274-
ach->collection = c;
275-
}
254+
return get_alien_coll_ref(std::move(c));
276255
}
277-
return seastar::make_ready_future<CollectionRef>(ch);
278256
});
279257
}
280258

@@ -657,4 +635,21 @@ AlienStore::read_errorator::future<std::map<uint64_t, uint64_t>> AlienStore::fie
657635
});
658636
}
659637

638+
CollectionRef AlienStore::get_alien_coll_ref(ObjectStore::CollectionHandle c) {
639+
std::lock_guard l(coll_map_lock);
640+
CollectionRef ch;
641+
auto cp = coll_map.find(c->cid);
642+
if (cp == coll_map.end()) {
643+
ch = new AlienCollection(c);
644+
coll_map[c->cid] = ch;
645+
} else {
646+
ch = cp->second;
647+
auto ach = static_cast<AlienCollection*>(ch.get());
648+
if (ach->collection != c) {
649+
ach->collection = c;
650+
}
651+
}
652+
return ch;
653+
}
654+
660655
}

src/crimson/os/alienstore/alien_store.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,29 @@ class AlienStore final : public FuturizedStore,
131131
std::unique_ptr<ObjectStore> store;
132132
std::unique_ptr<CephContext> cct;
133133
mutable seastar::gate op_gate;
134+
135+
/**
136+
* coll_map
137+
*
138+
* Contains a reference to every CollectionRef returned to the upper layer.
139+
* It's important that ObjectStore::CollectionHandle instances (in particular,
140+
* those from BlueStore) not be released from seastar reactor threads.
141+
* Keeping a reference here and breaking the
142+
* CollectionRef->ObjectStore::CollectionHandle links in AlienStore::stop()
143+
* ensures that all CollectionHandle's are released in the alien thread pool.
144+
*
145+
* Long term, we probably want to drop this map. To do that two things need
146+
* to happen:
147+
* 1. ~AlienCollection() needs to submit the ObjectStore::CollectionHandle
148+
* instance to the alien thread pool to be released.
149+
* 2. OSD shutdown needs to *guarantee* that all outstanding CollectionRefs
150+
* are released before unmounting and stopping the store.
151+
*
152+
* coll_map is accessed exclusively from alien threadpool threads under the
153+
* coll_map_lock.
154+
*/
155+
std::mutex coll_map_lock;
134156
std::unordered_map<coll_t, CollectionRef> coll_map;
157+
CollectionRef get_alien_coll_ref(ObjectStore::CollectionHandle c);
135158
};
136159
}

0 commit comments

Comments
 (0)