From 89f76d7509c0dd276109a9cdfe00cc9b6567388c Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 17 Oct 2025 15:56:56 -0400 Subject: [PATCH] kernel/vm: Fix double-read-lock in user_set_memory_swappable. lock_memory_etc also acquires the address space read lock. So, just perform that step first and separately from the loop. Discovered by the RW_LOCK_DEBUG assertions. --- src/system/kernel/vm/vm.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 14bc65fa57..f27018b8d6 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -6701,8 +6701,13 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable) const addr_t endAddress = address + size; + status_t error = lock_memory_etc(B_CURRENT_TEAM, + (void*)address, endAddress - address, 0); + if (error != B_OK) + return error; + AddressSpaceReadLocker addressSpaceLocker; - status_t error = addressSpaceLocker.SetTo(team_get_current_team_id()); + error = addressSpaceLocker.SetTo(team_get_current_team_id()); if (error != B_OK) return error; VMAddressSpace* addressSpace = addressSpaceLocker.AddressSpace(); @@ -6721,12 +6726,6 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable) const addr_t areaEnd = std::min(endAddress, area->Base() + area->Size()); nextAddress = areaEnd; - error = lock_memory_etc(addressSpace->ID(), (void*)areaStart, areaEnd - areaStart, 0); - if (error != B_OK) { - // We don't need to unset or reset things on failure. - break; - } - VMCacheChainLocker cacheChainLocker(vm_area_get_locked_cache(area)); VMAnonymousCache* anonCache = NULL; if (dynamic_cast(area->cache) != NULL) { @@ -6740,12 +6739,15 @@ user_set_memory_swappable(const void* _address, size_t size, bool swappable) } cacheChainLocker.Unlock(); - - unlock_memory_etc(addressSpace->ID(), (void*)areaStart, areaEnd - areaStart, 0); if (error != B_OK) break; } + addressSpaceLocker.Unlock(); + + unlock_memory_etc(B_CURRENT_TEAM, + (void*)address, endAddress - address, 0); + return error; #else // No swap support? Nothing to do.