Eliminate the reactivation of cached pages in vm_fault_prefault() and

vm_map_pmap_enter() unless the caller is madvise(MADV_WILLNEED).  With
the exception of calls to vm_map_pmap_enter() from
madvise(MADV_WILLNEED), vm_fault_prefault() and vm_map_pmap_enter()
are both used to create speculative mappings.  Thus, always
reactivating cached pages is a mistake.  In principle, cached pages
should only be reactivated by an actual access.  Otherwise, the
following misbehavior can occur.  On a hard fault for a text page the
clustering algorithm fetches not only the required page but also
several of the adjacent pages.  Now, suppose that one or more of the
adjacent pages are never accessed.  Ultimately, these unused pages
become cached pages through the efforts of the page daemon.  However,
the next activation of the executable reactivates and maps these
unused pages.  Consequently, they are never replaced.  In effect, they
become pinned in memory.
This commit is contained in:
Alan Cox 2007-05-22 04:45:59 +00:00
parent c28f49d439
commit cf4682ae23
2 changed files with 16 additions and 8 deletions

View file

@ -996,9 +996,9 @@ vm_fault_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
(m->flags & PG_FICTITIOUS) == 0) {
vm_page_lock_queues();
if (VM_PAGE_INQUEUE1(m, PQ_CACHE))
vm_page_deactivate(m);
pmap_enter_quick(pmap, addr, m, entry->protection);
if (!VM_PAGE_INQUEUE1(m, PQ_CACHE))
pmap_enter_quick(pmap, addr, m,
entry->protection);
vm_page_unlock_queues();
}
VM_OBJECT_UNLOCK(lobject);

View file

@ -1429,9 +1429,10 @@ vm_map_submap(
/*
* vm_map_pmap_enter:
*
* Preload read-only mappings for the given object into the specified
* map. This eliminates the soft faults on process startup and
* immediately after an mmap(2).
* Preload read-only mappings for the given object's resident pages into
* the given map. This eliminates the soft faults on process startup and
* immediately after an mmap(2). Unless the given flags include
* MAP_PREFAULT_MADVISE, cached pages are not reactivated and mapped.
*/
void
vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
@ -1502,8 +1503,15 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
are_queues_locked = TRUE;
vm_page_lock_queues();
}
if (VM_PAGE_INQUEUE1(p, PQ_CACHE))
vm_page_deactivate(p);
if (VM_PAGE_INQUEUE1(p, PQ_CACHE)) {
if ((flags & MAP_PREFAULT_MADVISE) != 0)
vm_page_deactivate(p);
else if (p_start != NULL) {
pmap_enter_object(map->pmap, start, addr +
ptoa(tmpidx), p_start, prot);
p_start = NULL;
}
}
} else if (p_start != NULL) {
pmap_enter_object(map->pmap, start, addr +
ptoa(tmpidx), p_start, prot);