]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore: avoid evicting promoted extent to the cold tier
authorZhang Song <zhangsong02@qianxin.com>
Wed, 3 Sep 2025 08:04:12 +0000 (16:04 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Sat, 23 May 2026 09:11:33 +0000 (17:11 +0800)
Signed-off-by: Zhang Song <zhangsong02@qianxin.com>
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/cache.cc
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/extent_placement_manager.h
src/crimson/os/seastore/transaction_manager.cc
src/crimson/os/seastore/transaction_manager.h
src/test/crimson/seastore/test_transaction_manager.cc

index f9f5470a3eb8102f55de70f2c62b0cb286f00491..555b81c14ce18e75c4d9a352ed5ccbab60fedf15 100644 (file)
@@ -1206,14 +1206,15 @@ CachedExtentRef Cache::alloc_new_non_data_extent_by_type(
   extent_types_t type,   ///< [in] type tag
   extent_len_t length,   ///< [in] length
   placement_hint_t hint, ///< [in] user hint
-  rewrite_gen_t gen      ///< [in] rewrite generation
+  rewrite_gen_t gen,     ///< [in] rewrite generation
+  bool is_tracked
 )
 {
   LOG_PREFIX(Cache::alloc_new_non_data_extent_by_type);
   SUBDEBUGT(seastore_cache, "allocate {} 0x{:x}B, hint={}, gen={}",
             t, type, length, hint, rewrite_gen_printer_t{gen});
   ceph_assert(get_extent_category(type) == data_category_t::METADATA);
-  auto opt = alloc_option_t{hint, gen};
+  auto opt = alloc_option_t{hint, gen, is_tracked};
   switch (type) {
   case extent_types_t::ROOT:
     ceph_assert(0 == "ROOT is never directly alloc'd");
@@ -1258,7 +1259,8 @@ std::vector<CachedExtentRef> Cache::alloc_new_data_extents_by_type(
   extent_types_t type,   ///< [in] type tag
   extent_len_t length,   ///< [in] length
   placement_hint_t hint, ///< [in] user hint
-  rewrite_gen_t gen      ///< [in] rewrite generation
+  rewrite_gen_t gen,      ///< [in] rewrite generation
+  bool is_tracked
 )
 {
   LOG_PREFIX(Cache::alloc_new_data_extents_by_type);
@@ -1270,14 +1272,14 @@ std::vector<CachedExtentRef> Cache::alloc_new_data_extents_by_type(
   case extent_types_t::OBJECT_DATA_BLOCK:
     {
       auto extents = alloc_new_data_extents<
-       ObjectDataBlock>(t, length, {hint, gen});
+       ObjectDataBlock>(t, length, {hint, gen, is_tracked});
       res.insert(res.begin(), extents.begin(), extents.end());
     }
     return res;
   case extent_types_t::TEST_BLOCK:
     {
       auto extents = alloc_new_data_extents<
-       TestBlock>(t, length, {hint, gen});
+       TestBlock>(t, length, {hint, gen, is_tracked});
       res.insert(res.begin(), extents.begin(), extents.end());
     }
     return res;
index 81c700fd84755e4b0178b5e04902569b87814e80..605a5cf35d999f56ba27cae96cf2a9a882882b0a 100644 (file)
@@ -1227,7 +1227,8 @@ public:
     extent_types_t type,   ///< [in] type tag
     extent_len_t length,   ///< [in] length
     placement_hint_t hint, ///< [in] user hint
-    rewrite_gen_t gen      ///< [in] rewrite generation
+    rewrite_gen_t gen,     ///< [in] rewrite generation
+    bool is_tracked
     );
 
   /**
@@ -1240,7 +1241,8 @@ public:
     extent_types_t type,   ///< [in] type tag
     extent_len_t length,   ///< [in] length
     placement_hint_t hint, ///< [in] user hint
-    rewrite_gen_t gen      ///< [in] rewrite generation
+    rewrite_gen_t gen,     ///< [in] rewrite generation
+    bool is_tracked
     );
 
   /**
index ee67127c469903cfe75d670b007c7da1dfaf9611..8b911b72884380ec3b4d2a36646e0f0ca8fa0245 100644 (file)
@@ -354,6 +354,7 @@ public:
   struct alloc_option_t {
     placement_hint_t hint;
     rewrite_gen_t gen;
+    bool is_tracked;
 #ifdef UNIT_TESTS_BUILT
     std::optional<paddr_t> external_paddr = std::nullopt;
 #endif
@@ -374,7 +375,7 @@ public:
     assert(opt.gen == INIT_GENERATION || opt.hint == placement_hint_t::REWRITE);
 
     data_category_t category = get_extent_category(type);
-    opt.gen = adjust_generation(category, type, opt.hint, opt.gen);
+    opt.gen = adjust_generation(category, type, opt.hint, opt.gen, opt.is_tracked);
 
     paddr_t addr;
 #ifdef UNIT_TESTS_BUILT
@@ -414,7 +415,7 @@ public:
     assert(opt.gen == INIT_GENERATION || opt.hint == placement_hint_t::REWRITE);
 
     data_category_t category = get_extent_category(type);
-    opt.gen = adjust_generation(category, type, opt.hint, opt.gen);
+    opt.gen = adjust_generation(category, type, opt.hint, opt.gen, opt.is_tracked);
     assert(opt.gen != INLINE_GENERATION);
 
     // XXX: bp might be extended to point to different memory (e.g. PMem)
@@ -620,7 +621,8 @@ private:
       data_category_t category,
       extent_types_t type,
       placement_hint_t hint,
-      rewrite_gen_t gen) {
+      rewrite_gen_t gen,
+      bool is_tracked) {
     assert(is_real_type(type));
     if (is_root_type(type)) {
       gen = INLINE_GENERATION;
@@ -655,6 +657,11 @@ private:
       gen = background_process.adjust_generation(gen);
     }
 
+    if (is_tracked && gen >= hot_tier_generations &&
+        hint != placement_hint_t::REWRITE) {
+      gen = hot_tier_generations - 1;
+    }
+
     if (gen > dynamic_max_rewrite_generation) {
       gen = dynamic_max_rewrite_generation;
     }
index f14376bf9c638d4028ab12385cd6c839605bf6fc..0a9a4b2921dafa70d5092181243a475eec342f19 100644 (file)
@@ -39,6 +39,7 @@ TransactionManager::TransactionManager(
     journal(std::move(_journal)),
     epm(std::move(_epm)),
     backref_manager(std::move(_backref_manager)),
+    logical_bucket(nullptr),
     full_extent_integrity_check(
       crimson::common::get_conf<bool>(
         "seastore_full_integrity_check")),
@@ -757,6 +758,14 @@ TransactionManager::rewrite_logical_extent(
     ceph_abort();
   }
 
+  bool is_tracked =
+    support_logical_bucket() &&
+    // lextent is from hot tier
+    !epm->is_cold_device(extent->get_paddr().get_device_id()) &&
+    // lextent is cached by non volatile cache
+    logical_bucket->is_cached(
+      extent->get_laddr().get_object_prefix());
+
   if (get_extent_category(extent->get_type()) == data_category_t::METADATA) {
     assert(extent->is_fully_loaded());
     cache->retire_extent(t, extent);
@@ -766,7 +775,8 @@ TransactionManager::rewrite_logical_extent(
       extent->get_length(),
       extent->get_user_hint(),
       // get target rewrite generation
-      extent->get_rewrite_generation())->cast<LogicalChildNode>();
+      extent->get_rewrite_generation(),
+      is_tracked)->cast<LogicalChildNode>();
     nextent->rewrite(t, *extent, 0);
 
     DEBUGT("rewriting meta -- {} to {}", t, *extent, *nextent);
@@ -810,7 +820,8 @@ TransactionManager::rewrite_logical_extent(
       extent->get_length(),
       extent->get_user_hint(),
       // get target rewrite generation
-      extent->get_rewrite_generation());
+      extent->get_rewrite_generation(),
+      is_tracked);
     extent_len_t off = 0;
     auto left = extent->get_length();
     extent_ref_count_t refcount = 0;
@@ -1096,7 +1107,8 @@ TransactionManager::promote_extent(
       orig_ext->get_type(),
       orig_ext->get_length(),
       placement_hint_t::HOT,
-      INIT_GENERATION);
+      INIT_GENERATION,
+      true);
 
     promoted_extents.reserve(promoted_raw_extents.size());
 
@@ -1137,7 +1149,8 @@ TransactionManager::promote_extent(
       orig_ext->get_type(),
       orig_ext->get_length(),
       placement_hint_t::HOT,
-      INIT_GENERATION);
+      INIT_GENERATION,
+      true);
     auto lext = promoted_extent->cast<LogicalChildNode>();
     lext->set_laddr(orig_ext->get_laddr());
     lext->rewrite(t, *orig_ext, 0);
index 54d49604e57e1e2d24a4bae3c0946d9db800c6cf..7006933ff9e10aa578adf034f6a9ea67799a7f02 100644 (file)
@@ -26,6 +26,7 @@
 #include "crimson/os/seastore/logging.h"
 #include "crimson/os/seastore/seastore_types.h"
 #include "crimson/os/seastore/cache.h"
+#include "crimson/os/seastore/logical_bucket.h"
 #include "crimson/os/seastore/root_meta.h"
 #include "crimson/os/seastore/lba_manager.h"
 #include "crimson/os/seastore/backref_manager.h"
@@ -1293,6 +1294,10 @@ public:
     co_return mapping;
   }
 
+  bool support_logical_bucket() const {
+    return logical_bucket != nullptr;
+  }
+
   ~TransactionManager();
 
 private:
@@ -1305,6 +1310,7 @@ private:
   BackrefManagerRef backref_manager;
 
   WritePipeline write_pipeline;
+  LogicalBucket *logical_bucket;
 
   bool full_extent_integrity_check = true;
 
index 25917d31e003c6981a891afd3e5afe784dbee42d..d07579abcceb814752f0a46330a68b0a744df10c 100644 (file)
@@ -1140,7 +1140,8 @@ struct transaction_manager_test_t :
               get_extent_category(t),
               t,
               placement_hint_t::HOT,
-              gen);
+              gen,
+             false);
             if (expected_generations[t][gen] != epm_gen) {
               logger().error("caller: {}, extent type: {}, input generation: {}, "
                             "expected generation : {}, adjust result from EPM: {}",