]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/avlallocator: add the interface that allocate
authorXuehan Xu <xuxuehan@qianxin.com>
Thu, 18 Jan 2024 03:21:19 +0000 (11:21 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Thu, 1 Feb 2024 07:00:09 +0000 (15:00 +0800)
multiple regions

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/random_block_manager.h
src/crimson/os/seastore/random_block_manager/avlallocator.cc
src/crimson/os/seastore/random_block_manager/avlallocator.h
src/crimson/os/seastore/random_block_manager/block_rb_manager.cc
src/crimson/os/seastore/random_block_manager/block_rb_manager.h
src/crimson/os/seastore/random_block_manager/extent_allocator.h

index d9be1b5e6d9cafafc9eeb66bc548c39b57fe6d63..f0e0f018bd1034dfbba1fca87a8276792a34a7c2 100644 (file)
 
 namespace crimson::os::seastore {
 
+struct alloc_paddr_result {
+  paddr_t start;
+  extent_len_t len;
+};
+
 struct rbm_shard_info_t {
   std::size_t size = 0;
   uint64_t start_offset = 0;
@@ -125,6 +130,10 @@ public:
   // allocator, return start addr of allocated blocks
   virtual paddr_t alloc_extent(size_t size) = 0;
 
+  using allocate_ret_bare = std::list<alloc_paddr_result>;
+  using allo_extents_ret = allocate_ertr::future<allocate_ret_bare>;
+  virtual allocate_ret_bare alloc_extents(size_t size) = 0;
+
   virtual void mark_space_used(paddr_t paddr, size_t len) = 0;
   virtual void mark_space_free(paddr_t paddr, size_t len) = 0;
 
index 28137a23d798e042a4f1d4cf2210c11415e91258..51624b1c8b2950a7888a12e55d67dc767baff946 100644 (file)
@@ -87,6 +87,33 @@ rbm_abs_addr AvlAllocator::find_block(size_t size)
   return total_size;
 }
 
+extent_len_t AvlAllocator::find_block(
+  size_t size,
+  rbm_abs_addr &start)
+{
+  uint64_t max_size = 0;
+  auto p = extent_size_tree.rbegin();
+  if (p != extent_size_tree.rend()) {
+    max_size = p->end - p->start;
+  }
+
+  assert(max_size);
+  if (max_size <= size) {
+    start = p->start;
+    return max_size;
+  }
+
+  const auto comp = extent_size_tree.key_comp();
+  auto iter = extent_size_tree.lower_bound(
+    extent_range_t{base_addr, base_addr + size}, comp);
+  ceph_assert(iter != extent_size_tree.end());
+  ceph_assert(is_aligned(iter->start, block_size));
+  ceph_assert(size <= iter->length());
+  start = iter->start;
+  return size;
+}
+
+
 void AvlAllocator::_add_to_tree(rbm_abs_addr start, rbm_abs_addr size)
 {
   LOG_PREFIX(AvlAllocator::_add_to_tree);
@@ -174,6 +201,50 @@ std::optional<interval_set<rbm_abs_addr>> AvlAllocator::alloc_extent(
   return result;
 }
 
+std::optional<interval_set<rbm_abs_addr>> AvlAllocator::alloc_extents(
+  size_t size)
+{
+  LOG_PREFIX(AvlAllocator::alloc_extents);
+  if (available_size < size) {
+    return std::nullopt;
+  }
+  if (extent_size_tree.empty()) {
+    return std::nullopt;
+  }
+  ceph_assert(size > 0);
+  ceph_assert(is_aligned(size, block_size));
+
+  interval_set<rbm_abs_addr> result;
+
+  auto try_to_alloc_block = [this, &result, FNAME] (uint64_t alloc_size)
+  {
+    while (alloc_size) {
+      rbm_abs_addr start = 0;
+      extent_len_t len = find_block(alloc_size, start);
+      ceph_assert(len);
+      _remove_from_tree(start, len);
+      DEBUG("allocate addr: {}, allocate size: {}, available size: {}",
+       start, len, available_size);
+      result.insert(start, len);
+      alloc_size -= len;
+    }
+    return 0;
+  };
+  
+  auto alloc = std::min(max_alloc_size, size);
+  try_to_alloc_block(alloc);
+
+  assert(!result.empty());
+  for (auto p : result) {
+    INFO("result start: {}, end: {}", p.first, p.first + p.second);
+    if (detailed) {
+      assert(!reserved_extent_tracker.contains(p.first, p.second));
+      reserved_extent_tracker.insert(p.first, p.second);
+    }
+  }
+  return result;
+}
+
 void AvlAllocator::free_extent(rbm_abs_addr addr, size_t size)
 {
   assert(total_size);
index d1a4fabca5a4c550316a058b33e41ed70575027f..fa703994e3f1ba9dfdcb964d313def8250d96510 100644 (file)
@@ -64,6 +64,8 @@ public:
     detailed(detailed) {}
   std::optional<interval_set<rbm_abs_addr>> alloc_extent(
     size_t size) final;
+  std::optional<interval_set<rbm_abs_addr>> alloc_extents(
+    size_t size) final;
 
   void free_extent(rbm_abs_addr addr, size_t size) final;
   void mark_extent_used(rbm_abs_addr addr, size_t size) final;
@@ -141,6 +143,7 @@ private:
 
   void _remove_from_tree(rbm_abs_addr start, rbm_abs_addr size);
   rbm_abs_addr find_block(size_t size);
+  extent_len_t find_block(size_t size, rbm_abs_addr &start);
 
   using extent_tree_t = 
     boost::intrusive::avl_set<
index 511b70a2eec9f0b8ba73a38d5bc31ac60dfa1dba..6bae96f84a5ad4385d075b2ba764a2d27ca92815 100644 (file)
@@ -62,6 +62,34 @@ paddr_t BlockRBManager::alloc_extent(size_t size)
   return paddr;
 }
 
+BlockRBManager::allocate_ret_bare
+BlockRBManager::alloc_extents(size_t size)
+{
+  LOG_PREFIX(BlockRBManager::alloc_extents);
+  assert(allocator);
+  auto alloc = allocator->alloc_extents(size);
+  if (!alloc) {
+    return {};
+  }
+  allocate_ret_bare ret;
+  size_t len = 0;
+  for (auto extent = (*alloc).begin();
+       extent != (*alloc).end();
+       extent++) {
+    len += extent.get_len();
+    paddr_t paddr = convert_abs_addr_to_paddr(
+      extent.get_start(),
+      device->get_device_id());
+    DEBUG("allocated addr: {}, size: {}, requested size: {}",
+         paddr, extent.get_len(), size);
+    ret.push_back(
+      {std::move(paddr),
+      static_cast<extent_len_t>(extent.get_len())});
+  }
+  ceph_assert(size == len);
+  return ret;
+}
+
 void BlockRBManager::complete_allocation(
     paddr_t paddr, size_t size)
 {
index b686820d066ea3943e50a5d12d47f7b2bae6baaa..14d2a28a314609a85922982fcc9b83e6b8148ce8 100644 (file)
@@ -54,11 +54,11 @@ public:
    * To do so, alloc_extent() looks into both in-memory allocator
    * and freebitmap blocks.
    *
-   * TODO: multiple allocation
-   *
    */
   paddr_t alloc_extent(size_t size) final; // allocator, return blocks
 
+  allocate_ret_bare alloc_extents(size_t size) final; // allocator, return blocks
+
   void complete_allocation(paddr_t addr, size_t size) final;
 
   size_t get_start_rbm_addr() const {
index 8a3e62c6d0502593dd54a9b6f2c549e7b393322a..e3d3c8003486f5a042e5e1e1a777724e8f263b0b 100644 (file)
@@ -26,6 +26,17 @@ public:
    */
   virtual std::optional<interval_set<rbm_abs_addr>> alloc_extent(
     size_t size) = 0;
+
+  /**
+   * alloc_extents
+   *
+   * Allocate regions for the given size. A continuous region is returned
+   * if possible.
+   *
+   */
+  virtual std::optional<interval_set<rbm_abs_addr>> alloc_extents(
+    size_t size) = 0;
+
   /**
    * free_extent
    *