]> git-server-git.apps.pok.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>
Fri, 15 Mar 2019 11:20:01 +0000 (14:20 +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>
src/os/bluestore/fastbmap_allocator_impl.cc
src/os/bluestore/fastbmap_allocator_impl.h
src/test/objectstore/fastbmap_allocator_test.cc

index f53d31a6fc7f26e4c18de8cfd2d88c7104931608..f6369071baaa3b9faaba45fbd1b7f2649c5e4420 100755 (executable)
@@ -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<uint32_t>(res.length, min_length);
+      res.length = p2align<uint64_t>(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<uint32_t>(longest.length, min_length);
+          ctx->min_affordable_len = p2align<uint64_t>(longest.length, min_length);
          ctx->min_affordable_offs = longest.offset;
         }
         if (mode == STOP_ON_PARTIAL) {
index d043715ca0a3587fabde1340bf0873ef15495e17..1c9cd3af080ee59ae3d20707df5cda67bc2a13e0 100755 (executable)
@@ -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_t> slot_vector_t;
 #include "include/mempool.h"
 #include "common/ceph_mutex.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 709db601916921c16b57725b8bea40625199ef00..650a452c0005ac28fd49e02403392cb4c8afdba1 100755 (executable)
@@ -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<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);
+  }
+}