]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore: make fresh extents go though the extent placement manager
authorXuehan Xu <xxhdx1985126@gmail.com>
Tue, 27 Jul 2021 15:00:56 +0000 (23:00 +0800)
committerXuehan Xu <xxhdx1985126@gmail.com>
Wed, 8 Sep 2021 03:03:01 +0000 (11:03 +0800)
Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/extent_placement_manager.h
src/crimson/os/seastore/seastore_types.cc
src/crimson/os/seastore/seastore_types.h
src/crimson/os/seastore/transaction.h
src/crimson/os/seastore/transaction_manager.h

index a265c601e0fa59a761da005baf042d2d63b72523..2cad75a77214c1460e254600ad067ac76d49cf08 100644 (file)
@@ -367,6 +367,11 @@ public:
     }
   }
 
+  /**
+   * alloc_new_extent
+   *
+   * Allocates a fresh extent. if delayed is true, addr will be alloc'd later
+   */
   template <typename T>
   TCachedExtentRef<T> alloc_new_extent(
     Transaction &t,       ///< [in, out] current transaction
index 1f1730b2b4cff371ffe15d04febec799887e48a5..8bbaa2a2c00cb597c134a8c612fc8f657bcfa0f0 100644 (file)
@@ -23,6 +23,7 @@ class CachedExtent;
 using CachedExtentRef = boost::intrusive_ptr<CachedExtent>;
 class SegmentedAllocator;
 class TransactionManager;
+class ExtentPlacementManager;
 
 // #define DEBUG_CACHED_EXTENT_REF
 #ifdef DEBUG_CACHED_EXTENT_REF
@@ -471,6 +472,7 @@ protected:
   friend class crimson::os::seastore::ool_record_t;
   friend class crimson::os::seastore::SegmentedAllocator;
   friend class crimson::os::seastore::TransactionManager;
+  friend class crimson::os::seastore::ExtentPlacementManager;
 };
 
 std::ostream &operator<<(std::ostream &, CachedExtent::extent_state_t);
