]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix smr allocator init
authorSage Weil <sage@newdream.net>
Mon, 6 Sep 2021 21:45:23 +0000 (16:45 -0500)
committerSage Weil <sage@newdream.net>
Fri, 29 Oct 2021 13:55:57 +0000 (09:55 -0400)
- initialize from device's pointers
- cross check against freelist manager's pointers (warn!)
- fix init_{add,rm}_free methods to do little/nothing (the other init
  method does most of what we need)

Signed-off-by: Sage Weil <sage@newdream.net>
src/os/bluestore/BlueStore.cc
src/os/bluestore/ZonedAllocator.cc
src/os/bluestore/ZonedAllocator.h

index ed36f945fd6bae9a08baaa007069038d88ff695a..fe59e8eb1ba7797725c2142f31cbf4a871d21d9c 100644 (file)
@@ -5570,12 +5570,22 @@ int BlueStore::_init_alloc()
     ceph_assert(a);
     auto f = dynamic_cast<ZonedFreelistManager*>(fm);
     ceph_assert(f);
-    a->init_alloc(f->get_zone_states(db),
-                 &zoned_cleaner_lock,
-                 &zoned_cleaner_cond);
+    a->init_from_zone_pointers(f->get_zone_states(db),
+                              &zoned_cleaner_lock,
+                              &zoned_cleaner_cond);
+    dout(1) << __func__
+           << " loaded zone pointers: "
+           << std::hex
+           << ", allocator type " << shared_alloc.a->get_type()
+           << ", capacity 0x" << shared_alloc.a->get_capacity()
+           << ", block size 0x" << shared_alloc.a->get_block_size()
+           << ", free 0x" << shared_alloc.a->get_free()
+           << ", fragmentation " << shared_alloc.a->get_fragmentation()
+           << std::dec << dendl;
+    return 0;
   }
 #endif
