From: Igor Fedotov Date: Wed, 13 Mar 2019 16:09:40 +0000 (+0300) Subject: os/bluestore: start using 64-bit intervals for bitmap allocator X-Git-Tag: v15.0.0~121^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d1466963a60ed2345a6fc159071ec09ce422b656;p=ceph.git os/bluestore: start using 64-bit intervals for bitmap allocator This helps to avoid 4Gb+ values wrapping which resulted in allocation failures. Fixes: https://tracker.ceph.com/issues/38761 Signed-off-by: Igor Fedotov --- diff --git a/src/os/bluestore/fastbmap_allocator_impl.cc b/src/os/bluestore/fastbmap_allocator_impl.cc index f53d31a6fc7f..f6369071baaa 100755 --- a/src/os/bluestore/fastbmap_allocator_impl.cc +++ b/src/os/bluestore/fastbmap_allocator_impl.cc @@ -23,7 +23,7 @@ inline interval_t _align2units(uint64_t offset, uint64_t len, uint64_t min_lengt auto delta_off = res.offset - offset; if (len > delta_off) { res.length = len - delta_off; - res.length = p2align(res.length, min_length); + res.length = p2align(res.length, min_length); if (res.length) { return res; } @@ -189,7 +189,7 @@ void AllocatorLevel01Loose::_analyze_partials(uint64_t pos_start, (ctx->min_affordable_len == 0 || (longest.length < ctx->min_affordable_len))) { - ctx->min_affordable_len = p2align(longest.length, min_length); + ctx->min_affordable_len = p2align(longest.length, min_length); ctx->min_affordable_offs = longest.offset; } if (mode == STOP_ON_PARTIAL) { diff --git a/src/os/bluestore/fastbmap_allocator_impl.h b/src/os/bluestore/fastbmap_allocator_impl.h index d043715ca0a3..1c9cd3af080e 100755 --- a/src/os/bluestore/fastbmap_allocator_impl.h +++ b/src/os/bluestore/fastbmap_allocator_impl.h @@ -21,7 +21,7 @@ typedef uint64_t slot_t; struct interval_t { uint64_t offset = 0; - uint32_t length = 0; + uint64_t length = 0; interval_t() {} interval_t(uint64_t o, uint64_t l) : offset(o), length(l) {} @@ -37,7 +37,7 @@ typedef std::vector slot_vector_t; #include "include/mempool.h" #include "common/ceph_mutex.h" -typedef bluestore_pextent_t interval_t; +typedef bluestore_interval_t interval_t; typedef PExtentVector interval_vector_t; typedef mempool::bluestore_alloc::vector slot_vector_t; diff --git a/src/test/objectstore/fastbmap_allocator_test.cc b/src/test/objectstore/fastbmap_allocator_test.cc index 709db6019169..650a452c0005 100755 --- a/src/test/objectstore/fastbmap_allocator_test.cc +++ b/src/test/objectstore/fastbmap_allocator_test.cc @@ -346,7 +346,7 @@ TEST(TestAllocatorLevel01, test_l2) ASSERT_EQ(0u, al2.debug_get_free()); for (uint64_t i = 0; i < capacity; i += _1m) { interval_vector_t r; - r.emplace_back(interval_t(i, _1m)); + r.emplace_back(i, _1m); al2.free_l2(r); if (0 == (i % (1 * 1024 * _1m))) { std::cout << "free1 " << i / 1024 / 1024 << " mb of " @@ -378,7 +378,7 @@ TEST(TestAllocatorLevel01, test_l2) for (uint64_t i = 0; i < capacity; i += 0x2000) { interval_vector_t r; - r.emplace_back(interval_t(i, 0x1000)); + r.emplace_back(i, 0x1000); al2.free_l2(r); if (0 == (i % (1 * 1024 * _1m))) { std::cout << "free2 " << i / 1024 / 1024 << " mb of " @@ -870,4 +870,46 @@ TEST(TestAllocatorLevel01, test_4G_alloc_bug) ASSERT_EQ(a4[0].offset, 0u); ASSERT_EQ(a4[0].length, _1m); } -} \ No newline at end of file +} + +TEST(TestAllocatorLevel01, test_4G_alloc_bug2) +{ + { + TestAllocatorLevel02 al2; + uint64_t capacity = 0x8000 * _1m; // = 32GB + al2.init(capacity, 0x10000); + + for (uint64_t i = 0; i < capacity; i += _1m) { + uint64_t allocated4 = 0; + interval_vector_t a4; + al2.allocate_l2(_1m, _1m, &allocated4, &a4); + ASSERT_EQ(a4.size(), 1u); + ASSERT_EQ(allocated4, _1m); + ASSERT_EQ(a4[0].offset, i); + ASSERT_EQ(a4[0].length, _1m); + } + ASSERT_EQ(0u , al2.debug_get_free()); + + interval_vector_t r; + r.emplace_back(0x5fec30000, 0x13d0000); + r.emplace_back(0x628000000, 0x80000000); + r.emplace_back(0x6a8000000, 0x80000000); + r.emplace_back(0x728100000, 0x70000); + al2.free_l2(r); + + std::map bins_overall; + al2.collect_stats(bins_overall); + + std::cout << "!!!!!!!!!!!!!!" << std::endl; + + uint64_t allocated4 = 0; + interval_vector_t a4; + al2.allocate_l2(0x3e000000, _1m, &allocated4, &a4); + ASSERT_EQ(a4.size(), 2u); + ASSERT_EQ(allocated4, 0x3e000000u); + ASSERT_EQ(a4[0].offset, 0x5fed00000u); + ASSERT_EQ(a4[0].length, 0x1300000u); + ASSERT_EQ(a4[1].offset, 0x628000000u); + ASSERT_EQ(a4[1].length, 0x3cd00000u); + } +}