]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/extent_placement_manager: make MIN_COLD_GENERATION
authorXuehan Xu <xuxuehan@qianxin.com>
Tue, 15 Jul 2025 06:22:16 +0000 (14:22 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Fri, 18 Jul 2025 07:28:24 +0000 (15:28 +0800)
and MAX_REWRITE_GENERATION configurable

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
13 files changed:
src/common/options/crimson.yaml.in
src/crimson/os/seastore/async_cleaner.cc
src/crimson/os/seastore/async_cleaner.h
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/extent_placement_manager.cc
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_manager.cc
src/test/crimson/seastore/test_btree_lba_manager.cc
src/test/crimson/seastore/test_seastore_cache.cc
src/test/crimson/seastore/test_transaction_manager.cc

index 5999758e22935be0c08885169efba460cc316a00..1d26d42c706957fc912d8cab2ae8a6d735c43d8d 100644 (file)
@@ -189,6 +189,16 @@ options:
   level: advanced
   desc: Begin fast eviction when the used ratio of the main tier reaches this value.
   default: 0.7
+- name: seastore_hot_tier_generations
+  type: uint
+  level: advanced
+  desc: The number of generations in the hot tier or the whole SeaStore instance if there's only one tier.
+  default: 5
+- name: seastore_cold_tier_generations
+  type: uint
+  level: advanced
+  desc: The number of generations in the cold tier if it exists.
+  default: 3
 - name: seastore_data_delta_based_overwrite
   type: size
   level: dev
index bc1d19afd48b677746bfd211e152008a3902ef33..52ed20415c7db0cc4df757e611819aaaf7e6d85f 100644 (file)
@@ -32,7 +32,6 @@ void segment_info_t::set_open(
   ceph_assert(_seq != NULL_SEG_SEQ);
   ceph_assert(_type != segment_type_t::NULL_SEG);
   ceph_assert(_category != data_category_t::NUM);
-  ceph_assert(is_rewrite_generation(_generation));
   state = Segment::segment_state_t::OPEN;
   seq = _seq;
   type = _type;
@@ -67,7 +66,6 @@ void segment_info_t::init_closed(
   ceph_assert(_seq != NULL_SEG_SEQ);
   ceph_assert(_type != segment_type_t::NULL_SEG);
   ceph_assert(_category != data_category_t::NUM);
-  ceph_assert(is_rewrite_generation(_generation));
   state = Segment::segment_state_t::CLOSED;
   seq = _seq;
   type = _type;
@@ -916,6 +914,7 @@ SegmentCleaner::SegmentCleaner(
   SegmentManagerGroupRef&& sm_group,
   BackrefManager &backref_manager,
   SegmentSeqAllocator &segment_seq_allocator,
+  rewrite_gen_t max_rewrite_generation,
   bool detailed,
   bool is_cold)
   : detailed(detailed),
@@ -923,7 +922,8 @@ SegmentCleaner::SegmentCleaner(
     config(config),
     sm_group(std::move(sm_group)),
     backref_manager(backref_manager),
-    ool_segment_seq_allocator(segment_seq_allocator)
+    ool_segment_seq_allocator(segment_seq_allocator),
+    max_rewrite_generation(max_rewrite_generation)
 {
   config.validate();
 }
@@ -1060,6 +1060,7 @@ segment_id_t SegmentCleaner::allocate_segment(
     auto& segment_info = it->second;
     if (segment_info.is_empty()) {
       auto old_usage = calc_utilization(seg_id);
+      ceph_assert(is_rewrite_generation(generation, max_rewrite_generation));
       segments.mark_open(seg_id, seq, type, category, generation);
       if (type == segment_type_t::JOURNAL) {
         assert(trimmer != nullptr);
@@ -1271,8 +1272,12 @@ SegmentCleaner::clean_space_ret SegmentCleaner::clean_space()
          space_tracker->calc_utilization(seg_id),
          sea_time_point_printer_t{segments.get_time_bound()});
     ceph_assert(segment_info.is_closed());
+    ceph_assert(is_rewrite_generation(
+       segment_info.generation, max_rewrite_generation));
     reclaim_state = reclaim_state_t::create(
         seg_id, segment_info.generation, segments.get_segment_size());
+    assert(is_target_rewrite_generation(
+       reclaim_state->target_generation, max_rewrite_generation));
   }
   reclaim_state->advance(config.reclaim_bytes_per_cycle);
 
index 72460c7c76c88125faf0f55464e5a90bb304ac07..7e99dda95e721053647c802a345c964ef80ccd70 100644 (file)
@@ -1291,6 +1291,7 @@ public:
     SegmentManagerGroupRef&& sm_group,
     BackrefManager &backref_manager,
     SegmentSeqAllocator &segment_seq_allocator,
+    rewrite_gen_t max_rewrite_generation,
     bool detailed,
     bool is_cold);
 
@@ -1303,11 +1304,13 @@ public:
       SegmentManagerGroupRef&& sm_group,
       BackrefManager &backref_manager,
       SegmentSeqAllocator &ool_seq_allocator,
+      rewrite_gen_t max_rewrite_generation,
       bool detailed,
       bool is_cold = false) {
     return std::make_unique<SegmentCleaner>(
         config, std::move(sm_group), backref_manager,
-        ool_seq_allocator, detailed, is_cold);
+        ool_seq_allocator, max_rewrite_generation,
+       detailed, is_cold);
   }
 
   /*
@@ -1472,7 +1475,6 @@ private:
         segment_id_t segment_id,
         rewrite_gen_t generation,
         segment_off_t segment_size) {
-      ceph_assert(is_rewrite_generation(generation));
 
       rewrite_gen_t target_gen;
       if (generation < MIN_REWRITE_GENERATION) {
@@ -1483,7 +1485,6 @@ private:
         target_gen = generation + 1;
       }
 
-      assert(is_target_rewrite_generation(target_gen));
       return {generation,
               target_gen,
               segment_size,
@@ -1611,6 +1612,7 @@ private:
     ceph_assert(s_type == segment_type_t::OOL ||
                 trimmer != nullptr); // segment_type_t::JOURNAL
     auto old_usage = calc_utilization(segment);
+    ceph_assert(is_rewrite_generation(generation, max_rewrite_generation));
     segments.init_closed(segment, seq, s_type, category, generation);
     auto new_usage = calc_utilization(segment);
     adjust_segment_util(old_usage, new_usage);
@@ -1670,6 +1672,7 @@ private:
 
   // TODO: drop once paddr->journal_seq_t is introduced
   SegmentSeqAllocator &ool_segment_seq_allocator;
+  const rewrite_gen_t max_rewrite_generation = NULL_GENERATION;
 };
 
 class RBMCleaner;
index 8aee25532875de04aa84d8c1e1940a462b640a13..0dacd80bcadd577e7a9c43eefdd59c942f92a7d8 100644 (file)
@@ -1115,6 +1115,9 @@ public:
       std::rethrow_exception(crimson::ct_error::enospc::exception_ptr());
     }
     auto ret = CachedExtent::make_cached_extent_ref<T>(std::move(result->bp));
+    assert(is_rewrite_generation(
+      result->gen,
+      epm.dynamic_max_rewrite_generation));
     ret->init(CachedExtent::extent_state_t::INITIAL_WRITE_PENDING,
               result->paddr,
               hint,
@@ -1160,6 +1163,9 @@ public:
     std::vector<TCachedExtentRef<T>> extents;
     for (auto &result : results) {
       auto ret = CachedExtent::make_cached_extent_ref<T>(std::move(result.bp));
+      assert(is_rewrite_generation(
+       result.gen,
+       epm.dynamic_max_rewrite_generation));
       ret->init(CachedExtent::extent_state_t::INITIAL_WRITE_PENDING,
                 result.paddr,
                 hint,
index 10c4aa704c810c1906a9f884d6b2a0eb628839af..4cc8f799490653d5df0ef5b2dba03c652ca40c40 100644 (file)
@@ -311,7 +311,6 @@ public:
             placement_hint_t hint,
             rewrite_gen_t gen,
            transaction_id_t trans_id) {
-    assert(gen == NULL_GENERATION || is_rewrite_generation(gen));
     state = _state;
     set_paddr(paddr);
     user_hint = hint;
@@ -758,8 +757,6 @@ public:
 
   /// assign the target rewrite generation for the followup rewrite
   void set_target_rewrite_generation(rewrite_gen_t gen) {
-    assert(is_target_rewrite_generation(gen));
-
     user_hint = placement_hint_t::REWRITE;
     rewrite_generation = gen;
   }
index 457cd1cf1dcf7fc3e440fd6f043c2b2dd9b4aeae..445c7b62f91a1cc249d3c50d6313e25bbf98825b 100644 (file)
@@ -193,10 +193,11 @@ void ExtentPlacementManager::init(
 {
   writer_refs.clear();
   auto cold_segment_cleaner = dynamic_cast<SegmentCleaner*>(cold_cleaner.get());
-  dynamic_max_rewrite_generation = MIN_COLD_GENERATION - 1;
+  dynamic_max_rewrite_generation = hot_tier_generations - 1;
   if (cold_segment_cleaner) {
-    dynamic_max_rewrite_generation = MAX_REWRITE_GENERATION;
+    dynamic_max_rewrite_generation = hot_tier_generations + cold_tier_generations - 1;
   }
+  ceph_assert(dynamic_max_rewrite_generation > MIN_REWRITE_GENERATION);
 
   if (trimmer->get_backend_type() == backend_type_t::SEGMENTED) {
     auto segment_cleaner = dynamic_cast<SegmentCleaner*>(cleaner.get());
@@ -204,7 +205,7 @@ void ExtentPlacementManager::init(
     auto num_writers = generation_to_writer(dynamic_max_rewrite_generation + 1);
 
     data_writers_by_gen.resize(num_writers, nullptr);
-    for (rewrite_gen_t gen = OOL_GENERATION; gen < MIN_COLD_GENERATION; ++gen) {
+    for (rewrite_gen_t gen = OOL_GENERATION; gen < hot_tier_generations; ++gen) {
       writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
            data_category_t::DATA, gen, *segment_cleaner,
             *ool_segment_seq_allocator));
@@ -212,7 +213,7 @@ void ExtentPlacementManager::init(
     }
 
     md_writers_by_gen.resize(num_writers, {});
-    for (rewrite_gen_t gen = OOL_GENERATION; gen < MIN_COLD_GENERATION; ++gen) {
+    for (rewrite_gen_t gen = OOL_GENERATION; gen < hot_tier_generations; ++gen) {
       writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
            data_category_t::METADATA, gen, *segment_cleaner,
             *ool_segment_seq_allocator));
@@ -241,13 +242,13 @@ void ExtentPlacementManager::init(
   }
 
   if (cold_segment_cleaner) {
-    for (rewrite_gen_t gen = MIN_COLD_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+    for (rewrite_gen_t gen = hot_tier_generations; gen <= dynamic_max_rewrite_generation; ++gen) {
       writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
             data_category_t::DATA, gen, *cold_segment_cleaner,
             *ool_segment_seq_allocator));
       data_writers_by_gen[generation_to_writer(gen)] = writer_refs.back().get();
     }
-    for (rewrite_gen_t gen = MIN_COLD_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+    for (rewrite_gen_t gen = hot_tier_generations; gen <= dynamic_max_rewrite_generation; ++gen) {
       writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
             data_category_t::METADATA, gen, *cold_segment_cleaner,
             *ool_segment_seq_allocator));
@@ -261,7 +262,8 @@ void ExtentPlacementManager::init(
 
   background_process.init(std::move(trimmer),
                           std::move(cleaner),
-                          std::move(cold_cleaner));
+                          std::move(cold_cleaner),
+                          hot_tier_generations);
   if (cold_segment_cleaner) {
     ceph_assert(get_main_backend_type() == backend_type_t::SEGMENTED);
     ceph_assert(background_process.has_cold_tier());
@@ -304,7 +306,7 @@ ExtentPlacementManager::get_device_stats(
     main_stats.add(main_writer_stats.back());
     // 2. mainmdat
     main_writer_stats.emplace_back();
-    for (rewrite_gen_t gen = MIN_REWRITE_GENERATION; gen < MIN_COLD_GENERATION; ++gen) {
+    for (rewrite_gen_t gen = MIN_REWRITE_GENERATION; gen < hot_tier_generations; ++gen) {
       const auto &writer = get_writer(METADATA, gen);
       ceph_assert(writer->get_type() == backend_type_t::SEGMENTED);
       main_writer_stats.back().add(writer->get_stats());
@@ -312,7 +314,7 @@ ExtentPlacementManager::get_device_stats(
     main_stats.add(main_writer_stats.back());
     // 3. maindata
     main_writer_stats.emplace_back();
-    for (rewrite_gen_t gen = MIN_REWRITE_GENERATION; gen < MIN_COLD_GENERATION; ++gen) {
+    for (rewrite_gen_t gen = MIN_REWRITE_GENERATION; gen < hot_tier_generations; ++gen) {
       const auto &writer = get_writer(DATA, gen);
       ceph_assert(writer->get_type() == backend_type_t::SEGMENTED);
       main_writer_stats.back().add(writer->get_stats());
@@ -333,7 +335,9 @@ ExtentPlacementManager::get_device_stats(
   if (has_cold_tier) {
     // 0. coldmdat
     cold_writer_stats.emplace_back();
-    for (rewrite_gen_t gen = MIN_COLD_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+    for (rewrite_gen_t gen = hot_tier_generations;
+        gen <= dynamic_max_rewrite_generation;
+        ++gen) {
       const auto &writer = get_writer(METADATA, gen);
       ceph_assert(writer->get_type() == backend_type_t::SEGMENTED);
       cold_writer_stats.back().add(writer->get_stats());
@@ -341,7 +345,9 @@ ExtentPlacementManager::get_device_stats(
     cold_stats.add(cold_writer_stats.back());
     // 1. colddata
     cold_writer_stats.emplace_back();
-    for (rewrite_gen_t gen = MIN_COLD_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+    for (rewrite_gen_t gen = hot_tier_generations;
+        gen <= dynamic_max_rewrite_generation;
+        ++gen) {
       const auto &writer = get_writer(DATA, gen);
       ceph_assert(writer->get_type() == backend_type_t::SEGMENTED);
       cold_writer_stats.back().add(writer->get_stats());
@@ -465,7 +471,7 @@ ExtentPlacementManager::dispatch_delayed_extents(Transaction &t)
       res.usage.cleaner_usage.main_usage += extent->get_length();
       t.mark_delayed_extent_inline(extent);
     } else {
-      if (extent->get_rewrite_generation() < MIN_COLD_GENERATION) {
+      if (extent->get_rewrite_generation() < hot_tier_generations) {
         res.usage.cleaner_usage.main_usage += extent->get_length();
       } else {
         assert(background_process.has_cold_tier());
index 913e95ab647ef6034b561de26e3477681217a1a7..63b36346183d5dd924485ee74a4b5a0515095d3b 100644 (file)
@@ -19,6 +19,8 @@ class transaction_manager_test_t;
 
 namespace crimson::os::seastore {
 
+class Cache;
+
 /**
  * ExtentOolWriter
  *
@@ -255,13 +257,21 @@ struct reserve_io_result_t {
 
 class ExtentPlacementManager {
 public:
-  ExtentPlacementManager()
-    : ool_segment_seq_allocator(
+  ExtentPlacementManager(
+    rewrite_gen_t hot_tier_generations,
+    rewrite_gen_t cold_tier_generations)
+    : hot_tier_generations(hot_tier_generations),
+      cold_tier_generations(cold_tier_generations),
+      dynamic_max_rewrite_generation(cold_tier_generations),
+      ool_segment_seq_allocator(
           std::make_unique<SegmentSeqAllocator>(segment_type_t::OOL)),
       max_data_allocation_size(crimson::common::get_conf<Option::size_t>(
          "seastore_max_data_allocation_size"))
   {
+    LOG_PREFIX(ExtentPlacementManager::ExtentPlacementManager);
     devices_by_id.resize(DEVICE_ID_MAX, nullptr);
+    SUBINFO(seastore_epm, "cold_tier_generations={}, hot_tier_generations={}",
+      cold_tier_generations, hot_tier_generations);
   }
 
   void init(JournalTrimmerImplRef &&, AsyncCleanerRef &&, AsyncCleanerRef &&);
@@ -343,7 +353,7 @@ public:
 #endif
   ) {
     assert(hint < placement_hint_t::NUM_HINTS);
-    assert(is_target_rewrite_generation(gen));
+    assert(is_target_rewrite_generation(gen, dynamic_max_rewrite_generation));
     assert(gen == INIT_GENERATION || hint == placement_hint_t::REWRITE);
 
     data_category_t category = get_extent_category(type);
@@ -390,7 +400,7 @@ public:
   ) {
     LOG_PREFIX(ExtentPlacementManager::alloc_new_data_extents);
     assert(hint < placement_hint_t::NUM_HINTS);
-    assert(is_target_rewrite_generation(gen));
+    assert(is_target_rewrite_generation(gen, dynamic_max_rewrite_generation));
     assert(gen == INIT_GENERATION || hint == placement_hint_t::REWRITE);
 
     data_category_t category = get_extent_category(type);
@@ -582,7 +592,7 @@ private:
     } else if (hint == placement_hint_t::COLD) {
       assert(gen == INIT_GENERATION);
       if (background_process.has_cold_tier()) {
-        gen = MIN_COLD_GENERATION;
+        gen = hot_tier_generations;
       } else {
         gen = MIN_REWRITE_GENERATION;
       }
@@ -643,7 +653,7 @@ private:
 
   ExtentOolWriter* get_writer(data_category_t category,
                               rewrite_gen_t gen) {
-    assert(is_rewrite_generation(gen));
+    assert(is_rewrite_generation(gen, dynamic_max_rewrite_generation));
     assert(gen != INLINE_GENERATION);
     assert(gen <= dynamic_max_rewrite_generation);
     ExtentOolWriter* ret = nullptr;
@@ -659,7 +669,7 @@ private:
 
   const ExtentOolWriter* get_writer(data_category_t category,
                                     rewrite_gen_t gen) const {
-    assert(is_rewrite_generation(gen));
+    assert(is_rewrite_generation(gen, dynamic_max_rewrite_generation));
     assert(gen != INLINE_GENERATION);
     assert(gen <= dynamic_max_rewrite_generation);
     ExtentOolWriter* ret = nullptr;
@@ -686,7 +696,8 @@ private:
 
     void init(JournalTrimmerImplRef &&_trimmer,
               AsyncCleanerRef &&_cleaner,
-              AsyncCleanerRef &&_cold_cleaner) {
+              AsyncCleanerRef &&_cold_cleaner,
+              rewrite_gen_t hot_tier_generations) {
       trimmer = std::move(_trimmer);
       trimmer->set_background_callback(this);
       main_cleaner = std::move(_cleaner);
@@ -709,7 +720,8 @@ private:
           crimson::common::get_conf<double>(
             "seastore_multiple_tiers_default_evict_ratio"),
           crimson::common::get_conf<double>(
-            "seastore_multiple_tiers_fast_evict_ratio"));
+            "seastore_multiple_tiers_fast_evict_ratio"),
+          hot_tier_generations);
       }
     }
 
@@ -958,10 +970,12 @@ private:
       double stop_evict_ratio;
       double default_evict_ratio;
       double fast_evict_ratio;
+      rewrite_gen_t hot_tier_generations;
 
       void init(double stop_ratio,
                 double default_ratio,
-                double fast_ratio) {
+                double fast_ratio,
+                rewrite_gen_t hot_tier_generations) {
         ceph_assert(0 <= stop_ratio);
         ceph_assert(stop_ratio < default_ratio);
         ceph_assert(default_ratio < fast_ratio);
@@ -970,6 +984,7 @@ private:
         stop_evict_ratio = stop_ratio;
         default_evict_ratio = default_ratio;
         fast_evict_ratio = fast_ratio;
+        this->hot_tier_generations = hot_tier_generations;
       }
 
       bool is_stop_mode() const {
@@ -988,15 +1003,15 @@ private:
         rewrite_gen_t ret = gen;
         switch(eviction_mode) {
         case eviction_mode_t::STOP:
-          if (gen == MIN_COLD_GENERATION) {
-            ret = MIN_COLD_GENERATION - 1;
+          if (gen == hot_tier_generations) {
+            ret = hot_tier_generations - 1;
           }
           break;
         case eviction_mode_t::DEFAULT:
           break;
         case eviction_mode_t::FAST:
-          if (gen >= MIN_REWRITE_GENERATION && gen < MIN_COLD_GENERATION) {
-            ret = MIN_COLD_GENERATION;
+          if (gen >= MIN_REWRITE_GENERATION && gen < hot_tier_generations) {
+            ret = hot_tier_generations;
           }
           break;
         default:
@@ -1094,13 +1109,17 @@ private:
   Device* primary_device = nullptr;
   std::size_t num_devices = 0;
 
-  rewrite_gen_t dynamic_max_rewrite_generation = REWRITE_GENERATIONS;
+  // without cold tier, the largest generation is less than hot_tier_generations
+  const rewrite_gen_t hot_tier_generations = NULL_GENERATION;
+  const rewrite_gen_t cold_tier_generations = NULL_GENERATION;
+  rewrite_gen_t dynamic_max_rewrite_generation = NULL_GENERATION;
   BackgroundProcess background_process;
   // TODO: drop once paddr->journal_seq_t is introduced
   SegmentSeqAllocatorRef ool_segment_seq_allocator;
   extent_len_t max_data_allocation_size = 0;
 
   friend class ::transaction_manager_test_t;
+  friend class Cache;
 };
 
 using ExtentPlacementManagerRef = std::unique_ptr<ExtentPlacementManager>;
index 0be29b80a2ba107f2d9c4270abc65d393e6fc799..4f1a593d841c0447a9ff9686c1e954eda7e63968 100644 (file)
@@ -287,8 +287,6 @@ std::ostream &operator<<(std::ostream &out, rewrite_gen_printer_t gen)
     return out << "GEN_INL";
   } else if (gen.gen == OOL_GENERATION) {
     return out << "GEN_OOL";
-  } else if (gen.gen > REWRITE_GENERATIONS) {
-    return out << "GEN_INVALID(" << (unsigned)gen.gen << ")!";
   } else {
     return out << "GEN(" << (unsigned)gen.gen << ")";
   }
index 5a80c6ef720f5f0449051b059324ce11406cd4f2..3d0d89ad39198e4fada64a9446564fd8b0895753 100644 (file)
@@ -1587,10 +1587,6 @@ constexpr rewrite_gen_t OOL_GENERATION = 2;
 
 // All the rewritten extents start with MIN_REWRITE_GENERATION
 constexpr rewrite_gen_t MIN_REWRITE_GENERATION = 3;
-// without cold tier, the largest generation is less than MIN_COLD_GENERATION
-constexpr rewrite_gen_t MIN_COLD_GENERATION = 5;
-constexpr rewrite_gen_t MAX_REWRITE_GENERATION = 7;
-constexpr rewrite_gen_t REWRITE_GENERATIONS = MAX_REWRITE_GENERATION + 1;
 constexpr rewrite_gen_t NULL_GENERATION =
   std::numeric_limits<rewrite_gen_t>::max();
 
@@ -1606,16 +1602,20 @@ constexpr std::size_t generation_to_writer(rewrite_gen_t gen) {
 }
 
 // before EPM decision
-constexpr bool is_target_rewrite_generation(rewrite_gen_t gen) {
+constexpr bool is_target_rewrite_generation(
+  rewrite_gen_t gen,
+  rewrite_gen_t max_gen) {
   return gen == INIT_GENERATION ||
          (gen >= MIN_REWRITE_GENERATION &&
-          gen <= REWRITE_GENERATIONS);
+         gen <= max_gen + 1);
 }
 
 // after EPM decision
-constexpr bool is_rewrite_generation(rewrite_gen_t gen) {
+constexpr bool is_rewrite_generation(
+  rewrite_gen_t gen,
+  rewrite_gen_t max_gen) {
   return gen >= INLINE_GENERATION &&
-         gen < REWRITE_GENERATIONS;
+        gen <= max_gen;
 }
 
 enum class data_category_t : uint8_t {
index 8a7759a2225e6d72120baaa00c0a4127997e1a4b..53acf6c937ab647116faa153d0422e2f9f33aeb9 100644 (file)
@@ -802,7 +802,12 @@ TransactionManagerRef make_transaction_manager(
     shard_stats_t& shard_stats,
     bool is_test)
 {
-  auto epm = std::make_unique<ExtentPlacementManager>();
+  rewrite_gen_t hot_tier_generations = crimson::common::get_conf<uint64_t>(
+    "seastore_hot_tier_generations");
+  rewrite_gen_t cold_tier_generations = crimson::common::get_conf<uint64_t>(
+    "seastore_cold_tier_generations");
+  auto epm = std::make_unique<ExtentPlacementManager>(
+    hot_tier_generations, cold_tier_generations);
   auto cache = std::make_unique<Cache>(*epm);
   auto lba_manager = lba::create_lba_manager(*cache);
   auto sms = std::make_unique<SegmentManagerGroup>();
@@ -890,6 +895,7 @@ TransactionManagerRef make_transaction_manager(
       std::move(cold_sms),
       *backref_manager,
       epm->get_ool_segment_seq_allocator(),
+      hot_tier_generations + cold_tier_generations - 1,
       cleaner_is_detailed,
       /* is_cold = */ true);
     if (backend_type == backend_type_t::SEGMENTED) {
@@ -906,6 +912,7 @@ TransactionManagerRef make_transaction_manager(
       std::move(sms),
       *backref_manager,
       epm->get_ool_segment_seq_allocator(),
+      hot_tier_generations - 1,
       cleaner_is_detailed);
     auto segment_cleaner = static_cast<SegmentCleaner*>(cleaner.get());
     for (auto id : segment_cleaner->get_device_ids()) {
index 2d867211edfc010aafe031e25af143b8d36648a6..b70f24f79c977cd5ab62383d7bf0908beb4e8552 100644 (file)
@@ -139,7 +139,12 @@ struct btree_test_base :
     }).safe_then([this] {
       sms.reset(new SegmentManagerGroup());
       journal = journal::make_segmented(*this, *this);
-      epm.reset(new ExtentPlacementManager());
+      rewrite_gen_t hot_tier_generations = crimson::common::get_conf<uint64_t>(
+       "seastore_hot_tier_generations");
+      rewrite_gen_t cold_tier_generations = crimson::common::get_conf<uint64_t>(
+       "seastore_cold_tier_generations");
+      epm.reset(new ExtentPlacementManager(
+       hot_tier_generations, cold_tier_generations));
       cache.reset(new Cache(*epm));
 
       block_size = segment_manager->get_block_size();
index 9eb4073b182908f3f411f3f7feeef2a7b75d821f..63a89bd15378d83b8ccaa9dd705a9df77b6e61d8 100644 (file)
@@ -110,7 +110,12 @@ struct cache_test_t : public seastar_test_suite_t {
       return segment_manager->mkfs(
         segment_manager::get_ephemeral_device_config(0, 1, 0));
     }).safe_then([this] {
-      epm.reset(new ExtentPlacementManager());
+      rewrite_gen_t hot_tier_generations = crimson::common::get_conf<uint64_t>(
+       "seastore_hot_tier_generations");
+      rewrite_gen_t cold_tier_generations = crimson::common::get_conf<uint64_t>(
+       "seastore_cold_tier_generations");
+      epm.reset(new ExtentPlacementManager(
+       hot_tier_generations, cold_tier_generations));
       cache.reset(new Cache(*epm));
       current = paddr_t::make_seg_paddr(segment_id_t(segment_manager->get_device_id(), 0), 0);
       epm->test_init_no_background(segment_manager.get());
index 1b26e35466efec0f4ed70024d49c76bc6372ddc7..f03ef118cda59157ddf81df62ff952e51089f0a6 100644 (file)
@@ -987,7 +987,7 @@ struct transaction_manager_test_t :
 
       epm->background_process
         .eviction_state
-        .init(stop_ratio, default_ratio, fast_ratio);
+        .init(stop_ratio, default_ratio, fast_ratio, epm->hot_tier_generations);
 
       // these variables are described in
       // EPM::BackgroundProcess::eviction_state_t::maybe_update_eviction_mode
@@ -1040,7 +1040,7 @@ struct transaction_manager_test_t :
       assert(all_extent_types.size() == EXTENT_TYPES_MAX - 4);
 
       std::vector<rewrite_gen_t> all_generations;
-      for (auto i = INIT_GENERATION; i < REWRITE_GENERATIONS; i++) {
+      for (auto i = INIT_GENERATION; i <= epm->dynamic_max_rewrite_generation; i++) {
         all_generations.push_back(i);
       }
 
@@ -1063,7 +1063,7 @@ struct transaction_manager_test_t :
            expected_generations[t][INIT_GENERATION] = OOL_GENERATION;
          }
 
-          for (auto i = INIT_GENERATION + 1; i < REWRITE_GENERATIONS; i++) {
+          for (auto i = INIT_GENERATION + 1; i <= epm->dynamic_max_rewrite_generation; i++) {
            expected_generations[t][i] = i;
           }
         }
@@ -1074,7 +1074,7 @@ struct transaction_manager_test_t :
           if (is_root_type(t) || is_lba_backref_node(t)) {
             continue;
           }
-          for (auto i = INIT_GENERATION + 1; i < REWRITE_GENERATIONS; i++) {
+          for (auto i = INIT_GENERATION + 1; i <= epm->dynamic_max_rewrite_generation; i++) {
             expected_generations[t][i] = func(i);
           }
         }
@@ -1102,9 +1102,9 @@ struct transaction_manager_test_t :
       };
 
       // verify that no data should go to the cold tier
-      update_data_gen_mapping([](rewrite_gen_t gen) -> rewrite_gen_t {
-        if (gen == MIN_COLD_GENERATION) {
-          return MIN_COLD_GENERATION - 1;
+      update_data_gen_mapping([this](rewrite_gen_t gen) -> rewrite_gen_t {
+        if (gen == epm->hot_tier_generations) {
+          return epm->hot_tier_generations - 1;
         } else {
           return gen;
         }
@@ -1130,9 +1130,9 @@ struct transaction_manager_test_t :
 
       // verify that data must go to the cold tier
       run_until(ratio_D_size).get();
-      update_data_gen_mapping([](rewrite_gen_t gen) {
-        if (gen >= MIN_REWRITE_GENERATION && gen < MIN_COLD_GENERATION) {
-          return MIN_COLD_GENERATION;
+      update_data_gen_mapping([this](rewrite_gen_t gen) {
+        if (gen >= MIN_REWRITE_GENERATION && gen < epm->hot_tier_generations) {
+          return epm->hot_tier_generations;
         } else {
           return gen;
         }