From: Xuehan Xu Date: Thu, 18 Jan 2024 03:21:19 +0000 (+0800) Subject: crimson/os/seastore/avlallocator: add the interface that allocate X-Git-Tag: v19.3.0~72^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cde33fcae7526303b6f9eba30c49d46b404da087;p=ceph.git crimson/os/seastore/avlallocator: add the interface that allocate multiple regions Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/random_block_manager.h b/src/crimson/os/seastore/random_block_manager.h index d9be1b5e6d9..f0e0f018bd1 100644 --- a/src/crimson/os/seastore/random_block_manager.h +++ b/src/crimson/os/seastore/random_block_manager.h @@ -22,6 +22,11 @@ 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; + using allo_extents_ret = allocate_ertr::future; + 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; diff --git a/src/crimson/os/seastore/random_block_manager/avlallocator.cc b/src/crimson/os/seastore/random_block_manager/avlallocator.cc index 28137a23d79..51624b1c8b2 100644 --- a/src/crimson/os/seastore/random_block_manager/avlallocator.cc +++ b/src/crimson/os/seastore/random_block_manager/avlallocator.cc @@ -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> AvlAllocator::alloc_extent( return result; } +std::optional> 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 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); diff --git a/src/crimson/os/seastore/random_block_manager/avlallocator.h b/src/crimson/os/seastore/random_block_manager/avlallocator.h index d1a4fabca5a..fa703994e3f 100644 --- a/src/crimson/os/seastore/random_block_manager/avlallocator.h +++ b/src/crimson/os/seastore/random_block_manager/avlallocator.h @@ -64,6 +64,8 @@ public: detailed(detailed) {} std::optional> alloc_extent( size_t size) final; + std::optional> 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< diff --git a/src/crimson/os/seastore/random_block_manager/block_rb_manager.cc b/src/crimson/os/seastore/random_block_manager/block_rb_manager.cc index 511b70a2eec..6bae96f84a5 100644 --- a/src/crimson/os/seastore/random_block_manager/block_rb_manager.cc +++ b/src/crimson/os/seastore/random_block_manager/block_rb_manager.cc @@ -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.get_len())}); + } + ceph_assert(size == len); + return ret; +} + void BlockRBManager::complete_allocation( paddr_t paddr, size_t size) { diff --git a/src/crimson/os/seastore/random_block_manager/block_rb_manager.h b/src/crimson/os/seastore/random_block_manager/block_rb_manager.h index b686820d066..14d2a28a314 100644 --- a/src/crimson/os/seastore/random_block_manager/block_rb_manager.h +++ b/src/crimson/os/seastore/random_block_manager/block_rb_manager.h @@ -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 { diff --git a/src/crimson/os/seastore/random_block_manager/extent_allocator.h b/src/crimson/os/seastore/random_block_manager/extent_allocator.h index 8a3e62c6d05..e3d3c800348 100644 --- a/src/crimson/os/seastore/random_block_manager/extent_allocator.h +++ b/src/crimson/os/seastore/random_block_manager/extent_allocator.h @@ -26,6 +26,17 @@ public: */ virtual std::optional> alloc_extent( size_t size) = 0; + + /** + * alloc_extents + * + * Allocate regions for the given size. A continuous region is returned + * if possible. + * + */ + virtual std::optional> alloc_extents( + size_t size) = 0; + /** * free_extent *