From 2c84bc3c0eab8064880c40b5ebe2e91eb7e4eda7 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 13 Dec 2024 16:59:30 -0500 Subject: [PATCH] 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 Haiku-Format: Haiku-format Bot Reviewed-by: waddlesplash --- src/system/kernel/vm/vm.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 1b4aa83156..feb362a806 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -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; }