From: Zhang Song Date: Thu, 7 Aug 2025 11:22:58 +0000 (+0800) Subject: crimson/os/seastore/EPM/BackgroundProcess: add promote and demote process X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b4f7d04200b54c2fa5bd6e5d627d022e3db14014;p=ceph-ci.git crimson/os/seastore/EPM/BackgroundProcess: add promote and demote process Signed-off-by: Zhang Song Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/async_cleaner.h b/src/crimson/os/seastore/async_cleaner.h index 7c54d7d33ae..df978020be9 100644 --- a/src/crimson/os/seastore/async_cleaner.h +++ b/src/crimson/os/seastore/async_cleaner.h @@ -453,6 +453,7 @@ struct BackgroundListener { virtual ~BackgroundListener() = default; virtual void maybe_wake_background() = 0; virtual void maybe_wake_blocked_io() = 0; + virtual void maybe_wake_promote() = 0; virtual state_t get_state() const = 0; bool is_ready() const { diff --git a/src/crimson/os/seastore/extent_pinboard.cc b/src/crimson/os/seastore/extent_pinboard.cc index 770e41751a8..2e478533cf4 100644 --- a/src/crimson/os/seastore/extent_pinboard.cc +++ b/src/crimson/os/seastore/extent_pinboard.cc @@ -319,7 +319,8 @@ public: remove_extent(list.front(), extent_pin_state_t::Fresh); } if (should_run_promote()) { - // TODO: wake promote background process + assert(listener); + listener->maybe_wake_promote(); } } diff --git a/src/crimson/os/seastore/extent_placement_manager.cc b/src/crimson/os/seastore/extent_placement_manager.cc index 1b093789d8a..b9f64800d7e 100644 --- a/src/crimson/os/seastore/extent_placement_manager.cc +++ b/src/crimson/os/seastore/extent_placement_manager.cc @@ -631,41 +631,49 @@ void ExtentPlacementManager::BackgroundProcess::start_background() ceph_assert(state == state_t::SCAN_SPACE); assert(!is_running()); process_join = seastar::now(); + promote_process_join = seastar::now(); state = state_t::RUNNING; assert(is_running()); process_join = run(); + if (has_cold_tier()) { + promote_process_join = run_promote(); + } } seastar::future<> ExtentPlacementManager::BackgroundProcess::stop_background() { LOG_PREFIX(BackgroundProcess::stop_background); - return seastar::futurize_invoke([this, FNAME] { - if (!is_running()) { - if (state != state_t::HALT) { - INFO("isn't RUNNING or HALT, STOP"); - state = state_t::STOP; - } else { - INFO("isn't RUNNING, already HALT"); - } - return seastar::now(); - } - INFO("is RUNNING, going to HALT..."); - auto ret = std::move(*process_join); - process_join.reset(); - state = state_t::HALT; - assert(!is_running()); - do_wake_background(); - return ret; - }).then([this, FNAME] { - INFO("done, {}, {}", - JournalTrimmerImpl::stat_printer_t{*trimmer, true}, - AsyncCleaner::stat_printer_t{*main_cleaner, true}); - if (has_cold_tier()) { - INFO("done, cold_cleaner: {}", - AsyncCleaner::stat_printer_t{*cold_cleaner, true}); + if (!is_running()) { + if (state != state_t::HALT) { + INFO("isn't RUNNING or HALT, STOP"); + state = state_t::STOP; + } else { + INFO("isn't RUNNING, already HALT"); } - }); + co_return; + } + INFO("is RUNNING, going to HALT..."); + std::vector> futs; + futs.emplace_back(std::move(*process_join)); + process_join.reset(); + if (promote_process_join) { + futs.emplace_back(std::move(*promote_process_join)); + promote_process_join.reset(); + } + state = state_t::HALT; + assert(!is_running()); + do_wake_background(); + do_wake_promote(); + co_await seastar::when_all(futs.begin(), futs.end()); + INFO("done, {}, {}", + JournalTrimmerImpl::stat_printer_t{*trimmer, true}, + AsyncCleaner::stat_printer_t{*main_cleaner, true}); + if (has_cold_tier()) { + INFO("done, cold_cleaner: {}", + AsyncCleaner::stat_printer_t{*cold_cleaner, true}); + } + co_return; } seastar::future<> @@ -1017,7 +1025,15 @@ ExtentPlacementManager::BackgroundProcess::do_background_cycle() proceed_clean_cold = true; } - if (!proceed_clean_main && !proceed_clean_cold) { + bool proceed_demote = false; + if (has_cold_tier() && + logical_bucket->could_demote() && + (eviction_state.is_fast_mode() || + logical_bucket->should_demote())) { + proceed_demote = true; + } + + if (!proceed_clean_main && !proceed_clean_cold && !proceed_demote) { ceph_abort_msg("no background process will start"); } return seastar::when_all( @@ -1059,11 +1075,51 @@ ExtentPlacementManager::BackgroundProcess::do_background_cycle() ).finally([FNAME] { DEBUG("finished clean cold"); }); + }, + [this, proceed_demote] { + if (!proceed_demote) { + return seastar::now(); + } + return logical_bucket->demote(); } ).discard_result(); } } +seastar::future<> ExtentPlacementManager::BackgroundProcess::run_promote() +{ + assert(pinboard); + assert(is_running()); + return seastar::repeat([this] { + if (!is_running()) { + return seastar::make_ready_future( + seastar::stop_iteration::yes); + } + + return seastar::futurize_invoke([this] { + if (pinboard->should_promote()) { + auto usage = cleaner_usage_t{pinboard->get_promotion_size(), 0}; + auto res = try_reserve_cleaner(usage); + if (res.is_successful()) { + return pinboard->promote( + ).finally([this, usage, res] { + abort_cleaner_usage(usage, res); + }); + } else { + // reserve usage failed, block + abort_cleaner_usage(usage, res); + } + } // shouldn't promote, block + + ceph_assert(!blocking_promote); + blocking_promote = seastar::promise<>(); + return blocking_promote->get_future(); + }).then([] { + return seastar::stop_iteration::no; + }); + }); +} + void ExtentPlacementManager::BackgroundProcess::register_metrics(store_index_t store_index) { namespace sm = seastar::metrics; diff --git a/src/crimson/os/seastore/extent_placement_manager.h b/src/crimson/os/seastore/extent_placement_manager.h index d0beffb88e3..31143bf2d7b 100644 --- a/src/crimson/os/seastore/extent_placement_manager.h +++ b/src/crimson/os/seastore/extent_placement_manager.h @@ -949,6 +949,15 @@ private: void maybe_wake_blocked_io() final; + void maybe_wake_promote() final { + if (!is_ready()) { + return; + } + if (pinboard && pinboard->should_promote()) { + do_wake_promote(); + } + } + private: // reserve helpers bool try_reserve_cold(std::size_t usage); @@ -983,6 +992,13 @@ private: } } + void do_wake_promote() { + if (blocking_promote) { + blocking_promote->set_value(); + blocking_promote = std::nullopt; + } + } + // background_should_run() should be atomic with do_background_cycle() // to make sure the condition is consistent. bool background_should_run() { @@ -1141,6 +1157,7 @@ private: }; seastar::future<> do_background_cycle(); + seastar::future<> run_promote(); void register_metrics(store_index_t store_index); @@ -1176,6 +1193,8 @@ private: // giving the woken continuation a chance to retry the reservation // before the next background cycle. bool pending_user_io_wake = false; + std::optional> promote_process_join; + std::optional> blocking_promote; bool is_running_until_halt = false; state_t state = state_t::STOP; eviction_state_t eviction_state; diff --git a/src/crimson/os/seastore/logical_bucket.cc b/src/crimson/os/seastore/logical_bucket.cc index 61df884f355..f234274bdcd 100644 --- a/src/crimson/os/seastore/logical_bucket.cc +++ b/src/crimson/os/seastore/logical_bucket.cc @@ -47,6 +47,10 @@ public: } else { TRACE("create bucket: {}", laddr); index[laddr] = lru.emplace(lru.end(), laddr); + if (should_demote()) { + assert(listener); + listener->maybe_wake_background(); + } } }