From: Yingxin Cheng Date: Mon, 22 Apr 2024 07:29:28 +0000 (+0800) Subject: crimson/osd/osd_operation: introduce PhasedOperationT::enter_stage_sync() X-Git-Tag: v19.1.1~236^2~5 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=f1bc9f9ac5ca133cfb00b7d510dc3d26d295a758;p=ceph.git crimson/osd/osd_operation: introduce PhasedOperationT::enter_stage_sync() Signed-off-by: Yingxin Cheng (cherry picked from commit 22847658944408446b1acbaa3be80e2aa99df5c6) --- diff --git a/src/crimson/common/operation.h b/src/crimson/common/operation.h index 938db0c87c8ee..1cdc672805fbf 100644 --- a/src/crimson/common/operation.h +++ b/src/crimson/common/operation.h @@ -502,15 +502,43 @@ class PipelineHandle { } template - seastar::future<> - do_enter(T &stage, typename T::BlockingEvent::template Trigger&& t) { - auto fut = t.maybe_record_blocking(stage.enter(t), stage); - return std::move(fut).then( - [this, t=std::move(t)](auto &&barrier_ref) mutable { + std::optional> + do_enter_maybe_sync(T &stage, typename T::BlockingEvent::template Trigger&& t) { + if constexpr (!T::is_enter_sync) { + auto fut = t.maybe_record_blocking(stage.enter(t), stage); + return std::move(fut).then( + [this, t=std::move(t)](auto &&barrier_ref) { + exit(); + barrier = std::move(barrier_ref); + return seastar::now(); + }); + } else { + auto barrier_ref = stage.enter(t); exit(); barrier = std::move(barrier_ref); - return seastar::now(); - }); + return std::nullopt; + } + } + + template + std::optional> + enter_maybe_sync(T &stage, typename T::BlockingEvent::template Trigger&& t) { + assert(stage.core == seastar::this_shard_id()); + auto wait_fut = wait_barrier(); + if (wait_fut.has_value()) { + return wait_fut.value( + ).then([this, &stage, t=std::move(t)]() mutable { + auto ret = do_enter_maybe_sync(stage, std::move(t)); + if constexpr (!T::is_enter_sync) { + return std::move(ret.value()); + } else { + assert(ret == std::nullopt); + return seastar::now(); + } + }); + } else { + return do_enter_maybe_sync(stage, std::move(t)); + } } public: @@ -530,18 +558,29 @@ public: template seastar::future<> enter(T &stage, typename T::BlockingEvent::template Trigger&& t) { - assert(stage.core == seastar::this_shard_id()); - auto wait_fut = wait_barrier(); - if (wait_fut.has_value()) { - return wait_fut.value( - ).then([this, &stage, t=std::move(t)]() mutable { - return do_enter(stage, std::move(t)); - }); + auto ret = enter_maybe_sync(stage, std::move(t)); + if (ret.has_value()) { + return std::move(ret.value()); } else { - return do_enter(stage, std::move(t)); + return seastar::now(); } } + /** + * Synchronously leaves the previous stage and enters the next stage. + * Required for the use case which needs ordering upon entering an + * ordered concurrent phase. + */ + template + void + enter_sync(T &stage, typename T::BlockingEvent::template Trigger&& t) { + static_assert(T::is_enter_sync); + auto ret = enter_maybe_sync(stage, std::move(t)); + // Expect that barrier->wait() (leaving the previous stage) + // also returns nullopt, see enter_maybe_sync() above + ceph_assert(!ret.has_value()); + } + /** * Completes pending exit barrier without entering a new one. */ @@ -607,6 +646,8 @@ class OrderedExclusivePhaseT : public PipelineStageIT { } public: + static constexpr bool is_enter_sync = false; + template seastar::future enter(TriggerT& t) { waiting++; @@ -709,10 +750,11 @@ private: }; public: + static constexpr bool is_enter_sync = true; + template - seastar::future enter(TriggerT& t) { - return seastar::make_ready_future( - new ExitBarrier{*this, mutex.lock(), t}); + PipelineExitBarrierI::Ref enter(TriggerT& t) { + return std::make_unique>(*this, mutex.lock(), t); } private: @@ -742,10 +784,11 @@ class UnorderedStageT : public PipelineStageIT { }; public: - template - seastar::future enter(IgnoreArgs&&...) { - return seastar::make_ready_future( - new ExitBarrier); + static constexpr bool is_enter_sync = true; + + template + PipelineExitBarrierI::Ref enter(TriggerT&) { + return std::make_unique(); } }; diff --git a/src/crimson/osd/osd_operation.h b/src/crimson/osd/osd_operation.h index 6c420f2cc2f96..1064a5c8e03e1 100644 --- a/src/crimson/osd/osd_operation.h +++ b/src/crimson/osd/osd_operation.h @@ -153,11 +153,15 @@ protected: get_event().trigger(*that(), std::forward(args)...); } + template + typename BlockingEventT::template Trigger + get_trigger() { + return {get_event(), *that()}; + } + template auto with_blocking_event(F&& f) { - auto ret = std::forward(f)(typename BlockingEventT::template Trigger{ - get_event(), *that() - }); + auto ret = std::forward(f)(get_trigger()); if constexpr (std::is_same_v) { return ret; } else { @@ -196,6 +200,12 @@ protected: }); } + template + void enter_stage_sync(StageT& stage) { + that()->get_handle().template enter_sync( + stage, this->template get_trigger()); + } + template friend class crimson::os::seastore::OperationProxyT;