From cf4682ae2354f5a0d644c859a5da0e0d2a930bb5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 May 2007 04:45:59 +0000 Subject: [PATCH] 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. --- sys/vm/vm_fault.c | 6 +++--- sys/vm/vm_map.c | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 63d804aba9b..cd5de64764f 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -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); diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 9ffa896a9b9..8efcc293c01 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -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);