From 0f7a4264d033e96ccd5f195925e502e081098de1 Mon Sep 17 00:00:00 2001 From: Zhang Song Date: Tue, 6 Dec 2022 15:36:48 +0800 Subject: [PATCH] crimson/os/seastore/EPM: parallelise trim_alloc and trim_dirty Signed-off-by: Zhang Song --- src/crimson/os/seastore/async_cleaner.cc | 29 ++++++++++++++++ src/crimson/os/seastore/async_cleaner.h | 23 ++++++++++--- .../os/seastore/extent_placement_manager.cc | 33 ++++++++++--------- .../seastore/test_btree_lba_manager.cc | 4 +++ src/test/crimson/seastore/test_cbjournal.cc | 4 +++ .../crimson/seastore/test_seastore_journal.cc | 4 +++ 6 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/crimson/os/seastore/async_cleaner.cc b/src/crimson/os/seastore/async_cleaner.cc index b4fd2f1b3a8..1564698526b 100644 --- a/src/crimson/os/seastore/async_cleaner.cc +++ b/src/crimson/os/seastore/async_cleaner.cc @@ -552,6 +552,35 @@ std::size_t JournalTrimmerImpl::get_alloc_journal_size() const return static_cast(ret); } +seastar::future<> JournalTrimmerImpl::trim() { + return seastar::when_all( + [this] { + if (should_trim_alloc()) { + return trim_alloc( + ).handle_error( + crimson::ct_error::assert_all{ + "encountered invalid error in trim_alloc" + } + ); + } else { + return seastar::now(); + } + }, + [this] { + if (should_trim_dirty()) { + return trim_dirty( + ).handle_error( + crimson::ct_error::assert_all{ + "encountered invalid error in trim_dirty" + } + ); + } else { + return seastar::now(); + } + } + ).discard_result(); +} + JournalTrimmerImpl::trim_ertr::future<> JournalTrimmerImpl::trim_alloc() { diff --git a/src/crimson/os/seastore/async_cleaner.h b/src/crimson/os/seastore/async_cleaner.h index d76084dea8e..41f24547b41 100644 --- a/src/crimson/os/seastore/async_cleaner.h +++ b/src/crimson/os/seastore/async_cleaner.h @@ -441,6 +441,8 @@ public: return std::min(get_alloc_tail(), get_dirty_tail()); } + virtual std::size_t get_trim_size_per_cycle() const = 0; + bool check_is_ready() const { return (get_journal_head() != JOURNAL_SEQ_NULL && get_dirty_tail() != JOURNAL_SEQ_NULL && @@ -519,6 +521,11 @@ public: void update_journal_tails( journal_seq_t dirty_tail, journal_seq_t alloc_tail) final; + std::size_t get_trim_size_per_cycle() const final { + return config.rewrite_backref_bytes_per_cycle + + config.rewrite_dirty_bytes_per_cycle; + } + journal_type_t get_journal_type() const { return journal_type; } @@ -545,6 +552,10 @@ public: return get_alloc_tail_target() > journal_alloc_tail; } + bool should_trim() const { + return should_trim_alloc() || should_trim_dirty(); + } + bool should_block_io_on_trim() const { return get_tail_limit() > get_journal_tail().add_offset( @@ -566,11 +577,7 @@ public: reserved_usage -= usage; } - using trim_ertr = crimson::errorator< - crimson::ct_error::input_output_error>; - trim_ertr::future<> trim_dirty(); - - trim_ertr::future<> trim_alloc(); + seastar::future<> trim(); static JournalTrimmerImplRef create( BackrefManager &backref_manager, @@ -589,6 +596,12 @@ public: friend std::ostream &operator<<(std::ostream &, const stat_printer_t &); private: + using trim_ertr = crimson::errorator< + crimson::ct_error::input_output_error>; + trim_ertr::future<> trim_dirty(); + + trim_ertr::future<> trim_alloc(); + journal_seq_t get_tail_limit() const; journal_seq_t get_dirty_tail_target() const; journal_seq_t get_alloc_tail_target() const; diff --git a/src/crimson/os/seastore/extent_placement_manager.cc b/src/crimson/os/seastore/extent_placement_manager.cc index 53055f2401c..535d52e2c07 100644 --- a/src/crimson/os/seastore/extent_placement_manager.cc +++ b/src/crimson/os/seastore/extent_placement_manager.cc @@ -513,21 +513,24 @@ seastar::future<> ExtentPlacementManager::BackgroundProcess::do_background_cycle() { assert(is_ready()); - if (trimmer->should_trim_alloc()) { - return trimmer->trim_alloc( - ).handle_error( - crimson::ct_error::assert_all{ - "do_background_cycle encountered invalid error in trim_alloc" - } - ); - } else if (trimmer->should_trim_dirty()) { - return trimmer->trim_dirty( - ).handle_error( - crimson::ct_error::assert_all{ - "do_background_cycle encountered invalid error in trim_dirty" - } - ); - } else if (cleaner->should_clean_space()) { + bool trimmer_reserve_success = true; + if (trimmer->should_trim()) { + trimmer_reserve_success = + cleaner->try_reserve_projected_usage( + trimmer->get_trim_size_per_cycle()); + } + + if (trimmer->should_trim() && trimmer_reserve_success) { + return trimmer->trim( + ).finally([this] { + cleaner->release_projected_usage( + trimmer->get_trim_size_per_cycle()); + }); + } else if (cleaner->should_clean_space() || + // make sure cleaner will start + // when the trimmer should run but + // failed to reserve space. + !trimmer_reserve_success) { return cleaner->clean_space( ).handle_error( crimson::ct_error::assert_all{ diff --git a/src/test/crimson/seastore/test_btree_lba_manager.cc b/src/test/crimson/seastore/test_btree_lba_manager.cc index 218f64fa060..56548a8c082 100644 --- a/src/test/crimson/seastore/test_btree_lba_manager.cc +++ b/src/test/crimson/seastore/test_btree_lba_manager.cc @@ -65,6 +65,10 @@ struct btree_test_base : void release_inline_usage(std::size_t) final {} + std::size_t get_trim_size_per_cycle() const final { + return 0; + } + /* * SegmentProvider interfaces */ diff --git a/src/test/crimson/seastore/test_cbjournal.cc b/src/test/crimson/seastore/test_cbjournal.cc index 21a66a3dd9f..23c979ab313 100644 --- a/src/test/crimson/seastore/test_cbjournal.cc +++ b/src/test/crimson/seastore/test_cbjournal.cc @@ -167,6 +167,10 @@ struct cbjournal_test_t : public seastar_test_suite_t, JournalTrimmer void release_inline_usage(std::size_t) final {} + std::size_t get_trim_size_per_cycle() const final { + return 0; + } + auto submit_record(record_t&& record) { entries.push_back(record); OrderingHandle handle = get_dummy_ordering_handle(); diff --git a/src/test/crimson/seastore/test_seastore_journal.cc b/src/test/crimson/seastore/test_seastore_journal.cc index 375e2d5b8a4..d323c00605b 100644 --- a/src/test/crimson/seastore/test_seastore_journal.cc +++ b/src/test/crimson/seastore/test_seastore_journal.cc @@ -104,6 +104,10 @@ struct journal_test_t : seastar_test_suite_t, SegmentProvider, JournalTrimmer { void release_inline_usage(std::size_t) final {} + std::size_t get_trim_size_per_cycle() const final { + return 0; + } + /* * SegmentProvider interfaces */ -- 2.39.5