From 8c3bd6e14eafe4b1d0af509c7abc7e6bd9a97c15 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Mon, 14 Apr 2025 17:17:42 -0400 Subject: [SharedCache] Evict file accessors from the global file accessor cache on file metadata destruction Previously we would just let them continue to exist after view destruction, this is fine assuming we expect the user to be re-opening the same cache over and over, but if a user wants to load a bunch of different caches they might want to evict the old file accessors so that COW pages are known to be evicted, along with other paged in memory. --- view/sharedcache/core/SharedCacheController.cpp | 46 +++++++++++++++---------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'view/sharedcache/core/SharedCacheController.cpp') diff --git a/view/sharedcache/core/SharedCacheController.cpp b/view/sharedcache/core/SharedCacheController.cpp index e0cd036f..6e275b4b 100644 --- a/view/sharedcache/core/SharedCacheController.cpp +++ b/view/sharedcache/core/SharedCacheController.cpp @@ -13,39 +13,49 @@ std::shared_mutex GlobalControllersMutex; std::map>& GlobalControllers() { // To make initialization order consistent we place the static in a function. - static std::map> g_dscViews = {}; - return g_dscViews; + static std::map> g_controllers = {}; + return g_controllers; } -ViewId GetViewIdFromView(BinaryView& view) +ViewId GetViewIdFromFileMetadata(const FileMetadata& file) { // Currently the view id is just the views session id. // NOTE: If we want more than one shared cache controller per view we would need to make this more unique. - return view.GetFile()->GetSessionId(); + return file.GetSessionId(); } -void DeleteController(BinaryView& view) +void DeleteController(const FileMetadata& file) { - const auto id = GetViewIdFromView(view); + const auto id = GetViewIdFromFileMetadata(file); std::unique_lock lock(GlobalControllersMutex); - auto& dscViews = GlobalControllers(); - if (auto it = dscViews.find(id); it != dscViews.end()) + auto& controllers = GlobalControllers(); + if (auto it = controllers.find(id); it != controllers.end()) { + auto controller = it->second; // Someone is still holding the controller, lets warn about this. - if (it->second->m_refs > 1) + if (controller->m_refs > 1) LogWarn("Deleting SharedCacheController for view %llx, but there are still %d references", id, - it->second->m_refs.load()); - dscViews.erase(it); - LogDebug("Deleted SharedCacheController for view %s", view.GetFile()->GetFilename().c_str()); + controller->m_refs.load()); + + // Go through the file accessor cache and remove the entries we reference. + auto& fileAccessorCache = FileAccessorCache::Global(); + for (const auto& entry : controller->GetCache().GetEntries()) + { + auto accessorId = GetCacheAccessorID(entry.GetFilePath()); + fileAccessorCache.RemoveAccessor(accessorId); + } + + controllers.erase(it); + LogDebug("Deleted SharedCacheController for view %s", file.GetFilename().c_str()); } } void RegisterSharedCacheControllerDestructor() { BNObjectDestructionCallbacks callbacks = {}; - callbacks.destructBinaryView = [](void* ctx, BNBinaryView* obj) -> void { - auto view = BinaryView(obj); - DeleteController(view); + callbacks.destructFileMetadata = [](void* ctx, BNFileMetadata* obj) -> void { + const auto file = FileMetadata(obj); + DeleteController(file); }; BNRegisterObjectDestructionCallbacks(&callbacks); } @@ -63,7 +73,7 @@ SharedCacheController::SharedCacheController(SharedCache&& cache, Ref lo DSCRef SharedCacheController::Initialize(BinaryView& view, SharedCache&& cache) { - auto id = GetViewIdFromView(view); + auto id = GetViewIdFromFileMetadata(*view.GetFile()); std::unique_lock lock(GlobalControllersMutex); auto logger = new Logger("SharedCache.Controller", view.GetFile()->GetSessionId()); DSCRef controller = new SharedCacheController(std::move(cache), logger); @@ -94,9 +104,9 @@ DSCRef SharedCacheController::Initialize(BinaryView& view return controller; } -DSCRef SharedCacheController::FromView(BinaryView& view) +DSCRef SharedCacheController::FromView(const BinaryView& view) { - auto id = GetViewIdFromView(view); + auto id = GetViewIdFromFileMetadata(*view.GetFile()); std::shared_lock lock(GlobalControllersMutex); auto& dscViews = GlobalControllers(); auto dscView = dscViews.find(id); -- cgit v1.3.1