kernel/vm: Handle overcommitting areas in cut_area properly.

We shouldn't adjust their commitments directly.
This commit is contained in:
Augustin Cavalier
2024-12-13 18:05:26 -05:00
parent 038d9b44d1
commit 5cfac6e80f
+11 -8
View File
@@ -768,7 +768,8 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
} }
int resizePriority = priority; int resizePriority = priority;
if (area->page_protections != NULL) { const bool overcommitting = (area->protection & B_OVERCOMMITTING_AREA) != 0;
if (area->page_protections != NULL && !overcommitting) {
// We'll adjust commitments directly, rather than letting VMCache do it. // We'll adjust commitments directly, rather than letting VMCache do it.
resizePriority = -1; resizePriority = -1;
} }
@@ -867,7 +868,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
} }
area->cache_offset += size; area->cache_offset += size;
if (area->page_protections != NULL) { if (area->page_protections != NULL && !overcommitting) {
const size_t newCommitmentPages = compute_area_page_commitment(area); const size_t newCommitmentPages = compute_area_page_commitment(area);
cache->Commit(newCommitmentPages * B_PAGE_SIZE, priority); cache->Commit(newCommitmentPages * B_PAGE_SIZE, priority);
} }
@@ -923,7 +924,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
// Create a new cache for the second area. // Create a new cache for the second area.
VMCache* secondCache; VMCache* secondCache;
error = VMCacheFactory::CreateAnonymousCache(secondCache, error = VMCacheFactory::CreateAnonymousCache(secondCache,
area->protection & B_OVERCOMMITTING_AREA, 0, 0, overcommitting, 0, 0,
dynamic_cast<VMAnonymousNoSwapCache*>(cache) == NULL, priority); dynamic_cast<VMAnonymousNoSwapCache*>(cache) == NULL, priority);
if (error != B_OK) { if (error != B_OK) {
addressSpace->ShrinkAreaTail(area, oldSize, allocationFlags); addressSpace->ShrinkAreaTail(area, oldSize, allocationFlags);
@@ -1026,12 +1027,14 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
// We don't need this anymore. // We don't need this anymore.
free_etc(areaOldProtections, allocationFlags); free_etc(areaOldProtections, allocationFlags);
// Shrink commitments. if (!overcommitting) {
const size_t areaCommitPages = compute_area_page_commitment(area); // Shrink commitments.
area->cache->Commit(areaCommitPages * B_PAGE_SIZE, priority); const size_t areaCommitPages = compute_area_page_commitment(area);
area->cache->Commit(areaCommitPages * B_PAGE_SIZE, priority);
const size_t secondCommitPages = compute_area_page_commitment(secondArea); const size_t secondCommitPages = compute_area_page_commitment(secondArea);
secondArea->cache->Commit(secondCommitPages * B_PAGE_SIZE, priority); secondArea->cache->Commit(secondCommitPages * B_PAGE_SIZE, priority);
}
// Set the correct page protections for the second area. // Set the correct page protections for the second area.
VMTranslationMap* map = addressSpace->TranslationMap(); VMTranslationMap* map = addressSpace->TranslationMap();