From 1d61be04a08b15b60c556be9d89f67670ff7a7d9 Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Wed, 13 Mar 2019 19:09:40 +0300 Subject: [PATCH] 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 (cherry picked from commit d1466963a60ed2345a6fc159071ec09ce422b656) --- src/os/bluestore/fastbmap_allocator_impl.h | 4 +- .../objectstore/fastbmap_allocator_test.cc | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/os/bluestore/fastbmap_allocator_impl.h b/src/os/bluestore/fastbmap_allocator_impl.h index 7e9c1452b85d2..7cb92a1fa2705 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) {} @@ -36,7 +36,7 @@ typedef std::vector slot_vector_t; #include "os/bluestore/bluestore_types.h" #include "include/mempool.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 b437ca9dcbd71..222fde3ca374d 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(0, 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 " @@ -865,4 +865,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); + } +} -- 2.39.5