From b344e70e837e3dfce5ae54d0d0dfeb672b61ed26 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Tue, 28 Sep 2021 18:46:25 -0700 Subject: [PATCH] crimson/os/seastore/transaction_manager: limit callers to reserve_projected_usage Adds an exclusive stage for obtaining projected usage as well as an unordered one for submitting ool writes. This should allow for a straightforward wait-list when io is blocked while still allowing concurrent submission of ool writes otherwise. Fixes: https://tracker.ceph.com/issues/52698 Signed-off-by: Samuel Just --- src/crimson/os/seastore/ordering_handle.h | 6 ++++ .../os/seastore/transaction_manager.cc | 35 +++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/crimson/os/seastore/ordering_handle.h b/src/crimson/os/seastore/ordering_handle.h index 6e519114ca6de..6bcfcfb7454c6 100644 --- a/src/crimson/os/seastore/ordering_handle.h +++ b/src/crimson/os/seastore/ordering_handle.h @@ -82,6 +82,12 @@ inline OrderingHandle get_dummy_ordering_handle() { } struct WritePipeline { + OrderedExclusivePhase reserve_projected_usage{ + "WritePipeline::reserve_projected_usage" + }; + UnorderedStage ool_writes{ + "UnorderedStage::ool_writes_stage" + }; OrderedExclusivePhase prepare{ "WritePipeline::prepare_phase" }; diff --git a/src/crimson/os/seastore/transaction_manager.cc b/src/crimson/os/seastore/transaction_manager.cc index 05df59ae0e1ea..d202b934463b5 100644 --- a/src/crimson/os/seastore/transaction_manager.cc +++ b/src/crimson/os/seastore/transaction_manager.cc @@ -224,15 +224,19 @@ TransactionManager::submit_transaction( Transaction &t) { LOG_PREFIX(TransactionManager::submit_transaction); - size_t projected_usage = t.get_allocation_size(); - DEBUGT("waiting for projected_usage: {}", t, projected_usage); return trans_intr::make_interruptible( - segment_cleaner->reserve_projected_usage(projected_usage) - ).then_interruptible([this, &t] { - return submit_transaction_direct(t); - }).finally([this, FNAME, projected_usage, &t] { - DEBUGT("releasing projected_usage: {}", t, projected_usage); - segment_cleaner->release_projected_usage(projected_usage); + t.get_handle().enter(write_pipeline.reserve_projected_usage) + ).then_interruptible([this, FNAME, &t] { + size_t projected_usage = t.get_allocation_size(); + DEBUGT("waiting for projected_usage: {}", t, projected_usage); + return trans_intr::make_interruptible( + segment_cleaner->reserve_projected_usage(projected_usage) + ).then_interruptible([this, &t] { + return submit_transaction_direct(t); + }).finally([this, FNAME, projected_usage, &t] { + DEBUGT("releasing projected_usage: {}", t, projected_usage); + segment_cleaner->release_projected_usage(projected_usage); + }); }); } @@ -243,12 +247,15 @@ TransactionManager::submit_transaction_direct( LOG_PREFIX(TransactionManager::submit_transaction_direct); DEBUGT("about to alloc delayed extents", tref); - return epm->delayed_alloc_or_ool_write(tref) - .handle_error_interruptible( - crimson::ct_error::input_output_error::pass_further(), - crimson::ct_error::assert_all("invalid error") - ).si_then([&tref, this] { - LOG_PREFIX(TransactionManager::submit_transaction_direct); + return trans_intr::make_interruptible( + tref.get_handle().enter(write_pipeline.ool_writes) + ).then_interruptible([this, &tref] { + return epm->delayed_alloc_or_ool_write(tref + ).handle_error_interruptible( + crimson::ct_error::input_output_error::pass_further(), + crimson::ct_error::assert_all("invalid error") + ); + }).si_then([this, FNAME, &tref] { DEBUGT("about to prepare", tref); return tref.get_handle().enter(write_pipeline.prepare); }).si_then([this, FNAME, &tref]() mutable -- 2.39.5