kernel/vm: Set the upper cache's commitment in vm_copy_on_write_area.
Otherwise we may fault later but have no memory to satisfy the fault. For a compile of HaikuDepot and the mime_db in VMware with -j4, this seems to increase the wait time on the "available memory" lock from ~0.1s to ~0.5s, and the wait count from ~500 to ~1500 (overall real time ~30s.) Probably we can mitigate that later by doing atomic updates on sAvailableMemory, at least for releasing memory. Change-Id: I61abc28d1fc30f7b3d5fd9a2e68e4f4ec960f88d Reviewed-on: https://review.haiku-os.org/c/haiku/+/8677 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
2acb67eef0
commit
b592ba6662
@@ -2735,14 +2735,13 @@ static status_t
|
||||
vm_copy_on_write_area(VMCache* lowerCache,
|
||||
vm_page_reservation* wiredPagesReservation)
|
||||
{
|
||||
VMCache* upperCache;
|
||||
|
||||
TRACE(("vm_copy_on_write_area(cache = %p)\n", lowerCache));
|
||||
|
||||
// We need to separate the cache from its areas. The cache goes one level
|
||||
// deeper and we create a new cache inbetween.
|
||||
|
||||
// create an anonymous cache
|
||||
VMCache* upperCache;
|
||||
status_t status = VMCacheFactory::CreateAnonymousCache(upperCache,
|
||||
lowerCache->CanOvercommit(), 0,
|
||||
lowerCache->GuardSize() / B_PAGE_SIZE,
|
||||
@@ -2757,6 +2756,22 @@ vm_copy_on_write_area(VMCache* lowerCache,
|
||||
upperCache->virtual_base = lowerCache->virtual_base;
|
||||
upperCache->virtual_end = lowerCache->virtual_end;
|
||||
|
||||
// Shrink the lower cache's commitment (if possible) and steal the remainder;
|
||||
// and increase the upper cache's commitment to the lower cache's old commitment.
|
||||
const off_t lowerOldCommitment = lowerCache->committed_size,
|
||||
lowerNewCommitment = (lowerCache->page_count * B_PAGE_SIZE);
|
||||
if (lowerNewCommitment < lowerOldCommitment) {
|
||||
lowerCache->committed_size = lowerNewCommitment;
|
||||
upperCache->committed_size = lowerOldCommitment - lowerNewCommitment;
|
||||
}
|
||||
status = upperCache->Commit(lowerOldCommitment, VM_PRIORITY_USER);
|
||||
if (status != B_OK) {
|
||||
lowerCache->committed_size += upperCache->committed_size;
|
||||
upperCache->committed_size = 0;
|
||||
upperCache->ReleaseRefAndUnlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
// transfer the lower cache areas to the upper cache
|
||||
rw_lock_write_lock(&sAreaCacheLock);
|
||||
upperCache->TransferAreas(lowerCache);
|
||||
|
||||
Reference in New Issue
Block a user