kernel/vm: Shrink commitments in discard_area_range if possible.

Confirmed by X512 to work with "mimalloc".

Change-Id: I981d6ef2d035a98f50b1b5cae1f698b9531e7dde
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8682
Tested-by: Commit checker robot <[email protected]>
Haiku-Format: Haiku-format Bot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-12-14 16:21:16 +00:00
committed by waddlesplash
parent a681d5a772
commit 2c84bc3c0e
+20 -1
View File
@@ -1120,12 +1120,31 @@ discard_area_range(VMArea* area, addr_t address, addr_t size)
unmap_pages(area, address, size);
ssize_t commitmentChange = 0;
if (cache->temporary && !cache->CanOvercommit() && area->page_protections != NULL) {
// See if the commitment can be shrunken after the pages are discarded.
const off_t areaCacheBase = area->Base() - area->cache_offset;
const off_t endAddress = address + size;
for (off_t pageAddress = address; pageAddress < endAddress; pageAddress += B_PAGE_SIZE) {
if (cache->LookupPage(pageAddress - areaCacheBase) == NULL)
continue;
const bool isWritable
= (get_area_page_protection(area, pageAddress) & B_WRITE_AREA) != 0;
if (!isWritable)
commitmentChange -= B_PAGE_SIZE;
}
}
// Since VMCache::Discard() can temporarily drop the lock, we must
// unlock all lower caches to prevent locking order inversion.
cacheChainLocker.Unlock(cache);
cache->Discard(cache->virtual_base + offset, size);
cache->ReleaseRefAndUnlock();
if (commitmentChange != 0)
cache->Commit(cache->committed_size + commitmentChange, VM_PRIORITY_USER);
cache->ReleaseRefAndUnlock();
return B_OK;
}