]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: make AvlAllocator overridable.
authorIgor Fedotov <ifedotov@suse.com>
Wed, 12 Feb 2020 13:17:40 +0000 (16:17 +0300)
committerIgor Fedotov <ifedotov@suse.com>
Mon, 13 Apr 2020 13:12:43 +0000 (16:12 +0300)
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
src/os/bluestore/AvlAllocator.cc
src/os/bluestore/AvlAllocator.h

index abc130a41a25de39dbe7d4885e98e4bba8c98714..c6f63fe35bf5d7d4d66b2ff2904d4d661edf1cbe 100644 (file)
@@ -135,13 +135,34 @@ void AvlAllocator::_remove_from_tree(uint64_t start, uint64_t size)
   }
 }
 
+int64_t AvlAllocator::_allocate(
+  uint64_t want,
+  uint64_t unit,
+  uint64_t max_alloc_size,
+  int64_t  hint, // unused, for now!
+  PExtentVector* extents)
+{
+  uint64_t allocated = 0;
+  while (allocated < want) {
+    uint64_t offset, length;
+    int r = _allocate(std::min(max_alloc_size, want - allocated),
+      unit, &offset, &length);
+    if (r < 0) {
+      // Allocation failed.
+      break;
+    }
+    extents->emplace_back(offset, length);
+    allocated += length;
+  }
+  return allocated ? allocated : -ENOSPC;
+}
+
 int AvlAllocator::_allocate(
   uint64_t size,
   uint64_t unit,
   uint64_t *offset,
   uint64_t *length)
 {
-  std::lock_guard l(lock);
   uint64_t max_size = 0;
   if (auto p = range_size_tree.rbegin(); p != range_size_tree.rend()) {
     max_size = p->end - p->start;
@@ -192,6 +213,25 @@ int AvlAllocator::_allocate(
   return 0;
 }
 
+void AvlAllocator::_release(const interval_set<uint64_t>& release_set)
+{
+  for (auto p = release_set.begin(); p != release_set.end(); ++p) {
+    const auto offset = p.get_start();
+    const auto length = p.get_len();
+    ldout(cct, 10) << __func__ << std::hex
+      << " offset 0x" << offset
+      << " length 0x" << length
+      << std::dec << dendl;
+    _add_to_tree(offset, length);
+  }
+}
+
+void AvlAllocator::_shutdown()
+{
+  range_size_tree.clear();
+  range_tree.clear_and_dispose(dispose_rs{});
+}
+
 AvlAllocator::AvlAllocator(CephContext* cct,
                            int64_t device_size,
                            int64_t block_size,
@@ -245,34 +285,13 @@ int64_t AvlAllocator::allocate(
       max_alloc_size >= cap) {
     max_alloc_size = cap;
   }
-
-  uint64_t allocated = 0;
-  while (allocated < want) {
-    uint64_t offset, length;
-    int r = _allocate(std::min(max_alloc_size, want - allocated),
-                      unit, &offset, &length);
-    if (r < 0) {
-      // Allocation failed.
-      break;
-    }
-    extents->emplace_back(offset, length);
-    allocated += length;
-  }
-  return allocated ? allocated : -ENOSPC;
+  std::lock_guard l(lock);
+  return _allocate(want, unit, max_alloc_size, hint, extents);
 }
 
-void AvlAllocator::release(const interval_set<uint64_t>& release_set)
-{
+void AvlAllocator::release(const interval_set<uint64_t>& release_set) {
   std::lock_guard l(lock);
-  for (auto p = release_set.begin(); p != release_set.end(); ++p) {
-    const auto offset = p.get_start();
-    const auto length = p.get_len();
-    ldout(cct, 10) << __func__ << std::hex
-                   << " offset 0x" << offset
-                   << " length 0x" << length
-                   << std::dec << dendl;
-    _add_to_tree(offset, length);
-  }
+  _release(release_set);
 }
 
 uint64_t AvlAllocator::get_free()
@@ -284,30 +303,31 @@ uint64_t AvlAllocator::get_free()
 double AvlAllocator::get_fragmentation()
 {
   std::lock_guard l(lock);
-  auto free_blocks = p2align(num_free, block_size) / block_size;
-  if (free_blocks <= 1) {
-    return .0;
-  }  
-  return (static_cast<double>(range_tree.size() - 1) / (free_blocks - 1));
+  return _get_fragmentation();
 }
 
 void AvlAllocator::dump()
 {
   std::lock_guard l(lock);
+  _dump();
+}
+
+void AvlAllocator::_dump() const
+{
   ldout(cct, 0) << __func__ << " range_tree: " << dendl;
   for (auto& rs : range_tree) {
     ldout(cct, 0) << std::hex
-                  << "0x" << rs.start << "~" << rs.end
-                  << std::dec
-                  << dendl;
+      << "0x" << rs.start << "~" << rs.end
+      << std::dec
+      << dendl;
   }
 
   ldout(cct, 0) << __func__ << " range_size_tree: " << dendl;
   for (auto& rs : range_size_tree) {
     ldout(cct, 0) << std::hex
-                  << "0x" << rs.start << "~" << rs.end
-                  << std::dec
-                  << dendl;
+      << "0x" << rs.start << "~" << rs.end
+      << std::dec
+      << dendl;
   }
 }
 
@@ -341,6 +361,5 @@ void AvlAllocator::init_rm_free(uint64_t offset, uint64_t length)
 void AvlAllocator::shutdown()
 {
   std::lock_guard l(lock);
-  range_size_tree.clear();
-  range_tree.clear_and_dispose(dispose_rs{});
+  _shutdown();
 }
index 0ad3c99c6a2e6c455a6ee5c253a5f2788acb1be7..79bb3f42d2fdacd616678a045859a3252879c5da 100644 (file)
@@ -49,7 +49,7 @@ struct range_seg_t {
   boost::intrusive::avl_set_member_hook<> size_hook;
 };
 
-class AvlAllocator final : public Allocator {
+class AvlAllocator : public Allocator {
   struct dispose_rs {
     void operator()(range_seg_t* p)
     {
@@ -60,7 +60,7 @@ class AvlAllocator final : public Allocator {
 protected:
   /*
   * ctor intended for the usage from descendant class(es) which
-  * provides handlig for spilled over entries
+  * provides handling for spilled over entries
   * (when entry count >= max_entries)
   */
   AvlAllocator(CephContext* cct, int64_t device_size, int64_t block_size,
@@ -75,23 +75,21 @@ public:
     uint64_t unit,
     uint64_t max_alloc_size,
     int64_t  hint,
-    PExtentVector *extents) final;
-  void release(const interval_set<uint64_t>& release_set) final;
-  uint64_t get_free() final;
-  double get_fragmentation() final;
+    PExtentVector *extents) override;
+  void release(const interval_set<uint64_t>& release_set) override;
+  uint64_t get_free() override;
+  double get_fragmentation() override;
 
-  void dump() final;
-  void dump(std::function<void(uint64_t offset, uint64_t length)> notify) final;
-  void init_add_free(uint64_t offset, uint64_t length) final;
-  void init_rm_free(uint64_t offset, uint64_t length) final;
-  void shutdown() final;
+  void dump() override;
+  void dump(std::function<void(uint64_t offset, uint64_t length)> notify) override;
+  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;
 
 private:
   template<class Tree>
   uint64_t _block_picker(const Tree& t, uint64_t *cursor, uint64_t size,
     uint64_t align);
-  void _add_to_tree(uint64_t start, uint64_t size);
-  void _remove_from_tree(uint64_t start, uint64_t size);
   int _allocate(
     uint64_t size,
     uint64_t unit,
@@ -157,13 +155,6 @@ private:
   */
   uint64_t range_count_cap = 0;
 
-  CephContext* cct;
-  std::mutex lock;
-
-  uint64_t _lowest_size_available() {
-    auto rs = range_size_tree.begin();
-    return rs != range_size_tree.end() ? rs->length() : 0;
-  }
   void _range_size_tree_rm(range_seg_t& r) {
     ceph_assert(num_free >= r.length());
     num_free -= r.length();
@@ -214,4 +205,34 @@ private:
     // i.e. (range_count_cap > 0)
     ceph_assert(false);
   }
+protected:
+  CephContext* cct;
+  std::mutex lock;
+
+  double _get_fragmentation() const {
+    auto free_blocks = p2align(num_free, block_size) / block_size;
+    if (free_blocks <= 1) {
+      return .0;
+    }
+    return (static_cast<double>(range_tree.size() - 1) / (free_blocks - 1));
+  }
+  void _dump() const;
+
+  uint64_t _lowest_size_available() {
+    auto rs = range_size_tree.begin();
+    return rs != range_size_tree.end() ? rs->length() : 0;
+  }
+
+  int64_t _allocate(
+    uint64_t want,
+    uint64_t unit,
+    uint64_t max_alloc_size,
+    int64_t  hint,
+    PExtentVector *extents);
+
+  void _release(const interval_set<uint64_t>& release_set);
+  void _shutdown();
+
+  void _add_to_tree(uint64_t start, uint64_t size);
+  void _remove_from_tree(uint64_t start, uint64_t size);
 };