diff --git a/src/system/kernel/vm/VMAnonymousCache.cpp b/src/system/kernel/vm/VMAnonymousCache.cpp index f17b4a7042..c0af8a1e99 100644 --- a/src/system/kernel/vm/VMAnonymousCache.cpp +++ b/src/system/kernel/vm/VMAnonymousCache.cpp @@ -527,8 +527,9 @@ VMAnonymousCache::Commit(off_t size, int priority) { TRACE("%p->VMAnonymousCache::Commit(%lld)\n", this, size); - // if we can overcommit, we don't commit here, but in anonymous_fault() - if (fCanOvercommit) { + // If we can overcommit, we don't commit here, but in Fault(). We always + // unreserve memory, if we're asked to shrink our commitment, though. + if (fCanOvercommit && size > committed_size) { if (fHasPrecommitted) return B_OK; @@ -783,14 +784,21 @@ VMAnonymousCache::Fault(struct VMAddressSpace* aspace, off_t offset) } if (fPrecommittedPages == 0) { + // never commit more than needed + if (committed_size / B_PAGE_SIZE > page_count) + return B_BAD_HANDLER; + // try to commit additional swap space/memory if (swap_space_reserve(B_PAGE_SIZE) == B_PAGE_SIZE) { fCommittedSwapSize += B_PAGE_SIZE; } else { int priority = aspace == VMAddressSpace::Kernel() ? VM_PRIORITY_SYSTEM : VM_PRIORITY_USER; - if (vm_try_reserve_memory(B_PAGE_SIZE, priority, 0) != B_OK) + if (vm_try_reserve_memory(B_PAGE_SIZE, priority, 0) != B_OK) { + dprintf("%p->VMAnonymousCache::Fault(): Failed to reserve " + "%d bytes of RAM.\n", this, (int)B_PAGE_SIZE); return B_NO_MEMORY; + } } committed_size += B_PAGE_SIZE; diff --git a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp index ca7acc743b..3bb45b0f6c 100644 --- a/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp +++ b/src/system/kernel/vm/VMAnonymousNoSwapCache.cpp @@ -60,8 +60,9 @@ VMAnonymousNoSwapCache::Init(bool canOvercommit, int32 numPrecommittedPages, status_t VMAnonymousNoSwapCache::Commit(off_t size, int priority) { - // if we can overcommit, we don't commit here, but in anonymous_fault() - if (fCanOvercommit) { + // If we can overcommit, we don't commit here, but in Fault(). We always + // unreserve memory, if we're asked to shrink our commitment, though. + if (fCanOvercommit && size > committed_size) { if (fHasPrecommitted) return B_OK; @@ -138,11 +139,18 @@ VMAnonymousNoSwapCache::Fault(struct VMAddressSpace *aspace, off_t offset) } if (fPrecommittedPages == 0) { + // never commit more than needed + if (committed_size / B_PAGE_SIZE > page_count) + return B_BAD_HANDLER; + // try to commit additional memory int priority = aspace == VMAddressSpace::Kernel() ? VM_PRIORITY_SYSTEM : VM_PRIORITY_USER; - if (vm_try_reserve_memory(B_PAGE_SIZE, priority, 0) != B_OK) + if (vm_try_reserve_memory(B_PAGE_SIZE, priority, 0) != B_OK) { + dprintf("%p->VMAnonymousNoSwapCache::Fault(): Failed to " + "reserve %d bytes of RAM.\n", this, (int)B_PAGE_SIZE); return B_NO_MEMORY; + } committed_size += B_PAGE_SIZE; } else