]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/os/bluestore/StupidAllocator.cc
import ceph 12.2.12
[ceph.git] / ceph / src / os / bluestore / StupidAllocator.cc
index 65d7baf59d8b1b31cfdbc5d05af9f6f3367c6dc5..c7224ea8c4e86b9836fd03c2e576197d0a8ee48b 100644 (file)
@@ -12,7 +12,6 @@
 
 StupidAllocator::StupidAllocator(CephContext* cct)
   : cct(cct), num_free(0),
-    num_reserved(0),
     free(10),
     last_alloc(0)
 {
@@ -48,28 +47,6 @@ void StupidAllocator::_insert_free(uint64_t off, uint64_t len)
   }
 }
 
-int StupidAllocator::reserve(uint64_t need)
-{
-  std::lock_guard<std::mutex> l(lock);
-  dout(10) << __func__ << " need 0x" << std::hex << need
-          << " num_free 0x" << num_free
-          << " num_reserved 0x" << num_reserved << std::dec << dendl;
-  if ((int64_t)need > num_free - num_reserved)
-    return -ENOSPC;
-  num_reserved += need;
-  return 0;
-}
-
-void StupidAllocator::unreserve(uint64_t unused)
-{
-  std::lock_guard<std::mutex> l(lock);
-  dout(10) << __func__ << " unused 0x" << std::hex << unused
-          << " num_free 0x" << num_free
-          << " num_reserved 0x" << num_reserved << std::dec << dendl;
-  assert(num_reserved >= (int64_t)unused);
-  num_reserved -= unused;
-}
-
 /// return the effective length of the extent if we align to alloc_unit
 uint64_t StupidAllocator::_aligned_len(
   StupidAllocator::interval_set_t::iterator p,
@@ -195,9 +172,7 @@ int64_t StupidAllocator::allocate_int(
   }
 
   num_free -= *length;
-  num_reserved -= *length;
   assert(num_free >= 0);
-  assert(num_reserved >= 0);
   last_alloc = *offset + *length;
   return 0;
 }
@@ -207,7 +182,7 @@ int64_t StupidAllocator::allocate(
   uint64_t alloc_unit,
   uint64_t max_alloc_size,
   int64_t hint,
-  mempool::bluestore_alloc::vector<AllocExtent> *extents)
+  PExtentVector *extents)
 {
   uint64_t allocated_size = 0;
   uint64_t offset = 0;
@@ -218,8 +193,6 @@ int64_t StupidAllocator::allocate(
     max_alloc_size = want_size;
   }
 
-  ExtentList block_list = ExtentList(extents, 1, max_alloc_size);
-
   while (allocated_size < want_size) {
     res = allocate_int(MIN(max_alloc_size, (want_size - allocated_size)),
        alloc_unit, hint, &offset, &length);
@@ -229,7 +202,19 @@ int64_t StupidAllocator::allocate(
        */
       break;
     }
-    block_list.add_extents(offset, length);
+    bool can_append = true;
+    if (!extents->empty()) {
+      bluestore_pextent_t &last_extent  = extents->back();
+      if ((last_extent.end() == offset) &&
+         ((last_extent.length + length) <= max_alloc_size)) {
+       can_append = false;
+       last_extent.length += length;
+      }
+    }
+    if (can_append) {
+      extents->emplace_back(bluestore_pextent_t(offset, length));
+    }
+
     allocated_size += length;
     hint = offset + length;
   }
@@ -241,13 +226,19 @@ int64_t StupidAllocator::allocate(
 }
 
 void StupidAllocator::release(
-  uint64_t offset, uint64_t length)
+  const interval_set<uint64_t>& release_set)
 {
   std::lock_guard<std::mutex> l(lock);
-  dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
-          << std::dec << dendl;
-  _insert_free(offset, length);
-  num_free += length;
+  for (interval_set<uint64_t>::const_iterator 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__ << " 0x" << std::hex << offset << "~" << length
+                  << std::dec << dendl;
+    _insert_free(offset, length);
+    num_free += length;
+  }
 }
 
 uint64_t StupidAllocator::get_free()
@@ -256,6 +247,31 @@ uint64_t StupidAllocator::get_free()
   return num_free;
 }
 
+double StupidAllocator::get_fragmentation(uint64_t alloc_unit)
+{
+  assert(alloc_unit);
+  double res;
+  uint64_t max_intervals = 0;
+  uint64_t intervals = 0;
+  {
+    std::lock_guard<std::mutex> l(lock);
+    max_intervals = num_free / alloc_unit;
+    for (unsigned bin = 0; bin < free.size(); ++bin) {
+      intervals += free[bin].num_intervals();
+    }
+  }
+  ldout(cct, 30) << __func__ << " " << intervals << "/" << max_intervals 
+                 << dendl;
+  assert(intervals <= max_intervals);
+  if (!intervals || max_intervals <= 1) {
+    return 0.0;
+  }
+  intervals--;
+  max_intervals--;
+  res = (double)intervals / max_intervals;
+  return res;
+}
+
 void StupidAllocator::dump()
 {
   std::lock_guard<std::mutex> l(lock);