]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix AU accounting in bluestore_cache_other mempool.
authorIgor Fedotov <ifedotov@suse.com>
Thu, 30 Jun 2022 13:34:04 +0000 (16:34 +0300)
committerIgor Fedotov <igor.fedotov@croit.io>
Thu, 28 Jul 2022 14:55:13 +0000 (17:55 +0300)
Fixes: https://tracker.ceph.com/issues/56424
Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159)

src/os/bluestore/bluestore_types.cc
src/os/bluestore/bluestore_types.h

index 121f7ccd3049f6aba8fd2478597212a49f3ab611..b62f6e2a3670b00ff7da37048685e0e9b364468f 100644 (file)
@@ -366,11 +366,12 @@ ostream& operator<<(ostream& out, const bluestore_extent_ref_map_t& m)
 bluestore_blob_use_tracker_t::bluestore_blob_use_tracker_t(
   const bluestore_blob_use_tracker_t& tracker)
  : au_size{tracker.au_size},
-   num_au{tracker.num_au},
+   num_au(0),
+   alloc_au(0),
    bytes_per_au{nullptr}
 {
-  if (num_au > 0) {
-    allocate();
+  if (tracker.num_au > 0) {
+    allocate(tracker.num_au);
     std::copy(tracker.bytes_per_au, tracker.bytes_per_au + num_au, bytes_per_au);
   } else {
     total_bytes = tracker.total_bytes;
@@ -385,9 +386,8 @@ bluestore_blob_use_tracker_t::operator=(const bluestore_blob_use_tracker_t& rhs)
   }
   clear();
   au_size = rhs.au_size;
-  num_au = rhs.num_au;
   if (rhs.num_au > 0) {
-    allocate();
+    allocate( rhs.num_au);
     std::copy(rhs.bytes_per_au, rhs.bytes_per_au + num_au, bytes_per_au);
   } else {
     total_bytes = rhs.total_bytes;
@@ -395,19 +395,31 @@ bluestore_blob_use_tracker_t::operator=(const bluestore_blob_use_tracker_t& rhs)
   return *this;
 }
 
-void bluestore_blob_use_tracker_t::allocate()
+void bluestore_blob_use_tracker_t::allocate(uint32_t au_count)
 {
-  ceph_assert(num_au != 0);
-  bytes_per_au = new uint32_t[num_au];
+  ceph_assert(au_count != 0);
+  ceph_assert(num_au == 0);
+  ceph_assert(alloc_au == 0);
+  num_au = alloc_au = au_count;
+  bytes_per_au = new uint32_t[alloc_au];
   mempool::get_pool(
     mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
-      adjust_count(1, sizeof(uint32_t) * num_au);
+      adjust_count(alloc_au, sizeof(uint32_t) * alloc_au);
 
   for (uint32_t i = 0; i < num_au; ++i) {
     bytes_per_au[i] = 0;
   }
 }
 
+void bluestore_blob_use_tracker_t::release(uint32_t au_count, uint32_t* ptr) {
+  if (au_count) {
+    delete[] ptr;
+    mempool::get_pool(
+      mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
+        adjust_count(-(int32_t)au_count, -(int32_t)(sizeof(uint32_t) * au_count));
+  }
+}
+
 void bluestore_blob_use_tracker_t::init(
   uint32_t full_length, uint32_t _au_size) {
   ceph_assert(!au_size || is_empty()); 
@@ -417,8 +429,7 @@ void bluestore_blob_use_tracker_t::init(
   uint32_t _num_au = round_up_to(full_length, _au_size) / _au_size;
   au_size = _au_size;
   if ( _num_au > 1 ) {
-    num_au = _num_au;
-    allocate();
+    allocate(_num_au);
   }
 }
 
index 584c33d7d674a7a0c88d86cb50eadd46e4a8cc47..b21531bfe5ed79e41fb76f2745a377006d8a9e18 100644 (file)
@@ -247,10 +247,11 @@ struct bluestore_blob_use_tracker_t {
   //   1) Struct isn't packed hence it's padded. And even if it's packed see 2)
   //   2) Mem manager has its own granularity, most probably >= 8 bytes
   //
-  uint32_t au_size; // Allocation (=tracking) unit size,
-                    // == 0 if uninitialized
-  uint32_t num_au;  // Amount of allocation units tracked
-                    // == 0 if single unit or the whole blob is tracked
+  uint32_t au_size;  // Allocation (=tracking) unit size,
+                     // == 0 if uninitialized
+  uint32_t num_au;   // Amount of allocation units tracked
+                     // == 0 if single unit or the whole blob is tracked
+  uint32_t alloc_au; // Amount of allocation units allocated
                        
   union {
     uint32_t* bytes_per_au;
@@ -258,7 +259,7 @@ struct bluestore_blob_use_tracker_t {
   };
   
   bluestore_blob_use_tracker_t()
-    : au_size(0), num_au(0), bytes_per_au(nullptr) {
+    : au_size(0), num_au(0), alloc_au(0), bytes_per_au(nullptr) {
   }
   bluestore_blob_use_tracker_t(const bluestore_blob_use_tracker_t& tracker);
   bluestore_blob_use_tracker_t& operator=(const bluestore_blob_use_tracker_t& rhs);
@@ -267,15 +268,11 @@ struct bluestore_blob_use_tracker_t {
   }
 
   void clear() {
-    if (num_au != 0) {
-      delete[] bytes_per_au;
-      mempool::get_pool(
-        mempool::pool_index_t(mempool::mempool_bluestore_cache_other)).
-          adjust_count(-1, -sizeof(uint32_t) * num_au);
-    }
+    release(alloc_au, bytes_per_au);
+    num_au = 0;
+    alloc_au = 0;
     bytes_per_au = 0;
     au_size = 0;
-    num_au = 0;
   }
 
   uint32_t get_referenced_bytes() const {
@@ -311,7 +308,6 @@ struct bluestore_blob_use_tracker_t {
       ceph_assert(_num_au <= num_au);
       if (_num_au) {
         num_au = _num_au; // bytes_per_au array is left unmodified
-
       } else {
         clear();
       }
@@ -337,15 +333,17 @@ struct bluestore_blob_use_tracker_t {
       if (_num_au > num_au) {
        auto old_bytes = bytes_per_au;
        auto old_num_au = num_au;
-       num_au = _num_au;
-       allocate();
+       auto old_alloc_au = alloc_au;
+       alloc_au = num_au = 0; // to bypass an assertion in allocate()
+       bytes_per_au = nullptr;
+       allocate(_num_au);
        for (size_t i = 0; i < old_num_au; i++) {
          bytes_per_au[i] = old_bytes[i];
        }
        for (size_t i = old_num_au; i < num_au; i++) {
          bytes_per_au[i] = 0;
        }
-       delete[] old_bytes;
+       release(old_alloc_au, old_bytes);
       }
     }
   }
@@ -410,12 +408,14 @@ struct bluestore_blob_use_tracker_t {
     clear();
     denc_varint(au_size, p);
     if (au_size) {
-      denc_varint(num_au, p);
-      if (!num_au) {
+      uint32_t _num_au;
+      denc_varint(_num_au, p);
+      if (!_num_au) {
+        num_au = 0;
         denc_varint(total_bytes, p);
       } else {
-        allocate();
-        for (size_t i = 0; i < num_au; ++i) {
+        allocate(_num_au);
+        for (size_t i = 0; i < _num_au; ++i) {
          denc_varint(bytes_per_au[i], p);
         }
       }
@@ -425,7 +425,8 @@ struct bluestore_blob_use_tracker_t {
   void dump(ceph::Formatter *f) const;
   static void generate_test_instances(std::list<bluestore_blob_use_tracker_t*>& o);
 private:
-  void allocate();
+  void allocate(uint32_t _num_au);
+  void release(uint32_t _num_au, uint32_t* ptr);
 };
 WRITE_CLASS_DENC(bluestore_blob_use_tracker_t)
 std::ostream& operator<<(std::ostream& out, const bluestore_blob_use_tracker_t& rm);