-  
+
   uint64_t num = 0, bytes = 0;
   utime_t start_time = ceph_clock_now();
   if (!fm->is_null_manager()) {
index 6425919639892e71c6223b06635236e6387c20ba..0ec8000e17b6eef0de05726f0c49b2e99d87475e 100644 (file)
@@ -28,6 +28,8 @@ ZonedAllocator::ZonedAllocator(CephContext* cct,
       cct(cct),
       num_free(0),
       size(size),
+      conventional_size(_first_sequential_zone * _zone_size),
+      sequential_size(size - conventional_size),
       block_size(blk_size),
       zone_size(_zone_size),
       first_seq_zone_num(_first_sequential_zone),
@@ -148,44 +150,26 @@ void ZonedAllocator::dump(std::function<void(uint64_t offset,
   std::lock_guard l(lock);
 }
 
-// This just increments |num_free|.  The actual free space is added by
-// init_alloc, as it updates the write pointer for each zone.
-void ZonedAllocator::init_add_free(uint64_t offset, uint64_t length)
-{
-  ldout(cct, 40) << " " << std::hex
-                << offset << "~" << length << std::dec << dendl;
-
-  num_free += length;
-}
-
-void ZonedAllocator::init_rm_free(uint64_t offset, uint64_t length)
+void ZonedAllocator::init_from_zone_pointers(
+  std::vector<zone_state_t> &&_zone_states,
+  ceph::mutex *_cleaner_lock,
+  ceph::condition_variable *_cleaner_cond)
 {
+  // this is called once, based on the device's zone pointers
   std::lock_guard l(lock);
-  ldout(cct, 40) << " 0x" << std::hex
-                << offset << "~" << length << std::dec << dendl;
-
-  num_free -= length;
-  ceph_assert(num_free >= 0);
-
-  uint64_t zone_num = offset / zone_size;
-  uint64_t write_pointer = offset % zone_size;
-  uint64_t remaining_space = get_remaining_space(zone_num);
-
-  ceph_assert(get_write_pointer(zone_num) == write_pointer);
-  ceph_assert(remaining_space <= length);
-  increment_write_pointer(zone_num, remaining_space);
-
-  ldout(cct, 40) << " set zone 0x" << std::hex
-                << zone_num << " write pointer to 0x" << zone_size << std::dec << dendl;
-
-  length -= remaining_space;
-  ceph_assert(length % zone_size == 0);
-
-  for ( ; length; length -= zone_size) {
-    increment_write_pointer(++zone_num, zone_size);
-    ldout(cct, 40) << " set zone 0x" << std::hex
-                  << zone_num << " write pointer to 0x" << zone_size << std::dec << dendl;
+  ldout(cct, 10) << dendl;
+  cleaner_lock = _cleaner_lock;
+  cleaner_cond = _cleaner_cond;
+  zone_states = std::move(_zone_states);
+  num_free = 0;
+  for (size_t i = first_seq_zone_num; i < num_zones; ++i) {
+    num_free += zone_size - (zone_states[i].write_pointer % zone_size);
   }
+  uint64_t conventional_size = first_seq_zone_num * zone_size;
+  uint64_t sequential_size = size - conventional_size;
+  ldout(cct, 10) << "free 0x" << std::hex << num_free
+                << " / 0x" << sequential_size << std::dec
+                << dendl;
 }
 
 const std::set<uint64_t> *ZonedAllocator::get_zones_to_clean(void)
@@ -198,16 +182,15 @@ bool ZonedAllocator::low_on_space(void)
 {
   ceph_assert(zones_to_clean.empty());
 
-  uint64_t conventional_size = first_seq_zone_num * zone_size;
-  uint64_t sequential_size = size - conventional_size;
   uint64_t sequential_num_free = num_free - conventional_size;
   double free_ratio = static_cast<double>(sequential_num_free) / sequential_size;
 
-  ldout(cct, 10) << " free size 0x" << std::hex << sequential_num_free
-                << " total size 0x" << sequential_size << std::dec
+  ldout(cct, 10) << " free 0x" << std::hex << sequential_num_free
+                << "/ 0x" << sequential_size << std::dec
                 << ", free ratio is " << free_ratio << dendl;
+  ceph_assert(sequential_num_free <= sequential_size);
 
-   // TODO: make 0.25 tunable
+  // TODO: make 0.25 tunable
   return free_ratio <= 0.25;
 }
 
@@ -257,18 +240,6 @@ void ZonedAllocator::find_zones_to_clean(void)
   cleaner_lock->unlock();
 }
  
-void ZonedAllocator::init_alloc(std::vector<zone_state_t> &&_zone_states,
-                               ceph::mutex *_cleaner_lock,
-                               ceph::condition_variable *_cleaner_cond)
-{
-  lderr(cct) << dendl;
-  std::lock_guard l(lock);
-  cleaner_lock = _cleaner_lock;
-  cleaner_cond = _cleaner_cond;
-  ldout(cct, 10) << dendl;
-  zone_states = std::move(_zone_states);
-}
-
 void ZonedAllocator::mark_zones_to_clean_free(void)
 {
   std::lock_guard l(lock);
index 585e8943cec67138ae453a3c35281d2ce5051474..73697e4cfd5f011b3fa6f7d94239f49428728b50 100644 (file)
@@ -32,6 +32,7 @@ class ZonedAllocator : public Allocator {
 
   std::atomic<int64_t> num_free;     ///< total bytes in freelist
   uint64_t size;
+  uint64_t conventional_size, sequential_size;
   uint64_t block_size;
   uint64_t zone_size;
   uint64_t first_seq_zone_num;
@@ -91,15 +92,15 @@ public:
   void dump(std::function<void(uint64_t offset,
                                uint64_t length)> notify) override;
 
-  void init_alloc(std::vector<zone_state_t> &&_zone_states,
-                 ceph::mutex *_cleaner_lock,
-                 ceph::condition_variable *_cleaner_cond);
-
   const std::set<uint64_t> *get_zones_to_clean(void);
   void mark_zones_to_clean_free(void);
 
-  void init_add_free(uint64_t offset, uint64_t length) override;
-  void init_rm_free(uint64_t offset, uint64_t length) override;
+  void init_from_zone_pointers(
+    std::vector<zone_state_t> &&_zone_states,
+    ceph::mutex *_cleaner_lock,
+    ceph::condition_variable *_cleaner_cond);
+  void init_add_free(uint64_t offset, uint64_t length) override {}
+  void init_rm_free(uint64_t offset, uint64_t length) override {}
 
   void shutdown() override;