diff -Nru ceph-16.2.9/debian/changelog ceph-16.2.9/debian/changelog --- ceph-16.2.9/debian/changelog 2022-06-13 10:14:15.000000000 +0000 +++ ceph-16.2.9/debian/changelog 2022-12-16 02:45:36.000000000 +0000 @@ -1,3 +1,10 @@ +ceph (16.2.9-0ubuntu0.21.10.1~cloud0ubuntu1) focal; urgency=medium + + * d/p/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + fix the leak in bluestore_cache_mempool + + -- Dongdong Tao Fri, 16 Dec 2022 02:45:36 +0000 + ceph (16.2.9-0ubuntu0.21.10.1~cloud0) focal-xena; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru ceph-16.2.9/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-16.2.9/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-16.2.9/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-16.2.9/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-12-16 02:43:28.000000000 +0000 @@ -0,0 +1,201 @@ +From ed957f632eeb60e3b752c1098228e6a29c5380c6 Mon Sep 17 00:00:00 2001 +From: Igor Fedotov +Date: Thu, 30 Jun 2022 16:34:04 +0300 +Subject: [PATCH] os/bluestore: fix AU accounting in bluestore_cache_other + mempool. + +Fixes: https://tracker.ceph.com/issues/56424 + +Signed-off-by: Igor Fedotov +(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159) +--- + src/os/bluestore/bluestore_types.cc | 33 ++++++++++++++-------- + src/os/bluestore/bluestore_types.h | 43 +++++++++++++++-------------- + 2 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc +index 121f7ccd304..b62f6e2a367 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -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); + } + } + +diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h +index 584c33d7d67..b21531bfe5e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -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& 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); +-- +2.34.1 + diff -Nru ceph-16.2.9/debian/patches/series ceph-16.2.9/debian/patches/series --- ceph-16.2.9/debian/patches/series 2022-05-30 14:35:00.000000000 +0000 +++ ceph-16.2.9/debian/patches/series 2022-12-16 02:43:28.000000000 +0000 @@ -13,3 +13,4 @@ # text relocation fix AARCH64 bug1917414.patch bug1914584.patch +16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-16.2.9/src/test/debian-jessie/debian/changelog ceph-16.2.9/src/test/debian-jessie/debian/changelog --- ceph-16.2.9/src/test/debian-jessie/debian/changelog 2022-06-13 10:14:15.000000000 +0000 +++ ceph-16.2.9/src/test/debian-jessie/debian/changelog 2022-12-16 02:45:36.000000000 +0000 @@ -1,3 +1,10 @@ +ceph (16.2.9-0ubuntu0.21.10.1~cloud0ubuntu1) focal; urgency=medium + + * d/p/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + fix the leak in bluestore_cache_mempool + + -- Dongdong Tao Fri, 16 Dec 2022 02:45:36 +0000 + ceph (16.2.9-0ubuntu0.21.10.1~cloud0) focal-xena; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru ceph-16.2.9/src/test/debian-jessie/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-16.2.9/src/test/debian-jessie/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-16.2.9/src/test/debian-jessie/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-16.2.9/src/test/debian-jessie/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-12-16 02:43:28.000000000 +0000 @@ -0,0 +1,201 @@ +From ed957f632eeb60e3b752c1098228e6a29c5380c6 Mon Sep 17 00:00:00 2001 +From: Igor Fedotov +Date: Thu, 30 Jun 2022 16:34:04 +0300 +Subject: [PATCH] os/bluestore: fix AU accounting in bluestore_cache_other + mempool. + +Fixes: https://tracker.ceph.com/issues/56424 + +Signed-off-by: Igor Fedotov +(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159) +--- + src/os/bluestore/bluestore_types.cc | 33 ++++++++++++++-------- + src/os/bluestore/bluestore_types.h | 43 +++++++++++++++-------------- + 2 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc +index 121f7ccd304..b62f6e2a367 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -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); + } + } + +diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h +index 584c33d7d67..b21531bfe5e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -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& 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); +-- +2.34.1 + diff -Nru ceph-16.2.9/src/test/debian-jessie/debian/patches/series ceph-16.2.9/src/test/debian-jessie/debian/patches/series --- ceph-16.2.9/src/test/debian-jessie/debian/patches/series 2022-05-30 14:35:00.000000000 +0000 +++ ceph-16.2.9/src/test/debian-jessie/debian/patches/series 2022-12-16 02:43:28.000000000 +0000 @@ -13,3 +13,4 @@ # text relocation fix AARCH64 bug1917414.patch bug1914584.patch +16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-16.2.9/src/test/ubuntu-16.04/debian/changelog ceph-16.2.9/src/test/ubuntu-16.04/debian/changelog --- ceph-16.2.9/src/test/ubuntu-16.04/debian/changelog 2022-06-13 10:14:15.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-16.04/debian/changelog 2022-12-16 02:45:36.000000000 +0000 @@ -1,3 +1,10 @@ +ceph (16.2.9-0ubuntu0.21.10.1~cloud0ubuntu1) focal; urgency=medium + + * d/p/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + fix the leak in bluestore_cache_mempool + + -- Dongdong Tao Fri, 16 Dec 2022 02:45:36 +0000 + ceph (16.2.9-0ubuntu0.21.10.1~cloud0) focal-xena; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-12-16 02:43:28.000000000 +0000 @@ -0,0 +1,201 @@ +From ed957f632eeb60e3b752c1098228e6a29c5380c6 Mon Sep 17 00:00:00 2001 +From: Igor Fedotov +Date: Thu, 30 Jun 2022 16:34:04 +0300 +Subject: [PATCH] os/bluestore: fix AU accounting in bluestore_cache_other + mempool. + +Fixes: https://tracker.ceph.com/issues/56424 + +Signed-off-by: Igor Fedotov +(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159) +--- + src/os/bluestore/bluestore_types.cc | 33 ++++++++++++++-------- + src/os/bluestore/bluestore_types.h | 43 +++++++++++++++-------------- + 2 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc +index 121f7ccd304..b62f6e2a367 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -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); + } + } + +diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h +index 584c33d7d67..b21531bfe5e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -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& 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); +-- +2.34.1 + diff -Nru ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/series ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/series --- ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/series 2022-05-30 14:35:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-16.04/debian/patches/series 2022-12-16 02:43:28.000000000 +0000 @@ -13,3 +13,4 @@ # text relocation fix AARCH64 bug1917414.patch bug1914584.patch +16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-16.2.9/src/test/ubuntu-18.04/debian/changelog ceph-16.2.9/src/test/ubuntu-18.04/debian/changelog --- ceph-16.2.9/src/test/ubuntu-18.04/debian/changelog 2022-06-13 10:14:15.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-18.04/debian/changelog 2022-12-16 02:45:36.000000000 +0000 @@ -1,3 +1,10 @@ +ceph (16.2.9-0ubuntu0.21.10.1~cloud0ubuntu1) focal; urgency=medium + + * d/p/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + fix the leak in bluestore_cache_mempool + + -- Dongdong Tao Fri, 16 Dec 2022 02:45:36 +0000 + ceph (16.2.9-0ubuntu0.21.10.1~cloud0) focal-xena; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-12-16 02:43:28.000000000 +0000 @@ -0,0 +1,201 @@ +From ed957f632eeb60e3b752c1098228e6a29c5380c6 Mon Sep 17 00:00:00 2001 +From: Igor Fedotov +Date: Thu, 30 Jun 2022 16:34:04 +0300 +Subject: [PATCH] os/bluestore: fix AU accounting in bluestore_cache_other + mempool. + +Fixes: https://tracker.ceph.com/issues/56424 + +Signed-off-by: Igor Fedotov +(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159) +--- + src/os/bluestore/bluestore_types.cc | 33 ++++++++++++++-------- + src/os/bluestore/bluestore_types.h | 43 +++++++++++++++-------------- + 2 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc +index 121f7ccd304..b62f6e2a367 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -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); + } + } + +diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h +index 584c33d7d67..b21531bfe5e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -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& 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); +-- +2.34.1 + diff -Nru ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/series ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/series --- ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/series 2022-05-30 14:35:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-18.04/debian/patches/series 2022-12-16 02:43:28.000000000 +0000 @@ -13,3 +13,4 @@ # text relocation fix AARCH64 bug1917414.patch bug1914584.patch +16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-16.2.9/src/test/ubuntu-20.04/debian/changelog ceph-16.2.9/src/test/ubuntu-20.04/debian/changelog --- ceph-16.2.9/src/test/ubuntu-20.04/debian/changelog 2022-06-13 10:14:15.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-20.04/debian/changelog 2022-12-16 02:45:36.000000000 +0000 @@ -1,3 +1,10 @@ +ceph (16.2.9-0ubuntu0.21.10.1~cloud0ubuntu1) focal; urgency=medium + + * d/p/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + fix the leak in bluestore_cache_mempool + + -- Dongdong Tao Fri, 16 Dec 2022 02:45:36 +0000 + ceph (16.2.9-0ubuntu0.21.10.1~cloud0) focal-xena; urgency=medium * New update for the Ubuntu Cloud Archive. diff -Nru ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-12-16 02:43:28.000000000 +0000 @@ -0,0 +1,201 @@ +From ed957f632eeb60e3b752c1098228e6a29c5380c6 Mon Sep 17 00:00:00 2001 +From: Igor Fedotov +Date: Thu, 30 Jun 2022 16:34:04 +0300 +Subject: [PATCH] os/bluestore: fix AU accounting in bluestore_cache_other + mempool. + +Fixes: https://tracker.ceph.com/issues/56424 + +Signed-off-by: Igor Fedotov +(cherry picked from commit f43f596aac97200a70db7a70a230eb9343018159) +--- + src/os/bluestore/bluestore_types.cc | 33 ++++++++++++++-------- + src/os/bluestore/bluestore_types.h | 43 +++++++++++++++-------------- + 2 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc +index 121f7ccd304..b62f6e2a367 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -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); + } + } + +diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h +index 584c33d7d67..b21531bfe5e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -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& 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); +-- +2.34.1 + diff -Nru ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/series ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/series --- ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/series 2022-05-30 14:35:00.000000000 +0000 +++ ceph-16.2.9/src/test/ubuntu-20.04/debian/patches/series 2022-12-16 02:43:28.000000000 +0000 @@ -13,3 +13,4 @@ # text relocation fix AARCH64 bug1917414.patch bug1914584.patch +16.2.9-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch