]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: start using 64-bit intervals for bitmap allocator
authorIgor Fedotov <ifedotov@suse.com>
Wed, 13 Mar 2019 16:09:40 +0000 (19:09 +0300)
committerIgor Fedotov <ifedotov@suse.com>
Tue, 2 Apr 2019 09:51:59 +0000 (12:51 +0300)
This helps to avoid 4Gb+ values wrapping which resulted in
allocation failures.

Fixes: https://tracker.ceph.com/issues/38761
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
(cherry picked from commit d1466963a60ed2345a6fc159071ec09ce422b656)

src/os/bluestore/fastbmap_allocator_impl.h
src/test/objectstore/fastbmap_allocator_test.cc

index 5413fb67037c91e144915495fe7c2e37357a84cd..6bf8c30f58d55286241294ebf0d05daac1a76b4a 100755 (executable)
@@ -22,7 +22,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_t> slot_vector_t;
 #include "os/bluestore/bluestore_types.h"
 #include "include/mempool.h"
 
-typedef bluestore_pextent_t interval_t;
+typedef bluestore_interval_t<uint64_t, uint64_t> interval_t;
 typedef PExtentVector interval_vector_t;
 
 typedef mempool::bluestore_alloc::vector<slot_t> slot_vector_t;
index f5a046858f685db7d00d3bc25f134aa87c21cf6f..3bc9a188cedff5f5625fab83bd86dd7cd4da8186 100755 (executable)
@@ -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 "
@@ -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<size_t, size_t> 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);
+  }
+}