From: Igor Fedotov Date: Wed, 12 Feb 2020 13:17:40 +0000 (+0300) Subject: os/bluestore: make AvlAllocator overridable. X-Git-Tag: v17.0.0~2640^2~8 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=59c0aa5eb40957364ddb0e9d62dffa3449991249;p=ceph.git os/bluestore: make AvlAllocator overridable. Signed-off-by: Igor Fedotov --- diff --git a/src/os/bluestore/AvlAllocator.cc b/src/os/bluestore/AvlAllocator.cc index abc130a41a25d..c6f63fe35bf5d 100644 --- a/src/os/bluestore/AvlAllocator.cc +++ b/src/os/bluestore/AvlAllocator.cc @@ -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& 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& release_set) -{ +void AvlAllocator::release(const interval_set& 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(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(); } diff --git a/src/os/bluestore/AvlAllocator.h b/src/os/bluestore/AvlAllocator.h index 0ad3c99c6a2e6..79bb3f42d2fda 100644 --- a/src/os/bluestore/AvlAllocator.h +++ b/src/os/bluestore/AvlAllocator.h @@ -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& release_set) final; - uint64_t get_free() final; - double get_fragmentation() final; + PExtentVector *extents) override; + void release(const interval_set& release_set) override; + uint64_t get_free() override; + double get_fragmentation() override; - void dump() final; - void dump(std::function 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 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 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(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& release_set); + void _shutdown(); + + void _add_to_tree(uint64_t start, uint64_t size); + void _remove_from_tree(uint64_t start, uint64_t size); };