diff -Nru ceph-15.2.17/debian/changelog ceph-15.2.17/debian/changelog --- ceph-15.2.17/debian/changelog 2022-10-12 13:30:58.000000000 +0000 +++ ceph-15.2.17/debian/changelog 2022-11-16 06:55:37.000000000 +0000 @@ -1,3 +1,11 @@ +ceph (15.2.17-0ubuntu0.20.04.2) focal; urgency=medium + + * d/p/os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + cherry-pick the upstream change to fix the bluestore_cache_other + mempool's entry leak issue (LP: #1996010) + + -- Dongdong Tao Wed, 16 Nov 2022 06:55:37 +0000 + ceph (15.2.17-0ubuntu0.20.04.1) focal; urgency=medium * New upstream release (LP: #1990862). diff -Nru ceph-15.2.17/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-15.2.17/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-15.2.17/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-15.2.17/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-11-16 06:54:48.000000000 +0000 @@ -0,0 +1,202 @@ +From 4a3352744cd3dfb48da91fc0f2acba1206e0190b 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) +Signed-off-by: root +--- + 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 f85f842f6ad..aa06f6e4048 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -356,11 +356,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; +@@ -375,9 +376,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; +@@ -385,19 +385,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()); +@@ -407,8 +419,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 3a7db755668..3895d0fd88e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -244,10 +244,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; +@@ -255,7 +256,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); +@@ -264,15 +265,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 { +@@ -308,7 +305,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(); + } +@@ -334,15 +330,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); + } + } + } +@@ -407,12 +405,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); + } + } +@@ -422,7 +422,8 @@ struct bluestore_blob_use_tracker_t { + void dump(Formatter *f) const; + static void generate_test_instances(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) + ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& rm); +-- +2.17.1 + diff -Nru ceph-15.2.17/debian/patches/series ceph-15.2.17/debian/patches/series --- ceph-15.2.17/debian/patches/series 2022-10-12 13:26:35.000000000 +0000 +++ ceph-15.2.17/debian/patches/series 2022-11-16 06:54:48.000000000 +0000 @@ -11,3 +11,4 @@ riscv64-link-pthread.patch # AARCH64 EC regression bug1917414.patch +15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-15.2.17/src/test/debian-jessie/debian/changelog ceph-15.2.17/src/test/debian-jessie/debian/changelog --- ceph-15.2.17/src/test/debian-jessie/debian/changelog 2022-10-12 13:30:58.000000000 +0000 +++ ceph-15.2.17/src/test/debian-jessie/debian/changelog 2022-11-16 06:55:37.000000000 +0000 @@ -1,3 +1,11 @@ +ceph (15.2.17-0ubuntu0.20.04.2) focal; urgency=medium + + * d/p/os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + cherry-pick the upstream change to fix the bluestore_cache_other + mempool's entry leak issue (LP: #1996010) + + -- Dongdong Tao Wed, 16 Nov 2022 06:55:37 +0000 + ceph (15.2.17-0ubuntu0.20.04.1) focal; urgency=medium * New upstream release (LP: #1990862). diff -Nru ceph-15.2.17/src/test/debian-jessie/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-15.2.17/src/test/debian-jessie/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-15.2.17/src/test/debian-jessie/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-15.2.17/src/test/debian-jessie/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-11-16 06:54:48.000000000 +0000 @@ -0,0 +1,202 @@ +From 4a3352744cd3dfb48da91fc0f2acba1206e0190b 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) +Signed-off-by: root +--- + 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 f85f842f6ad..aa06f6e4048 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -356,11 +356,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; +@@ -375,9 +376,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; +@@ -385,19 +385,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()); +@@ -407,8 +419,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 3a7db755668..3895d0fd88e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -244,10 +244,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; +@@ -255,7 +256,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); +@@ -264,15 +265,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 { +@@ -308,7 +305,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(); + } +@@ -334,15 +330,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); + } + } + } +@@ -407,12 +405,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); + } + } +@@ -422,7 +422,8 @@ struct bluestore_blob_use_tracker_t { + void dump(Formatter *f) const; + static void generate_test_instances(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) + ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& rm); +-- +2.17.1 + diff -Nru ceph-15.2.17/src/test/debian-jessie/debian/patches/series ceph-15.2.17/src/test/debian-jessie/debian/patches/series --- ceph-15.2.17/src/test/debian-jessie/debian/patches/series 2022-10-12 13:26:35.000000000 +0000 +++ ceph-15.2.17/src/test/debian-jessie/debian/patches/series 2022-11-16 06:54:48.000000000 +0000 @@ -11,3 +11,4 @@ riscv64-link-pthread.patch # AARCH64 EC regression bug1917414.patch +15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-15.2.17/src/test/ubuntu-16.04/debian/changelog ceph-15.2.17/src/test/ubuntu-16.04/debian/changelog --- ceph-15.2.17/src/test/ubuntu-16.04/debian/changelog 2022-10-12 13:30:58.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-16.04/debian/changelog 2022-11-16 06:55:37.000000000 +0000 @@ -1,3 +1,11 @@ +ceph (15.2.17-0ubuntu0.20.04.2) focal; urgency=medium + + * d/p/os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + cherry-pick the upstream change to fix the bluestore_cache_other + mempool's entry leak issue (LP: #1996010) + + -- Dongdong Tao Wed, 16 Nov 2022 06:55:37 +0000 + ceph (15.2.17-0ubuntu0.20.04.1) focal; urgency=medium * New upstream release (LP: #1990862). diff -Nru ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-11-16 06:54:48.000000000 +0000 @@ -0,0 +1,202 @@ +From 4a3352744cd3dfb48da91fc0f2acba1206e0190b 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) +Signed-off-by: root +--- + 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 f85f842f6ad..aa06f6e4048 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -356,11 +356,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; +@@ -375,9 +376,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; +@@ -385,19 +385,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()); +@@ -407,8 +419,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 3a7db755668..3895d0fd88e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -244,10 +244,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; +@@ -255,7 +256,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); +@@ -264,15 +265,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 { +@@ -308,7 +305,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(); + } +@@ -334,15 +330,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); + } + } + } +@@ -407,12 +405,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); + } + } +@@ -422,7 +422,8 @@ struct bluestore_blob_use_tracker_t { + void dump(Formatter *f) const; + static void generate_test_instances(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) + ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& rm); +-- +2.17.1 + diff -Nru ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/series ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/series --- ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/series 2022-10-12 13:26:35.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-16.04/debian/patches/series 2022-11-16 06:54:48.000000000 +0000 @@ -11,3 +11,4 @@ riscv64-link-pthread.patch # AARCH64 EC regression bug1917414.patch +15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch diff -Nru ceph-15.2.17/src/test/ubuntu-18.04/debian/changelog ceph-15.2.17/src/test/ubuntu-18.04/debian/changelog --- ceph-15.2.17/src/test/ubuntu-18.04/debian/changelog 2022-10-12 13:30:58.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-18.04/debian/changelog 2022-11-16 06:55:37.000000000 +0000 @@ -1,3 +1,11 @@ +ceph (15.2.17-0ubuntu0.20.04.2) focal; urgency=medium + + * d/p/os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch: + cherry-pick the upstream change to fix the bluestore_cache_other + mempool's entry leak issue (LP: #1996010) + + -- Dongdong Tao Wed, 16 Nov 2022 06:55:37 +0000 + ceph (15.2.17-0ubuntu0.20.04.1) focal; urgency=medium * New upstream release (LP: #1990862). diff -Nru ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch --- ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 1970-01-01 00:00:00.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch 2022-11-16 06:54:48.000000000 +0000 @@ -0,0 +1,202 @@ +From 4a3352744cd3dfb48da91fc0f2acba1206e0190b 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) +Signed-off-by: root +--- + 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 f85f842f6ad..aa06f6e4048 100644 +--- a/src/os/bluestore/bluestore_types.cc ++++ b/src/os/bluestore/bluestore_types.cc +@@ -356,11 +356,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; +@@ -375,9 +376,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; +@@ -385,19 +385,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()); +@@ -407,8 +419,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 3a7db755668..3895d0fd88e 100644 +--- a/src/os/bluestore/bluestore_types.h ++++ b/src/os/bluestore/bluestore_types.h +@@ -244,10 +244,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; +@@ -255,7 +256,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); +@@ -264,15 +265,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 { +@@ -308,7 +305,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(); + } +@@ -334,15 +330,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); + } + } + } +@@ -407,12 +405,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); + } + } +@@ -422,7 +422,8 @@ struct bluestore_blob_use_tracker_t { + void dump(Formatter *f) const; + static void generate_test_instances(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) + ostream& operator<<(ostream& out, const bluestore_blob_use_tracker_t& rm); +-- +2.17.1 + diff -Nru ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/series ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/series --- ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/series 2022-10-12 13:26:35.000000000 +0000 +++ ceph-15.2.17/src/test/ubuntu-18.04/debian/patches/series 2022-11-16 06:54:48.000000000 +0000 @@ -11,3 +11,4 @@ riscv64-link-pthread.patch # AARCH64 EC regression bug1917414.patch +15.2.17-os-bluestore-fix-AU-accounting-in-bluestore_cache_ot.patch