kernel/vm: Always insert new clean pages into the topmost cache on fault.
The previous logic, which dates back to the NewOS kernel, inserted them into the deepest cache instead if the fault was a read and not a write. But this creates problems if the deepest cache is of a smaller size than the topmost cache, because then we'll be inserting pages with offsets past the cache's virtual_end. In the case there are multiple levels of caches between the topmost and the deepest cache which all are smaller than the topmost, then when/if the deepest cache is merged with the second- deepest cache, those pages will get skipped and freed when they may still be in-use, which was the cause of #19367. To solve this, just insert new pages into the topmost cache always. Inserting them into the deepest cache seems to have been an optimization (and a savings of pages), and not a matter of correctness.
This commit is contained in:
@@ -4367,10 +4367,8 @@ fault_get_page(PageFaultContext& context)
|
||||
}
|
||||
|
||||
if (page == NULL) {
|
||||
// There was no adequate page, determine the cache for a clean one.
|
||||
// Read-only pages come in the deepest cache, only the top most cache
|
||||
// may have direct write access.
|
||||
cache = context.isWrite ? context.topCache : lastCache;
|
||||
// There was no adequate page. Insert a clean one into the topmost cache.
|
||||
cache = context.topCache;
|
||||
|
||||
// allocate a clean page
|
||||
page = vm_page_allocate_page(&context.reservation,
|
||||
|
||||
Reference in New Issue
Block a user