]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/EPM: parallelise trim_alloc and trim_dirty
authorZhang Song <zhangsong325@gmail.com>
Tue, 6 Dec 2022 07:36:48 +0000 (15:36 +0800)
committerZhang Song <zhangsong325@gmail.com>
Wed, 7 Dec 2022 06:26:58 +0000 (14:26 +0800)
Signed-off-by: Zhang Song <zhangsong325@gmail.com>
src/crimson/os/seastore/async_cleaner.cc
src/crimson/os/seastore/async_cleaner.h
src/crimson/os/seastore/extent_placement_manager.cc
src/test/crimson/seastore/test_btree_lba_manager.cc
src/test/crimson/seastore/test_cbjournal.cc
src/test/crimson/seastore/test_seastore_journal.cc

index b4fd2f1b3a8e42c26d703859c900b6bb139629f4..1564698526b4d033e558589caa539509bc3cd8b8 100644 (file)
@@ -552,6 +552,35 @@ std::size_t JournalTrimmerImpl::get_alloc_journal_size() const
   return static_cast<std::size_t>(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()
 {
index d76084dea8e0f2f53cbe7b0a6f1fa1c75eaabeb8..41f24547b4169add8cd462a52d9eac5e349d2c9a 100644 (file)
@@ -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;
index 53055f2401ce2e52a3011f925c79edaa956686ee..535d52e2c07983fb3244f12ad61d14229e3542d7 100644 (file)
@@ -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{
index 218f64fa06043e868bca50c56ab945e487ea72fa..56548a8c0821b8acf0f56d7c0c48844b0fc253d2 100644 (file)
@@ -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
    */
index 21a66a3dd9f5590d5a7caf1f94d05f7dfb7e11f3..23c979ab3138f461f8da7922376bae35719fa927 100644 (file)
@@ -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();
index 375e2d5b8a4bd6bf1e7e3c2531426d9ecdff7b43..d323c00605b8ca0dd027c44260f8a313162b2492 100644 (file)
@@ -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
    */