From 351575e0e432ad8ff46fc1e80a0b7f8eedf740bf Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 15 Apr 2019 11:14:59 -0400 Subject: [PATCH] kernel/vm: Do not invoke the low_resource monitor in map_backing_store. As the comment implies, we don't want to wait here, but low_resource() waits forever when timeout=0. It doesn't seem to do anything with the "size" argument at all, so not calling it is just as effective, and so replace the comment there altogether. The case where this was most often hit, causing a full system deadlock in anything relating to memory management, was when the passed "size" was 0. So now we check for this case explicity at the beginning and panic() on KDEBUG kernels for it. --- src/system/kernel/vm/vm.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 04c6980598..920745c4b5 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -805,6 +805,14 @@ map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset, _area, areaName)); cache->AssertLocked(); + if (size == 0) { +#if KDEBUG + panic("map_backing_store(): called with size=0 for area '%s'!", + areaName); +#endif + return B_BAD_VALUE; + } + uint32 allocationFlags = HEAP_DONT_WAIT_FOR_MEMORY | HEAP_DONT_LOCK_KERNEL_SPACE; int priority; @@ -873,11 +881,11 @@ map_backing_store(VMAddressSpace* addressSpace, VMCache* cache, off_t offset, allocationFlags, _virtualAddress); if (status == B_NO_MEMORY && addressRestrictions->address_specification == B_ANY_KERNEL_ADDRESS) { - // Since the kernel address space is locked by the caller, we can't - // wait here as of course no resources can be released while the locks - // are held. But we can at least issue this so the next caller doesn't - // run into the same problem. - low_resource(B_KERNEL_RESOURCE_ADDRESS_SPACE, size, 0, 0); + // TODO: At present, there is no way to notify the low_resource monitor + // that kernel addresss space is fragmented, nor does it check for this + // automatically. Due to how many locks are held, we cannot wait here + // for space to be freed up, but it would be good to at least notify + // that we tried and failed to allocate some amount. } if (status != B_OK) goto err2;