@@ -565,7 +567,8 @@ public:
 
   void erase(CachedExtent &extent) {
     assert(extent.parent_index);
-    auto erased = extent_index.erase(extent);
+    auto erased = extent_index.erase(
+      extent_index.s_iterator_to(extent));
     extent.parent_index = nullptr;
 
     if (erased) {
index 934f012c01c3f1174155e4b08f18b8122bf06865..e7cfb8a8abd52a3341e57f064019c7d54112651d 100644 (file)
@@ -214,7 +214,6 @@ class SegmentedAllocator : public ExtentAllocator {
     finish_record_ret finish_write(
       Transaction& t,
       ool_record_t& record);
-    segment_off_t fake_paddr_off = 0;
     bool _needs_roll(segment_off_t length) const;
 
     write_iertr::future<> _write(
@@ -325,6 +324,28 @@ public:
     return extent;
   }
 
+  template<
+    typename T,
+    std::enable_if_t<std::is_base_of_v<LogicalCachedExtent, T>, int> = 0>
+  TCachedExtentRef<T> alloc_new_extent(
+    Transaction& t,
+    segment_off_t length,
+    ool_placement_hint_t hint = ool_placement_hint_t::NONE)
+  {
+    auto dtype = get_allocator_type(hint);
+    TCachedExtentRef<T> extent;
+    if (need_delayed_allocation(dtype)) {
+      // set a unique temperary paddr, this is necessary because
+      // transaction's write_set is indexed by paddr
+      extent = cache.alloc_new_extent<T>(t, length, true);
+    } else {
+      extent = cache.alloc_new_extent<T>(t, length);
+    }
+    extent->backend_type = dtype;
+    extent->hint = hint;
+    return extent;
+  }
+
   /**
    * delayed_alloc_or_ool_write
    *
index 82871df3d9064e9818ab5504006cba5639f87638..5b18e4f55d14de99aa4749994d0c8a865ebbafec 100644 (file)
@@ -17,6 +17,8 @@ std::ostream &segment_to_stream(std::ostream &out, const segment_id_t &t)
     return out << "ZERO_SEG";
   else if (t == FAKE_SEG_ID)
     return out << "FAKE_SEG";
+  else if (t == DELAYED_TEMP_SEG_ID)
+    return out << "DELAYED_TEMP_SEG";
   else
     return out << t;
 }
index 465cd2dfb4794b32f9a0fda0d9d13c9765fdbfff..f5e052975912759e2b857097c40fecbd759cc7e4 100644 (file)
@@ -55,6 +55,8 @@ constexpr segment_id_t FAKE_SEG_ID =
  */
 constexpr segment_id_t ZERO_SEG_ID =
   std::numeric_limits<segment_id_t>::max() - 5;
+constexpr segment_id_t DELAYED_TEMP_SEG_ID =
+  std::numeric_limits<segment_id_t>::max() - 6;
 
 std::ostream &segment_to_stream(std::ostream &, const segment_id_t &t);
 
@@ -215,6 +217,9 @@ constexpr paddr_t make_fake_paddr(segment_off_t off) {
 constexpr paddr_t zero_paddr() {
   return paddr_t{ZERO_SEG_ID, 0};
 }
+constexpr paddr_t delayed_temp_paddr(segment_off_t off) {
+  return paddr_t{DELAYED_TEMP_SEG_ID, off};
+}
 
 struct __attribute((packed)) paddr_le_t {
   ceph_le32 segment = ceph_le32(NULL_SEG_ID);
index 7fda438bba8e2410e467d3f5ccb67ccd4188d85b..0161a5e90c86430acdc5bfe7f97ba2f03f4076c8 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <boost/intrusive/list.hpp>
 
+#include "crimson/common/log.h"
 #include "crimson/os/seastore/ordering_handle.h"
 #include "crimson/os/seastore/seastore_types.h"
 #include "crimson/os/seastore/cached_extent.h"
@@ -39,6 +40,11 @@ public:
       if (out)
        *out = CachedExtentRef(&*iter);
       return get_extent_ret::PRESENT;
+    } else if (auto iter = delayed_set.find_offset(addr);
+       iter != delayed_set.end()) {
+      if (out)
+       *out = CachedExtentRef(&*iter);
+      return get_extent_ret::PRESENT;
     } else if (
       auto iter = read_set.find(addr);
       iter != read_set.end()) {
@@ -60,7 +66,12 @@ public:
       // will affect relative paddrs, and it should be rare to retire a fresh
       // extent.
       ref->state = CachedExtent::extent_state_t::INVALID;
-      write_set.erase(*ref);
+      if (ref->is_inline()) {
+       write_set.erase(*ref);
+      } else {
+       // if ref is not relative, it must be in the delayed set
+       delayed_set.erase(*ref);
+      }
     } else if (ref->is_mutation_pending()) {
       ref->state = CachedExtent::extent_state_t::INVALID;
       write_set.erase(*ref);
@@ -89,6 +100,8 @@ public:
     ceph_assert(!is_weak());
     if (delayed) {
       assert(ref->is_logical());
+      ref->set_paddr(delayed_temp_paddr(delayed_temp_offset));
+      delayed_temp_offset += ref->get_length();
       delayed_alloc_list.emplace_back(ref->cast<LogicalCachedExtent>());
       delayed_set.insert(*ref);
     } else {
@@ -216,6 +229,10 @@ public:
       i->state = CachedExtent::extent_state_t::INVALID;
       write_set.erase(*i++);
     }
+    for (auto i = delayed_set.begin();
+        i != delayed_set.end();) {
+      delayed_set.erase(*i++);
+    }
   }
 
   friend class crimson::os::seastore::SeaStore;
@@ -224,8 +241,10 @@ public:
   void reset_preserve_handle(journal_seq_t initiated_after) {
     root.reset();
     offset = 0;
+    delayed_temp_offset = 0;
     read_set.clear();
     write_set.clear();
+    delayed_set.clear();
     fresh_block_list.clear();
     mutated_block_list.clear();
     delayed_alloc_list.clear();
@@ -274,9 +293,12 @@ private:
   RootBlockRef root;        ///< ref to root if read or written by transaction
 
   segment_off_t offset = 0; ///< relative offset of next block
+  segment_off_t delayed_temp_offset = 0;
 
   read_set_t<Transaction> read_set; ///< set of extents read by paddr
   ExtentIndex write_set;            ///< set of extents written by paddr
+  ExtentIndex delayed_set;         ///< set of extents whose paddr
+                                   ///  allocation are delayed
 
   std::list<CachedExtentRef> fresh_block_list;   ///< list of fresh blocks
   std::list<CachedExtentRef> mutated_block_list; ///< list of mutated blocks
index 695484d45f9a1dab2fc5594d8f10b6edcb5c6fb7..2a455ab426b22d23ac6afa8a1414be26efebbe01 100644 (file)
@@ -284,7 +284,7 @@ public:
     Transaction &t,
     laddr_t hint,
     extent_len_t len) {
-    auto ext = cache->alloc_new_extent<T>(
+    auto ext = epm->alloc_new_extent<T>(
       t,
       len);
     return lba_manager->alloc_extent(