Skip to content

Commit 8cf6dbd

Browse files
authored
Merge pull request ceph#58986 from NitzanMordhai/wip-nitzan-crimson-op_gate-alianstore-multi-core
crimson: use gate per shard for AlienStore and OSD Reviewed-by: Matan Breizman <[email protected]> Reviewed-by: Yingxin Cheng <[email protected]>
2 parents e837655 + d14d87b commit 8cf6dbd

File tree

7 files changed

+108
-24
lines changed

7 files changed

+108
-24
lines changed

src/crimson/common/gated.h

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <seastar/core/gate.hh>
77
#include <seastar/core/future.hh>
88
#include <seastar/core/future-util.hh>
9+
#include <type_traits>
10+
#include <vector>
911

1012
#include "crimson/common/exception.h"
1113
#include "crimson/common/log.h"
@@ -15,15 +17,27 @@ namespace crimson::common {
1517

1618
class Gated {
1719
public:
20+
Gated() : sid(seastar::this_shard_id()) {}
21+
Gated(const seastar::shard_id sid) : sid(sid) {}
22+
Gated(const Gated&) = delete;
23+
Gated& operator=(const Gated&) = delete;
24+
Gated(Gated&&) = default;
25+
Gated& operator=(Gated&&) = delete;
26+
virtual ~Gated() = default;
27+
1828
static seastar::logger& gated_logger() {
1929
return crimson::get_logger(ceph_subsys_osd);
2030
}
31+
2132
template <typename Func, typename T>
2233
inline void dispatch_in_background(const char* what, T& who, Func&& func) {
23-
(void) dispatch(what, who, func);
34+
//ceph_assert(seastar::this_shard_id() == sid);
35+
(void) dispatch(what, who, std::forward<Func>(func));
2436
}
37+
2538
template <typename Func, typename T>
2639
inline seastar::future<> dispatch(const char* what, T& who, Func&& func) {
40+
//ceph_assert(seastar::this_shard_id() == sid);
2741
return seastar::with_gate(pending_dispatch, std::forward<Func>(func)
2842
).handle_exception([what, &who] (std::exception_ptr eptr) {
2943
if (*eptr.__cxa_exception_type() == typeid(system_shutdown_exception)) {
@@ -42,14 +56,81 @@ class Gated {
4256
});
4357
}
4458

59+
template <typename Func>
60+
auto simple_dispatch(const char* what, Func&& func) {
61+
//ceph_assert(seastar::this_shard_id() == sid);
62+
return seastar::with_gate(pending_dispatch, std::forward<Func>(func));
63+
}
64+
4565
seastar::future<> close() {
66+
ceph_assert(seastar::this_shard_id() == sid);
4667
return pending_dispatch.close();
4768
}
69+
4870
bool is_closed() const {
4971
return pending_dispatch.is_closed();
5072
}
73+
74+
seastar::shard_id get_shard_id() const {
75+
return sid;
76+
}
5177
private:
5278
seastar::gate pending_dispatch;
79+
const seastar::shard_id sid;
80+
};
81+
82+
// gate_per_shard is a class that provides a gate for each shard.
83+
// It was introduced to provide a way to have gate for each shard
84+
// in a seastar application since gates are not supposed to be shared
85+
// across shards. ( https://tracker.ceph.com/issues/64332 )
86+
class gate_per_shard {
87+
public:
88+
gate_per_shard() : gates(seastar::smp::count) {
89+
std::vector<seastar::future<>> futures;
90+
for (unsigned shard = 0; shard < seastar::smp::count; ++shard) {
91+
futures.push_back(seastar::smp::submit_to(shard, [this, shard] {
92+
gates[shard] = std::make_unique<Gated>();
93+
}));
94+
}
95+
seastar::when_all_succeed(futures.begin(), futures.end()).get();
96+
}
97+
//explicit gate_per_shard(size_t shard_count) : gates(shard_count) {}
98+
gate_per_shard(const gate_per_shard&) = delete;
99+
gate_per_shard& operator=(const gate_per_shard&) = delete;
100+
gate_per_shard(gate_per_shard&&) = default;
101+
gate_per_shard& operator=(gate_per_shard&&) = default;
102+
~gate_per_shard() = default;
103+
104+
template <typename Func, typename T>
105+
inline void dispatch_in_background(const char* what, T& who, Func&& func) {
106+
(void) dispatch(what, who, std::forward<Func>(func));
107+
}
108+
109+
template <typename Func, typename T>
110+
inline auto dispatch(const char* what, T& who, Func&& func) {
111+
return gates[seastar::this_shard_id()]->dispatch(what, who, std::forward<Func>(func));
112+
}
113+
114+
template <typename Func>
115+
auto simple_dispatch(const char* what, Func&& func) {
116+
return gates[seastar::this_shard_id()]->simple_dispatch(what, std::forward<Func>(func));
117+
}
118+
119+
bool is_closed() const {
120+
return gates[seastar::this_shard_id()]->is_closed();
121+
}
122+
123+
seastar::future<> close_all() {
124+
ceph_assert(gates.size() == seastar::smp::count);
125+
return seastar::parallel_for_each(gates.begin(), gates.end(), [] (std::unique_ptr<Gated>& gate_ptr) {
126+
return seastar::smp::submit_to(gate_ptr->get_shard_id(), [gate = gate_ptr.get()] {
127+
return gate->close();
128+
});
129+
});
130+
}
131+
132+
private:
133+
std::vector<std::unique_ptr<Gated>> gates;
53134
};
54135

55-
}// namespace crimson::common
136+
} // namespace crimson::common

src/crimson/net/io_handler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class IOHandler final : public ConnectionHandler {
255255
class shard_states_t {
256256
public:
257257
shard_states_t(seastar::shard_id _sid, io_state_t state)
258-
: sid{_sid}, io_state{state} {}
258+
: sid{_sid}, io_state{state}, gate{_sid} {}
259259

260260
seastar::shard_id get_shard_id() const {
261261
return sid;

src/crimson/os/alienstore/alien_store.cc

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ AlienStore::AlienStore(const std::string& type,
7575
const ConfigValues& values)
7676
: type(type),
7777
path{path},
78-
values(values)
78+
values(values),
79+
op_gates()
7980
{
8081
}
8182

@@ -142,12 +143,12 @@ AlienStore::exists(
142143
CollectionRef ch,
143144
const ghobject_t& oid)
144145
{
145-
return seastar::with_gate(op_gate, [=, this] {
146-
return tp->submit(ch->get_cid().hash_to_shard(tp->size()), [=, this] {
147-
auto c = static_cast<AlienCollection*>(ch.get());
148-
return store->exists(c->collection, oid);
146+
return op_gates.simple_dispatch("exists", [=, this] {
147+
return tp->submit(ch->get_cid().hash_to_shard(tp->size()), [=, this] {
148+
auto c = static_cast<AlienCollection*>(ch.get());
149+
return store->exists(c->collection, oid);
150+
});
149151
});
150-
});
151152
}
152153

153154
AlienStore::mount_ertr::future<> AlienStore::mount()
@@ -173,7 +174,7 @@ seastar::future<> AlienStore::umount()
173174
// not really started yet
174175
return seastar::now();
175176
}
176-
return op_gate.close().then([this] {
177+
return op_gates.close_all().then([this] {
177178
return tp->submit([this] {
178179
{
179180
std::lock_guard l(coll_map_lock);
@@ -183,10 +184,10 @@ seastar::future<> AlienStore::umount()
183184
coll_map.clear();
184185
}
185186
return store->umount();
187+
}).then([] (int r) {
188+
assert(r == 0);
189+
return seastar::now();
186190
});
187-
}).then([] (int r) {
188-
assert(r == 0);
189-
return seastar::now();
190191
});
191192
}
192193

@@ -477,7 +478,7 @@ seastar::future<> AlienStore::inject_data_error(const ghobject_t& o)
477478
{
478479
logger().debug("{}", __func__);
479480
assert(tp);
480-
return seastar::with_gate(op_gate, [=, this] {
481+
return op_gates.simple_dispatch("inject_data_error", [=, this] {
481482
return tp->submit([o, this] {
482483
return store->inject_data_error(o);
483484
});
@@ -488,8 +489,8 @@ seastar::future<> AlienStore::inject_mdata_error(const ghobject_t& o)
488489
{
489490
logger().debug("{}", __func__);
490491
assert(tp);
491-
return seastar::with_gate(op_gate, [=, this] {
492-
return tp->submit([=, this] {
492+
return op_gates.simple_dispatch("inject_mdata_error", [=, this] {
493+
return tp->submit([o, this] {
493494
return store->inject_mdata_error(o);
494495
});
495496
});
@@ -500,7 +501,7 @@ seastar::future<> AlienStore::write_meta(const std::string& key,
500501
{
501502
logger().debug("{}", __func__);
502503
assert(tp);
503-
return seastar::with_gate(op_gate, [=, this] {
504+
return op_gates.simple_dispatch("write_meta", [=, this] {
504505
return tp->submit([=, this] {
505506
return store->write_meta(key, value);
506507
}).then([] (int r) {
@@ -515,8 +516,8 @@ AlienStore::read_meta(const std::string& key)
515516
{
516517
logger().debug("{}", __func__);
517518
assert(tp);
518-
return seastar::with_gate(op_gate, [this, key] {
519-
return tp->submit([this, key] {
519+
return op_gates.simple_dispatch("read_meta", [this, key] {
520+
return tp->submit([key, this] {
520521
std::string value;
521522
int r = store->read_meta(key, &value);
522523
if (r > 0) {

src/crimson/os/alienstore/alien_store.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "os/ObjectStore.h"
1111
#include "osd/osd_types.h"
1212

13+
#include "crimson/common/gated.h"
1314
#include "crimson/os/alienstore/thread_pool.h"
1415
#include "crimson/os/futurized_collection.h"
1516
#include "crimson/os/futurized_store.h"
@@ -111,9 +112,10 @@ class AlienStore final : public FuturizedStore,
111112
}
112113

113114
private:
115+
114116
template <class... Args>
115117
auto do_with_op_gate(Args&&... args) const {
116-
return seastar::with_gate(op_gate,
118+
return op_gates.simple_dispatch("AlienStore::do_with_op_gate",
117119
// perfect forwarding in lambda's closure isn't available in C++17
118120
// using tuple as workaround; see: https://stackoverflow.com/a/49902823
119121
[args = std::make_tuple(std::forward<Args>(args)...)] () mutable {
@@ -130,7 +132,7 @@ class AlienStore final : public FuturizedStore,
130132
uint64_t used_bytes = 0;
131133
std::unique_ptr<ObjectStore> store;
132134
std::unique_ptr<CephContext> cct;
133-
mutable seastar::gate op_gate;
135+
mutable crimson::common::gate_per_shard op_gates;
134136

135137
/**
136138
* coll_map

src/crimson/osd/osd.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ seastar::future<> OSD::stop()
718718
DEBUG("prepared to stop");
719719
public_msgr->stop();
720720
cluster_msgr->stop();
721-
auto gate_close_fut = gate.close();
721+
auto gate_close_fut = gate.close_all();
722722
return asok->stop().then([this] {
723723
return heartbeat->stop();
724724
}).then([this] {

src/crimson/osd/osd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ class OSD final : public crimson::net::Dispatcher,
232232
Ref<MOSDPGUpdateLogMissingReply> m);
233233

234234
private:
235-
crimson::common::Gated gate;
235+
crimson::common::gate_per_shard gate;
236236

237237
seastar::promise<> stop_acked;
238238
void got_stop_ack() {

src/seastar

0 commit comments

Comments
 (0)