From dce3a4366d9a1ae4562a186a48b6f848a9d3d023 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 4 Feb 2026 14:59:27 -0500 Subject: [PATCH] packagefs: Add a fallback buffer for reading heaps in low-memory conditions. Otherwise we might fail with B_NO_MEMORY, or wait for long periods of time, which we don't want to do in such a critical routine. Should improve system responsiveness (or even prevent application crashes) under high memory pressure. --- .../package/hpkg/PackageFileHeapAccessorBase.h | 1 + .../file_systems/packagefs/kernel_interface.cpp | 6 +++++- .../package/hpkg/PackageFileHeapAccessorBase.cpp | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h index 904778c8f2..d53f0bd45b 100644 --- a/headers/private/package/hpkg/PackageFileHeapAccessorBase.h +++ b/headers/private/package/hpkg/PackageFileHeapAccessorBase.h @@ -100,6 +100,7 @@ public: static const size_t kChunkSize = 64 * 1024; #if defined(_KERNEL_MODE) static void* sQuadChunkCache; + static void* sQuadChunkFallbackBuffer; #endif protected: diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index e66058267c..7b56630c23 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -1153,7 +1153,8 @@ packagefs_std_ops(int32 op, ...) create_object_cache("pkgfs heap buffers", PackageFileHeapAccessorBase::kChunkSize * 4, 0); - object_cache_set_minimum_reserve(quadChunkCache, 1); + PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer = + object_cache_alloc(quadChunkCache, 0); TwoKeyAVLTreeNode::sNodeCache = create_object_cache("pkgfs TKAVLTreeNodes", @@ -1176,6 +1177,9 @@ packagefs_std_ops(int32 op, ...) PRINT("package_std_ops(): B_MODULE_UNINIT\n"); PackageFSRoot::GlobalUninit(); delete_object_cache(TwoKeyAVLTreeNode::sNodeCache); + object_cache_free((object_cache*) + PackageFileHeapAccessorBase::sQuadChunkCache, + PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer, 0); delete_object_cache((object_cache*) PackageFileHeapAccessorBase::sQuadChunkCache); StringConstants::Cleanup(); diff --git a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp index e0c6d3f6bd..bfb98be661 100644 --- a/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp +++ b/src/kits/package/hpkg/PackageFileHeapAccessorBase.cpp @@ -11,7 +11,8 @@ #include #include -#ifdef _KERNEL_MODE +#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE) +#include #include #endif @@ -30,8 +31,10 @@ namespace BHPKG { namespace BPrivate { -#if defined(_KERNEL_MODE) +#if defined(_KERNEL_MODE) && !defined(_BOOT_MODE) void* PackageFileHeapAccessorBase::sQuadChunkCache = NULL; +void* PackageFileHeapAccessorBase::sQuadChunkFallbackBuffer = NULL; +static mutex sFallbackBufferLock = MUTEX_INITIALIZER("PackageFileHeapAccessorBase fallback buffer"); #endif @@ -239,9 +242,16 @@ PackageFileHeapAccessorBase::ReadDataToOutput(off_t offset, size_t size, }; ObjectCacheDeleter chunkBufferDeleter((object_cache*)sQuadChunkCache); - uint8* quadChunkBuffer = (uint8*)object_cache_alloc((object_cache*)sQuadChunkCache, 0); + uint8* quadChunkBuffer = (uint8*)object_cache_alloc((object_cache*)sQuadChunkCache, + CACHE_DONT_WAIT_FOR_MEMORY); chunkBufferDeleter.object = quadChunkBuffer; + MutexLocker fallbackBufferLocker(sFallbackBufferLock, false, false); + if (quadChunkBuffer == NULL) { + fallbackBufferLocker.Lock(); + quadChunkBuffer = (uint8*)sQuadChunkFallbackBuffer; + } + // segment data buffer iovec localScratch; compressedDataBuffer = (uint16*)(quadChunkBuffer + 0);