From 36216493f69d5721de86c24c9b25b99e47f8a38e Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Sun, 2 Jun 2024 14:56:32 +0800 Subject: [PATCH] crimson/os/seastore/lba_manager: batch alloc mappings when doing remaps Signed-off-by: Xuehan Xu (cherry picked from commit 28efb5180e8fc2497673594fb87fe4ed29af9ce6) --- src/crimson/os/seastore/cache.h | 6 +- .../lba_manager/btree/btree_lba_manager.h | 164 ++++++++++-------- src/crimson/os/seastore/transaction_manager.h | 6 +- 3 files changed, 103 insertions(+), 73 deletions(-) diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index 04138c463f5c3..5af65f4b9e438 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -953,10 +953,12 @@ public: NULL_GENERATION, t.get_trans_id()); + auto extent = ext->template cast(); + extent->set_laddr(remap_laddr); t.add_fresh_extent(ext); SUBTRACET(seastore_cache, "allocated {} {}B, hint={}, has ptr? {} -- {}", - t, T::TYPE, remap_length, remap_laddr, original_bptr.has_value(), *ext); - return ext; + t, T::TYPE, remap_length, remap_laddr, original_bptr.has_value(), *extent); + return extent; } /** diff --git a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h index 7a4dbbd5c26ed..617e1e29ec213 100644 --- a/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h +++ b/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h @@ -287,12 +287,16 @@ public: laddr_t intermediate_key, laddr_t intermediate_base) final { - return alloc_cloned_mapping( + std::vector alloc_infos = { + alloc_mapping_info_t::create_indirect( + laddr, len, intermediate_key)}; + return alloc_cloned_mappings( t, laddr, - len, - intermediate_key - ).si_then([&t, this, intermediate_base](auto imapping) { + std::move(alloc_infos) + ).si_then([&t, this, intermediate_base](auto imappings) { + assert(imappings.size() == 1); + auto &imapping = imappings.front(); return update_refcount(t, intermediate_base, 1, false ).si_then([imapping=std::move(imapping)](auto p) mutable { auto mapping = std::move(p.mapping); @@ -397,7 +401,7 @@ public: std::move(remaps), std::move(extents), std::move(orig_mapping), - [&t, FNAME, this](auto &ret, auto &remaps, + [&t, FNAME, this](auto &ret, const auto &remaps, auto &extents, auto &orig_mapping) { return update_refcount(t, orig_mapping->get_key(), -1, false ).si_then([&ret, this, &extents, &remaps, @@ -408,68 +412,80 @@ public: ret.ruret.addr.is_paddr() && !ret.ruret.addr.get_paddr().is_zero()); } - return trans_intr::do_for_each( - boost::make_counting_iterator(size_t(0)), - boost::make_counting_iterator(remaps.size()), - [&remaps, &t, this, &orig_mapping, &extents, FNAME, &ret](auto i) { - laddr_t orig_laddr = orig_mapping->get_key(); - extent_len_t orig_len = orig_mapping->get_length(); - paddr_t orig_paddr = orig_mapping->get_val(); - laddr_t intermediate_base = orig_mapping->is_indirect() - ? orig_mapping->get_intermediate_base() - : L_ADDR_NULL; - laddr_t intermediate_key = orig_mapping->is_indirect() - ? orig_mapping->get_intermediate_key() - : L_ADDR_NULL; - auto &remap = remaps[i]; - auto remap_offset = remap.offset; - auto remap_len = remap.len; - auto remap_laddr = orig_laddr + remap_offset; - auto remap_paddr = orig_paddr.add_offset(remap_offset); - if (orig_mapping->is_indirect()) { + auto fut = alloc_extent_iertr::make_ready_future< + std::vector>(); + laddr_t orig_laddr = orig_mapping->get_key(); + if (orig_mapping->is_indirect()) { + std::vector alloc_infos; + for (auto &remap : remaps) { + extent_len_t orig_len = orig_mapping->get_length(); + paddr_t orig_paddr = orig_mapping->get_val(); + laddr_t intermediate_base = orig_mapping->is_indirect() + ? orig_mapping->get_intermediate_base() + : L_ADDR_NULL; + laddr_t intermediate_key = orig_mapping->is_indirect() + ? orig_mapping->get_intermediate_key() + : L_ADDR_NULL; + auto remap_offset = remap.offset; + auto remap_len = remap.len; + auto remap_laddr = orig_laddr + remap_offset; ceph_assert(intermediate_base != L_ADDR_NULL); ceph_assert(intermediate_key != L_ADDR_NULL); - remap_paddr = orig_paddr; - } - ceph_assert(remap_len < orig_len); - ceph_assert(remap_offset + remap_len <= orig_len); - ceph_assert(remap_len != 0); - SUBDEBUGT(seastore_lba, - "remap laddr: {}, remap paddr: {}, remap length: {}," - " intermediate_base: {}, intermediate_key: {}", t, - remap_laddr, remap_paddr, remap_len, - intermediate_base, intermediate_key); - auto fut = alloc_extent_iertr::make_ready_future(); - if (orig_mapping->is_indirect()) { - assert(intermediate_base != L_ADDR_NULL - && intermediate_key != L_ADDR_NULL); + ceph_assert(remap_len < orig_len); + ceph_assert(remap_offset + remap_len <= orig_len); + ceph_assert(remap_len != 0); + SUBDEBUGT(seastore_lba, + "remap laddr: {}, remap paddr: {}, remap length: {}," + " intermediate_base: {}, intermediate_key: {}", t, + remap_laddr, orig_paddr, remap_len, + intermediate_base, intermediate_key); auto remapped_intermediate_key = intermediate_key + remap_offset; - fut = alloc_cloned_mapping( - t, - remap_laddr, - remap_len, - remapped_intermediate_key - ).si_then([&orig_mapping](auto imapping) mutable { + alloc_infos.emplace_back( + alloc_mapping_info_t::create_indirect( + remap_laddr, + remap_len, + remapped_intermediate_key)); + } + fut = alloc_cloned_mappings( + t, + remaps.front().offset + orig_laddr, + std::move(alloc_infos) + ).si_then([&orig_mapping](auto imappings) mutable { + std::vector mappings; + for (auto &imapping : imappings) { auto mapping = orig_mapping->duplicate(); auto bmapping = static_cast(mapping.get()); bmapping->adjust_mutable_indirect_attrs( imapping->get_key(), imapping->get_length(), imapping->get_intermediate_key()); - return seastar::make_ready_future( - std::move(mapping)); - }); - } else { - fut = alloc_extent(t, remap_laddr, *extents[i]); - } - return fut.si_then([remap_laddr, remap_len, &ret, - remap_paddr](auto &&ref) { - assert(ref->get_key() == remap_laddr); - assert(ref->get_val() == remap_paddr); - assert(ref->get_length() == remap_len); - ret.remapped_mappings.emplace_back(std::move(ref)); - return seastar::now(); + mappings.emplace_back(std::move(mapping)); + } + return seastar::make_ready_future>( + std::move(mappings)); }); + } else { // !orig_mapping->is_indirect() + fut = alloc_extents( + t, + remaps.front().offset + orig_laddr, + std::move(extents), + EXTENT_DEFAULT_REF_COUNT); + } + + return fut.si_then([&ret, &remaps, &orig_mapping](auto &&refs) { + assert(refs.size() == remaps.size()); +#ifndef NDEBUG + auto ref_it = refs.begin(); + auto remap_it = remaps.begin(); + for (;ref_it != refs.end(); ref_it++, remap_it++) { + auto &ref = *ref_it; + auto &remap = *remap_it; + assert(ref->get_key() == orig_mapping->get_key() + remap.offset); + assert(ref->get_length() == remap.len); + } +#endif + ret.remapped_mappings = std::move(refs); + return seastar::now(); }); }).si_then([&remaps, &t, &orig_mapping, this] { if (remaps.size() > 1 && orig_mapping->is_indirect()) { @@ -599,15 +615,16 @@ private: }); } - alloc_extent_iertr::future alloc_cloned_mapping( + alloc_extent_iertr::future> alloc_cloned_mappings( Transaction &t, laddr_t laddr, - extent_len_t len, - laddr_t intermediate_key) + std::vector alloc_infos) { - assert(intermediate_key != L_ADDR_NULL); - std::vector alloc_infos = { - alloc_mapping_info_t::create_indirect(L_ADDR_NULL, len, intermediate_key)}; +#ifndef NDEBUG + for (auto &alloc_info : alloc_infos) { + assert(alloc_info.val.get_laddr() != L_ADDR_NULL); + } +#endif return seastar::do_with( std::move(alloc_infos), [this, &t, laddr](auto &alloc_infos) { @@ -616,12 +633,21 @@ private: laddr, alloc_infos, EXTENT_DEFAULT_REF_COUNT - ).si_then([laddr](auto mappings) { - ceph_assert(mappings.size() == 1); - auto mapping = std::move(mappings.front()); - ceph_assert(mapping->get_key() == laddr); - return std::unique_ptr( - static_cast(mapping.release())); + ).si_then([&alloc_infos](auto mappings) { + assert(alloc_infos.size() == mappings.size()); + std::vector rets; + auto mit = mappings.begin(); + auto ait = alloc_infos.begin(); + for (; mit != mappings.end(); mit++, ait++) { + auto mapping = static_cast(mit->release()); + auto &alloc_info = *ait; + assert(mapping->get_key() == alloc_info.key); + assert(mapping->get_raw_val().get_laddr() == + alloc_info.val.get_laddr()); + assert(mapping->get_length() == alloc_info.len); + rets.emplace_back(mapping); + } + return rets; }); }); } diff --git a/src/crimson/os/seastore/transaction_manager.h b/src/crimson/os/seastore/transaction_manager.h index cc3abe42d9d74..c0aa518a6790a 100644 --- a/src/crimson/os/seastore/transaction_manager.h +++ b/src/crimson/os/seastore/transaction_manager.h @@ -413,6 +413,7 @@ public: Transaction &t, LBAMappingRef &&pin, std::array remaps) { + static_assert(std::is_base_of_v); #ifndef NDEBUG std::sort(remaps.begin(), remaps.end(), @@ -496,13 +497,14 @@ public: SUBDEBUGT(seastore_tm, "remap laddr: {}, remap paddr: {}, remap length: {}", t, remap_laddr, remap_paddr, remap_len); - extents.emplace_back(cache->alloc_remapped_extent( + auto extent = cache->alloc_remapped_extent( t, remap_laddr, remap_paddr, remap_len, original_laddr, - original_bptr)); + original_bptr); + extents.emplace_back(std::move(extent)); } }); } -- 2.39.5