From c21e0e6d1488fdf099962531a598f80b0f2d54dd Mon Sep 17 00:00:00 2001 From: Matan Breizman Date: Tue, 24 Dec 2024 11:22:58 +0000 Subject: [PATCH] crimson/common/shared_lru: invalidate Deleter's cache Once we destruct SharedLRU, SharedLRU::weak_refs map is destroyed. As a weak refernce might outlive the SharedLRU itself, when destroying the object via the custom Deleter, we try to access the already destroyed SharedLRU instance's weak ref map. Instead, invalidate the custom Deleter (Deleter::cache), when destructing the SharedLRU. Fixes: https://tracker.ceph.com/issues/66478 Signed-off-by: Matan Breizman --- src/crimson/common/shared_lru.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/crimson/common/shared_lru.h b/src/crimson/common/shared_lru.h index 92d99d332c44d..c08f033e0ea7a 100644 --- a/src/crimson/common/shared_lru.h +++ b/src/crimson/common/shared_lru.h @@ -25,11 +25,16 @@ class SharedLRU { SimpleLRU cache; std::map> weak_refs; + // Once all of the shared pointers are destoryed, + // erase the tracked object from the weak_ref map + // before actually destorying it struct Deleter { SharedLRU* cache; const K key; void operator()(V* ptr) { - cache->_erase_weak(key); + if (cache) { + cache->_erase_weak(key); + } delete ptr; } }; @@ -42,9 +47,19 @@ public: {} ~SharedLRU() { cache.clear(); + // initially, we were assuming that no pointer obtained from SharedLRU // can outlive the lru itself. However, since going with the interruption // concept for handling shutdowns, this is no longer valid. + // Moreover, before clearing weak_refs, invalidate each deleter + // cache pointer as this SharedLRU is being destoryed. + for (const auto& [key, value] : weak_refs) { + shared_ptr_t val; + val = value.first.lock(); + auto this_deleter = get_deleter(val); + this_deleter->cache = nullptr; + } + weak_refs.clear(); } /** -- 2.39.5