vm_pageout.c revision 22975
1109864Sjeff/* 2165762Sjeff * Copyright (c) 1991 Regents of the University of California. 3109864Sjeff * All rights reserved. 4109864Sjeff * Copyright (c) 1994 John S. Dyson 5109864Sjeff * All rights reserved. 6109864Sjeff * Copyright (c) 1994 David Greenman 7109864Sjeff * All rights reserved. 8109864Sjeff * 9109864Sjeff * This code is derived from software contributed to Berkeley by 10109864Sjeff * The Mach Operating System project at Carnegie-Mellon University. 11109864Sjeff * 12109864Sjeff * Redistribution and use in source and binary forms, with or without 13109864Sjeff * modification, are permitted provided that the following conditions 14109864Sjeff * are met: 15109864Sjeff * 1. Redistributions of source code must retain the above copyright 16109864Sjeff * notice, this list of conditions and the following disclaimer. 17109864Sjeff * 2. Redistributions in binary form must reproduce the above copyright 18109864Sjeff * notice, this list of conditions and the following disclaimer in the 19109864Sjeff * documentation and/or other materials provided with the distribution. 20109864Sjeff * 3. All advertising materials mentioning features or use of this software 21109864Sjeff * must display the following acknowledgement: 22109864Sjeff * This product includes software developed by the University of 23109864Sjeff * California, Berkeley and its contributors. 24109864Sjeff * 4. Neither the name of the University nor the names of its contributors 25109864Sjeff * may be used to endorse or promote products derived from this software 26109864Sjeff * without specific prior written permission. 27171482Sjeff * 28171482Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29171482Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30171482Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31171482Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32171482Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33171482Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34171482Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35171482Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36171482Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37171482Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38116182Sobrien * SUCH DAMAGE. 39116182Sobrien * 40116182Sobrien * from: @(#)vm_pageout.c 7.4 (Berkeley) 5/7/91 41147565Speter * 42147565Speter * 43134649Sscottl * Copyright (c) 1987, 1990 Carnegie-Mellon University. 44109864Sjeff * All rights reserved. 45109864Sjeff * 46131929Smarcel * Authors: Avadis Tevanian, Jr., Michael Wayne Young 47109864Sjeff * 48109864Sjeff * Permission to use, copy, modify and distribute this software and 49109864Sjeff * its documentation is hereby granted, provided that both the copyright 50109864Sjeff * notice and this permission notice appear in all copies of the 51109864Sjeff * software, derivative works or modified versions, and any portions 52112966Sjeff * thereof, and that both notices appear in supporting documentation. 53122038Sjeff * 54109864Sjeff * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 55109864Sjeff * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 56109864Sjeff * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 57109864Sjeff * 58109864Sjeff * Carnegie Mellon requests users of this software to return to 59139453Sjhb * 60161599Sdavidxu * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 61109864Sjeff * School of Computer Science 62109864Sjeff * Carnegie Mellon University 63109864Sjeff * Pittsburgh PA 15213-3890 64109864Sjeff * 65109864Sjeff * any improvements or extensions that they make and grant Carnegie the 66109864Sjeff * rights to redistribute these changes. 67145256Sjkoshy * 68145256Sjkoshy * $Id$ 69145256Sjkoshy */ 70145256Sjkoshy 71109864Sjeff/* 72121790Sjeff * The proverbial page-out daemon. 73109864Sjeff */ 74166190Sjeff 75166190Sjeff#include <sys/param.h> 76166190Sjeff#include <sys/systm.h> 77166190Sjeff#include <sys/kernel.h> 78171482Sjeff#include <sys/proc.h> 79166137Sjeff#include <sys/resourcevar.h> 80166137Sjeff#include <sys/malloc.h> 81171482Sjeff#include <sys/kernel.h> 82171482Sjeff#include <sys/signalvar.h> 83146954Sjeff#include <sys/vnode.h> 84164936Sjulian#include <sys/vmmeter.h> 85171482Sjeff#include <sys/sysctl.h> 86171482Sjeff 87171482Sjeff#include <vm/vm.h> 88171482Sjeff#include <vm/vm_param.h> 89171482Sjeff#include <vm/vm_prot.h> 90164936Sjulian#include <sys/lock.h> 91171482Sjeff#include <vm/vm_object.h> 92171482Sjeff#include <vm/vm_page.h> 93171482Sjeff#include <vm/vm_map.h> 94134791Sjulian#include <vm/vm_pageout.h> 95164936Sjulian#include <vm/vm_kern.h> 96164936Sjulian#include <vm/vm_pager.h> 97164936Sjulian#include <vm/swap_pager.h> 98166108Sjeff#include <vm/vm_extern.h> 99166108Sjeff 100166108Sjeff/* 101134791Sjulian * System initialization 102164936Sjulian */ 103166108Sjeff 104166108Sjeff/* the kernel process "vm_pageout"*/ 105121790Sjeffstatic void vm_pageout __P((void)); 106164936Sjulianstatic int vm_pageout_clean __P((vm_page_t, int)); 107109864Sjeffstatic int vm_pageout_scan __P((void)); 108109864Sjeffstatic int vm_pageout_free_page_calc __P((vm_size_t count)); 109165762Sjeffstruct proc *pageproc; 110111857Sjeff 111165762Sjeffstatic struct kproc_desc page_kp = { 112165762Sjeff "pagedaemon", 113165796Sjeff vm_pageout, 114165762Sjeff &pageproc 115165762Sjeff}; 116165762SjeffSYSINIT_KT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, &page_kp) 117165762Sjeff 118165762Sjeff#if !defined(NO_SWAPPING) 119165762Sjeff/* the kernel process "vm_daemon"*/ 120165796Sjeffstatic void vm_daemon __P((void)); 121165762Sjeffstatic struct proc *vmproc; 122165762Sjeff 123165830Sjeffstatic struct kproc_desc vm_kp = { 124165762Sjeff "vmdaemon", 125165762Sjeff vm_daemon, 126165762Sjeff &vmproc 127165762Sjeff}; 128165762SjeffSYSINIT_KT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, &vm_kp) 129165762Sjeff#endif 130165762Sjeff 131165762Sjeff 132165762Sjeffint vm_pages_needed; /* Event on which pageout daemon sleeps */ 133116642Sjeff 134165762Sjeffint vm_pageout_pages_needed; /* flag saying that the pageout daemon needs pages */ 135165762Sjeff 136109864Sjeffextern int npendingio; 137165762Sjeff#if !defined(NO_SWAPPING) 138121869Sjeffstatic int vm_pageout_req_swapout; /* XXX */ 139165762Sjeffstatic int vm_daemon_needed; 140165762Sjeff#endif 141170787Sjeffextern int nswiodone; 142165762Sjeffextern int vm_swap_size; 143165762Sjeffextern int vfs_update_wakeup; 144165827Sjeffint vm_pageout_algorithm_lru=0; 145165762Sjeff#if defined(NO_SWAPPING) 146109864Sjeffint vm_swapping_enabled=0; 147109864Sjeff#else 148165762Sjeffint vm_swapping_enabled=1; 149165762Sjeff#endif 150165762Sjeff 151165762SjeffSYSCTL_INT(_vm, VM_PAGEOUT_ALGORITHM, pageout_algorithm, 152109864Sjeff CTLFLAG_RW, &vm_pageout_algorithm_lru, 0, ""); 153110645Sjeff 154110645Sjeff#if defined(NO_SWAPPING) 155121868SjeffSYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swapping_enabled, 156116365Sjeff CTLFLAG_RD, &vm_swapping_enabled, 0, ""); 157111857Sjeff#else 158109864SjeffSYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swapping_enabled, 159165762Sjeff CTLFLAG_RW, &vm_swapping_enabled, 0, ""); 160165762Sjeff#endif 161116365Sjeff 162116365Sjeff#define MAXLAUNDER (cnt.v_page_count > 1800 ? 32 : 16) 163121126Sjeff 164111857Sjeff#define VM_PAGEOUT_PAGE_COUNT 16 165109864Sjeffint vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT; 166165762Sjeff 167165762Sjeffint vm_page_max_wired; /* XXX max # of wired pages system-wide */ 168165762Sjeff 169165762Sjeff#if !defined(NO_SWAPPING) 170165762Sjefftypedef void freeer_fcn_t __P((vm_map_t, vm_object_t, vm_pindex_t, int)); 171171482Sjeffstatic void vm_pageout_map_deactivate_pages __P((vm_map_t, vm_pindex_t)); 172109864Sjeffstatic freeer_fcn_t vm_pageout_object_deactivate_pages; 173165762Sjeffstatic void vm_req_vmdaemon __P((void)); 174165762Sjeff#endif 175165762Sjeff 176165762Sjeff/* 177171482Sjeff * vm_pageout_clean: 178109864Sjeff * 179109864Sjeff * Clean the page and remove it from the laundry. 180171482Sjeff * 181171482Sjeff * We set the busy bit to cause potential page faults on this page to 182171482Sjeff * block. 183109864Sjeff * 184164936Sjulian * And we set pageout-in-progress to keep the object from disappearing 185171713Sjeff * during pageout. This guarantees that the page won't move from the 186171482Sjeff * inactive queue. (However, any other page on the inactive queue may 187171482Sjeff * move!) 188165620Sjeff */ 189171482Sjeffstatic int 190166557Sjeffvm_pageout_clean(m, sync) 191166557Sjeff vm_page_t m; 192110267Sjeff int sync; 193171482Sjeff{ 194171482Sjeff register vm_object_t object; 195165620Sjeff vm_page_t mc[2*vm_pageout_page_count]; 196165620Sjeff int pageout_count; 197125289Sjeff int i, forward_okay, backward_okay, page_base; 198165620Sjeff vm_pindex_t pindex = m->pindex; 199110267Sjeff 200171482Sjeff object = m->object; 201109864Sjeff 202166108Sjeff /* 203123433Sjeff * If not OBJT_SWAP, additional memory may be needed to do the pageout. 204109864Sjeff * Try to avoid the deadlock. 205164936Sjulian */ 206123433Sjeff if ((sync != VM_PAGEOUT_FORCE) && 207123433Sjeff (object->type == OBJT_DEFAULT) && 208123433Sjeff ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_pageout_free_min)) 209123433Sjeff return 0; 210123433Sjeff 211123433Sjeff /* 212164936Sjulian * Don't mess with the page if it's busy. 213171713Sjeff */ 214171713Sjeff if ((!sync && m->hold_count != 0) || 215171713Sjeff ((m->busy != 0) || (m->flags & PG_BUSY))) 216171713Sjeff return 0; 217171713Sjeff 218171713Sjeff /* 219165620Sjeff * Try collapsing before it's too late. 220165620Sjeff */ 221171713Sjeff if (!sync && object->backing_object) { 222171482Sjeff vm_object_collapse(object); 223123433Sjeff } 224171482Sjeff 225166108Sjeff mc[vm_pageout_page_count] = m; 226166108Sjeff pageout_count = 1; 227123433Sjeff page_base = vm_pageout_page_count; 228166108Sjeff forward_okay = TRUE; 229166108Sjeff if (pindex != 0) 230171506Sjeff backward_okay = TRUE; 231171506Sjeff else 232171506Sjeff backward_okay = FALSE; 233166108Sjeff /* 234166108Sjeff * Scan object for clusterable pages. 235171482Sjeff * 236171506Sjeff * We can cluster ONLY if: ->> the page is NOT 237171506Sjeff * clean, wired, busy, held, or mapped into a 238170293Sjeff * buffer, and one of the following: 239166108Sjeff * 1) The page is inactive, or a seldom used 240166108Sjeff * active page. 241165620Sjeff * -or- 242109864Sjeff * 2) we force the issue. 243166108Sjeff */ 244165620Sjeff for (i = 1; (i < vm_pageout_page_count) && (forward_okay || backward_okay); i++) { 245164936Sjulian vm_page_t p; 246164936Sjulian 247171482Sjeff /* 248171482Sjeff * See if forward page is clusterable. 249129982Sjeff */ 250164936Sjulian if (forward_okay) { 251164936Sjulian /* 252171713Sjeff * Stop forward scan at end of object. 253164936Sjulian */ 254171713Sjeff if ((pindex + i) > object->size) { 255123433Sjeff forward_okay = FALSE; 256164936Sjulian goto do_backward; 257171713Sjeff } 258129982Sjeff p = vm_page_lookup(object, pindex + i); 259170315Sjeff if (p) { 260164936Sjulian if (((p->queue - p->pc) == PQ_CACHE) || 261164936Sjulian (p->flags & PG_BUSY) || p->busy) { 262110028Sjeff forward_okay = FALSE; 263109864Sjeff goto do_backward; 264171482Sjeff } 265171482Sjeff vm_page_test_dirty(p); 266171482Sjeff if ((p->dirty & p->valid) != 0 && 267171482Sjeff ((p->queue == PQ_INACTIVE) || 268171713Sjeff (sync == VM_PAGEOUT_FORCE)) && 269171482Sjeff (p->wire_count == 0) && 270163709Sjb (p->hold_count == 0)) { 271146954Sjeff mc[vm_pageout_page_count + i] = p; 272163709Sjb pageout_count++; 273163709Sjb if (pageout_count == vm_pageout_page_count) 274163709Sjb break; 275164936Sjulian } else { 276109864Sjeff forward_okay = FALSE; 277110267Sjeff } 278164936Sjulian } else { 279164936Sjulian forward_okay = FALSE; 280164936Sjulian } 281164936Sjulian } 282164936Sjuliando_backward: 283164936Sjulian /* 284164936Sjulian * See if backward page is clusterable. 285165762Sjeff */ 286171482Sjeff if (backward_okay) { 287110267Sjeff /* 288171482Sjeff * Stop backward scan at beginning of object. 289171482Sjeff */ 290171482Sjeff if ((pindex - i) == 0) { 291171482Sjeff backward_okay = FALSE; 292164936Sjulian } 293171482Sjeff p = vm_page_lookup(object, pindex - i); 294171482Sjeff if (p) { 295171482Sjeff if (((p->queue - p->pc) == PQ_CACHE) || 296164936Sjulian (p->flags & PG_BUSY) || p->busy) { 297164936Sjulian backward_okay = FALSE; 298171482Sjeff continue; 299171482Sjeff } 300171482Sjeff vm_page_test_dirty(p); 301171713Sjeff if ((p->dirty & p->valid) != 0 && 302165827Sjeff ((p->queue == PQ_INACTIVE) || 303166108Sjeff (sync == VM_PAGEOUT_FORCE)) && 304121790Sjeff (p->wire_count == 0) && 305110028Sjeff (p->hold_count == 0)) { 306165762Sjeff mc[vm_pageout_page_count - i] = p; 307165762Sjeff pageout_count++; 308165762Sjeff page_base--; 309165762Sjeff if (pageout_count == vm_pageout_page_count) 310165762Sjeff break; 311165762Sjeff } else { 312171482Sjeff backward_okay = FALSE; 313171482Sjeff } 314171482Sjeff } else { 315165762Sjeff backward_okay = FALSE; 316165762Sjeff } 317165762Sjeff } 318165762Sjeff } 319165762Sjeff 320165762Sjeff /* 321165762Sjeff * we allow reads during pageouts... 322165762Sjeff */ 323165762Sjeff for (i = page_base; i < (page_base + pageout_count); i++) { 324165762Sjeff mc[i]->flags |= PG_BUSY; 325165762Sjeff vm_page_protect(mc[i], VM_PROT_READ); 326165762Sjeff } 327165762Sjeff 328165762Sjeff return vm_pageout_flush(&mc[page_base], pageout_count, sync); 329165762Sjeff} 330165762Sjeff 331165762Sjeffint 332165762Sjeffvm_pageout_flush(mc, count, sync) 333165762Sjeff vm_page_t *mc; 334165762Sjeff int count; 335165762Sjeff int sync; 336165762Sjeff{ 337165762Sjeff register vm_object_t object; 338165762Sjeff int pageout_status[count]; 339171482Sjeff int anyok = 0; 340171482Sjeff int i; 341171482Sjeff 342113357Sjeff object = mc[0]->object; 343164936Sjulian object->paging_in_progress += count; 344110267Sjeff 345164936Sjulian vm_pager_put_pages(object, mc, count, 346112994Sjeff ((sync || (object == kernel_object)) ? TRUE : FALSE), 347164936Sjulian pageout_status); 348112994Sjeff 349171713Sjeff for (i = 0; i < count; i++) { 350171482Sjeff vm_page_t mt = mc[i]; 351165620Sjeff 352171482Sjeff switch (pageout_status[i]) { 353165766Sjeff case VM_PAGER_OK: 354165762Sjeff ++anyok; 355165762Sjeff break; 356165762Sjeff case VM_PAGER_PEND: 357165762Sjeff ++anyok; 358165762Sjeff break; 359165762Sjeff case VM_PAGER_BAD: 360121896Sjeff /* 361165620Sjeff * Page outside of range of object. Right now we 362171713Sjeff * essentially lose the changes by pretending it 363171713Sjeff * worked. 364171713Sjeff */ 365121896Sjeff pmap_clear_modify(VM_PAGE_TO_PHYS(mt)); 366113357Sjeff mt->dirty = 0; 367112994Sjeff break; 368171482Sjeff case VM_PAGER_ERROR: 369171482Sjeff case VM_PAGER_FAIL: 370171482Sjeff /* 371171482Sjeff * If page couldn't be paged out, then reactivate the 372171482Sjeff * page so it doesn't clog the inactive list. (We 373171482Sjeff * will try paging out it again later). 374122744Sjeff */ 375164936Sjulian if (mt->queue == PQ_INACTIVE) 376122744Sjeff vm_page_activate(mt); 377171482Sjeff break; 378171482Sjeff case VM_PAGER_AGAIN: 379122744Sjeff break; 380165762Sjeff } 381165620Sjeff 382165620Sjeff 383164936Sjulian /* 384123433Sjeff * If the operation is still going, leave the page busy to 385122744Sjeff * block all other accesses. Also, leave the paging in 386165762Sjeff * progress indicator set so that we don't attempt an object 387166557Sjeff * collapse. 388165762Sjeff */ 389165762Sjeff if (pageout_status[i] != VM_PAGER_PEND) { 390165762Sjeff vm_object_pip_wakeup(object); 391165762Sjeff PAGE_WAKEUP(mt); 392165762Sjeff } 393165762Sjeff } 394165762Sjeff return anyok; 395165762Sjeff} 396171713Sjeff 397165762Sjeff#if !defined(NO_SWAPPING) 398165762Sjeff/* 399165766Sjeff * vm_pageout_object_deactivate_pages 400165766Sjeff * 401165766Sjeff * deactivate enough pages to satisfy the inactive target 402165766Sjeff * requirements or if vm_page_proc_limit is set, then 403165766Sjeff * deactivate all of the pages in the object and its 404165766Sjeff * backing_objects. 405165766Sjeff * 406167664Sjeff * The object and map must be locked. 407165762Sjeff */ 408165766Sjeffstatic void 409165762Sjeffvm_pageout_object_deactivate_pages(map, object, desired, map_remove_only) 410165762Sjeff vm_map_t map; 411165762Sjeff vm_object_t object; 412122744Sjeff vm_pindex_t desired; 413122744Sjeff int map_remove_only; 414171482Sjeff{ 415171482Sjeff register vm_page_t p, next; 416171482Sjeff int rcount; 417171482Sjeff int remove_mode; 418171482Sjeff int s; 419122744Sjeff 420164936Sjulian if (object->type == OBJT_DEVICE) 421122744Sjeff return; 422171482Sjeff 423171482Sjeff while (object) { 424171482Sjeff if (vm_map_pmap(map)->pm_stats.resident_count <= desired) 425122744Sjeff return; 426164936Sjulian if (object->paging_in_progress) 427165620Sjeff return; 428165620Sjeff 429164936Sjulian remove_mode = map_remove_only; 430123433Sjeff if (object->shadow_count > 1) 431122744Sjeff remove_mode = 1; 432165766Sjeff /* 433165766Sjeff * scan the objects entire memory queue 434165766Sjeff */ 435165766Sjeff rcount = object->resident_page_count; 436165766Sjeff p = TAILQ_FIRST(&object->memq); 437165796Sjeff while (p && (rcount-- > 0)) { 438165796Sjeff int refcount; 439165796Sjeff if (vm_map_pmap(map)->pm_stats.resident_count <= desired) 440165796Sjeff return; 441165796Sjeff next = TAILQ_NEXT(p, listq); 442165796Sjeff cnt.v_pdpages++; 443165796Sjeff if (p->wire_count != 0 || 444165766Sjeff p->hold_count != 0 || 445165762Sjeff p->busy != 0 || 446122744Sjeff (p->flags & PG_BUSY) || 447122744Sjeff !pmap_page_exists(vm_map_pmap(map), VM_PAGE_TO_PHYS(p))) { 448171482Sjeff p = next; 449171482Sjeff continue; 450171482Sjeff } 451171482Sjeff 452113357Sjeff refcount = pmap_ts_referenced(VM_PAGE_TO_PHYS(p)); 453164936Sjulian if (refcount) { 454113357Sjeff p->flags |= PG_REFERENCED; 455121896Sjeff } else if (p->flags & PG_REFERENCED) { 456171482Sjeff refcount = 1; 457171482Sjeff } 458171482Sjeff 459164936Sjulian if ((p->queue != PQ_ACTIVE) && 460165620Sjeff (p->flags & PG_REFERENCED)) { 461171713Sjeff vm_page_activate(p); 462166108Sjeff p->act_count += refcount; 463166108Sjeff p->flags &= ~PG_REFERENCED; 464123487Sjeff } else if (p->queue == PQ_ACTIVE) { 465165620Sjeff if ((p->flags & PG_REFERENCED) == 0) { 466125289Sjeff p->act_count -= min(p->act_count, ACT_DECLINE); 467165620Sjeff if (!remove_mode && (vm_pageout_algorithm_lru || (p->act_count == 0))) { 468123487Sjeff vm_page_protect(p, VM_PROT_NONE); 469110267Sjeff vm_page_deactivate(p); 470113357Sjeff } else { 471171482Sjeff s = splvm(); 472171482Sjeff TAILQ_REMOVE(&vm_page_queue_active, p, pageq); 473171482Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq); 474171482Sjeff splx(s); 475112994Sjeff } 476164936Sjulian } else { 477110267Sjeff p->flags &= ~PG_REFERENCED; 478121896Sjeff if (p->act_count < (ACT_MAX - ACT_ADVANCE)) 479171482Sjeff p->act_count += ACT_ADVANCE; 480171482Sjeff s = splvm(); 481171482Sjeff TAILQ_REMOVE(&vm_page_queue_active, p, pageq); 482164936Sjulian TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq); 483166108Sjeff splx(s); 484166108Sjeff } 485123487Sjeff } else if (p->queue == PQ_INACTIVE) { 486165620Sjeff vm_page_protect(p, VM_PROT_NONE); 487125289Sjeff } 488165620Sjeff p = next; 489123487Sjeff } 490171482Sjeff object = object->backing_object; 491171713Sjeff } 492165620Sjeff return; 493165620Sjeff} 494164936Sjulian 495110267Sjeff/* 496110267Sjeff * deactivate some number of pages in a map, try to do it fairly, but 497113357Sjeff * that is really hard to do. 498116069Sjeff */ 499122744Sjeffstatic void 500116069Sjeffvm_pageout_map_deactivate_pages(map, desired) 501116069Sjeff vm_map_t map; 502116069Sjeff vm_pindex_t desired; 503116069Sjeff{ 504116069Sjeff vm_map_entry_t tmpe; 505116069Sjeff vm_object_t obj, bigobj; 506116069Sjeff 507171482Sjeff vm_map_reference(map); 508116069Sjeff if (lockmgr(&map->lock, LK_EXCLUSIVE | LK_NOWAIT, (void *)0, curproc)) { 509116069Sjeff vm_map_deallocate(map); 510121790Sjeff return; 511171482Sjeff } 512116069Sjeff 513164936Sjulian bigobj = NULL; 514164936Sjulian 515165620Sjeff /* 516123487Sjeff * first, search out the biggest object, and try to free pages from 517123487Sjeff * that. 518123487Sjeff */ 519171506Sjeff tmpe = map->header.next; 520171482Sjeff while (tmpe != &map->header) { 521171482Sjeff if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) { 522139334Sjeff obj = tmpe->object.vm_object; 523123487Sjeff if ((obj != NULL) && (obj->shadow_count <= 1) && 524165620Sjeff ((bigobj == NULL) || 525165620Sjeff (bigobj->resident_page_count < obj->resident_page_count))) { 526165620Sjeff bigobj = obj; 527123487Sjeff } 528123487Sjeff } 529123487Sjeff tmpe = tmpe->next; 530123487Sjeff } 531165620Sjeff 532165620Sjeff if (bigobj) 533165620Sjeff vm_pageout_object_deactivate_pages(map, bigobj, desired, 0); 534165620Sjeff 535165620Sjeff /* 536165620Sjeff * Next, hunt around for other pages to deactivate. We actually 537123487Sjeff * do this search sort of wrong -- .text first is not the best idea. 538123487Sjeff */ 539123487Sjeff tmpe = map->header.next; 540165620Sjeff while (tmpe != &map->header) { 541165620Sjeff if (vm_map_pmap(map)->pm_stats.resident_count <= desired) 542123487Sjeff break; 543123487Sjeff if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) { 544171482Sjeff obj = tmpe->object.vm_object; 545171482Sjeff if (obj) 546171482Sjeff vm_pageout_object_deactivate_pages(map, obj, desired, 0); 547123487Sjeff } 548171482Sjeff tmpe = tmpe->next; 549123487Sjeff }; 550123487Sjeff 551123487Sjeff /* 552171506Sjeff * Remove all mappings if a process is swapped out, this will free page 553171482Sjeff * table pages. 554171482Sjeff */ 555171482Sjeff if (desired == 0) 556171482Sjeff pmap_remove(vm_map_pmap(map), 557171482Sjeff VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); 558123487Sjeff vm_map_unlock(map); 559123487Sjeff vm_map_deallocate(map); 560171482Sjeff return; 561171482Sjeff} 562171482Sjeff#endif 563123487Sjeff 564165620Sjeff/* 565123487Sjeff * vm_pageout_scan does the dirty work for the pageout daemon. 566164936Sjulian */ 567164936Sjulianstatic int 568164936Sjulianvm_pageout_scan() 569123487Sjeff{ 570123487Sjeff vm_page_t m, next; 571165620Sjeff int page_shortage, addl_page_shortage, maxscan, maxlaunder, pcount; 572123487Sjeff int pages_freed; 573123487Sjeff struct proc *p, *bigproc; 574123487Sjeff vm_offset_t size, bigsize; 575165620Sjeff vm_object_t object; 576165620Sjeff int force_wakeup = 0; 577165620Sjeff int vnodes_skipped = 0; 578164936Sjulian int s; 579165620Sjeff 580164936Sjulian /* 581123487Sjeff * Start scanning the inactive queue for pages we can free. We keep 582123487Sjeff * scanning until we have enough free pages or we have scanned through 583123487Sjeff * the entire queue. If we encounter dirty pages, we start cleaning 584123487Sjeff * them. 585123487Sjeff */ 586171482Sjeff 587171482Sjeff pages_freed = 0; 588171482Sjeff addl_page_shortage = 0; 589123487Sjeff 590171482Sjeff maxlaunder = (cnt.v_inactive_target > MAXLAUNDER) ? 591171482Sjeff MAXLAUNDER : cnt.v_inactive_target; 592171482Sjeffrescan0: 593171482Sjeff maxscan = cnt.v_inactive_count; 594171482Sjeff for( m = TAILQ_FIRST(&vm_page_queue_inactive); 595171482Sjeff 596171482Sjeff (m != NULL) && (maxscan-- > 0) && 597171482Sjeff ((cnt.v_cache_count + cnt.v_free_count) < 598171482Sjeff (cnt.v_cache_min + cnt.v_free_target)); 599171482Sjeff 600171482Sjeff m = next) { 601171482Sjeff 602171482Sjeff cnt.v_pdpages++; 603171482Sjeff 604171482Sjeff if (m->queue != PQ_INACTIVE) { 605164936Sjulian goto rescan0; 606123487Sjeff } 607123433Sjeff 608116069Sjeff next = TAILQ_NEXT(m, pageq); 609116069Sjeff 610116069Sjeff if (m->hold_count) { 611116069Sjeff s = splvm(); 612116069Sjeff TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); 613116069Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); 614171482Sjeff splx(s); 615116069Sjeff addl_page_shortage++; 616123433Sjeff continue; 617164936Sjulian } 618123433Sjeff /* 619123433Sjeff * Dont mess with busy pages, keep in the front of the 620165620Sjeff * queue, most likely are being paged out. 621165620Sjeff */ 622165620Sjeff if (m->busy || (m->flags & PG_BUSY)) { 623165620Sjeff addl_page_shortage++; 624123487Sjeff continue; 625165620Sjeff } 626165620Sjeff 627165620Sjeff if (m->object->ref_count == 0) { 628123487Sjeff m->flags &= ~PG_REFERENCED; 629123433Sjeff pmap_clear_reference(VM_PAGE_TO_PHYS(m)); 630122744Sjeff } else if (((m->flags & PG_REFERENCED) == 0) && 631165620Sjeff pmap_ts_referenced(VM_PAGE_TO_PHYS(m))) { 632122744Sjeff vm_page_activate(m); 633171482Sjeff continue; 634171482Sjeff } 635171482Sjeff 636171482Sjeff if ((m->flags & PG_REFERENCED) != 0) { 637171482Sjeff m->flags &= ~PG_REFERENCED; 638171482Sjeff pmap_clear_reference(VM_PAGE_TO_PHYS(m)); 639171482Sjeff vm_page_activate(m); 640171482Sjeff continue; 641171482Sjeff } 642171482Sjeff 643171482Sjeff if (m->dirty == 0) { 644116069Sjeff vm_page_test_dirty(m); 645116069Sjeff } else if (m->dirty != 0) { 646116069Sjeff m->dirty = VM_PAGE_BITS_ALL; 647171482Sjeff } 648171482Sjeff 649171482Sjeff if (m->valid == 0) { 650121790Sjeff vm_page_protect(m, VM_PROT_NONE); 651171482Sjeff vm_page_free(m); 652116069Sjeff cnt.v_dfree++; 653171482Sjeff ++pages_freed; 654171482Sjeff } else if (m->dirty == 0) { 655164936Sjulian vm_page_cache(m); 656171482Sjeff ++pages_freed; 657116069Sjeff } else if (maxlaunder > 0) { 658164936Sjulian int written; 659171482Sjeff struct vnode *vp = NULL; 660164936Sjulian 661164936Sjulian object = m->object; 662165620Sjeff if (object->flags & OBJ_DEAD) { 663123433Sjeff s = splvm(); 664165620Sjeff TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); 665165620Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); 666165620Sjeff splx(s); 667123433Sjeff continue; 668164936Sjulian } 669123433Sjeff 670123433Sjeff if (object->type == OBJT_VNODE) { 671164936Sjulian vp = object->handle; 672171482Sjeff if (VOP_ISLOCKED(vp) || 673123433Sjeff vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, 674164936Sjulian curproc)) { 675123433Sjeff if ((m->queue == PQ_INACTIVE) && 676171482Sjeff (m->hold_count == 0) && 677171482Sjeff (m->busy == 0) && 678171482Sjeff (m->flags & PG_BUSY) == 0) { 679171482Sjeff s = splvm(); 680171482Sjeff TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); 681171482Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); 682171482Sjeff splx(s); 683171482Sjeff } 684171482Sjeff if (object->flags & OBJ_MIGHTBEDIRTY) 685166108Sjeff ++vnodes_skipped; 686171482Sjeff continue; 687171482Sjeff } 688171505Sjeff 689116069Sjeff /* 690110267Sjeff * The page might have been moved to another queue 691171482Sjeff * during potential blocking in vget() above. 692171482Sjeff */ 693171482Sjeff if (m->queue != PQ_INACTIVE) { 694171482Sjeff if (object->flags & OBJ_MIGHTBEDIRTY) 695123433Sjeff ++vnodes_skipped; 696164936Sjulian vput(vp); 697121790Sjeff continue; 698165620Sjeff } 699164936Sjulian 700164936Sjulian /* 701171482Sjeff * The page may have been busied during the blocking in 702171482Sjeff * vput(); We don't move the page back onto the end of 703171482Sjeff * the queue so that statistics are more correct if we don't. 704171482Sjeff */ 705171482Sjeff if (m->busy || (m->flags & PG_BUSY)) { 706123433Sjeff vput(vp); 707171482Sjeff continue; 708171482Sjeff } 709165620Sjeff 710123433Sjeff /* 711165620Sjeff * If the page has become held, then skip it 712123433Sjeff */ 713123433Sjeff if (m->hold_count) { 714166108Sjeff s = splvm(); 715165620Sjeff TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq); 716165620Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq); 717123433Sjeff splx(s); 718171482Sjeff if (object->flags & OBJ_MIGHTBEDIRTY) 719164936Sjulian ++vnodes_skipped; 720166108Sjeff vput(vp); 721166108Sjeff continue; 722171482Sjeff } 723166108Sjeff } 724166108Sjeff 725171482Sjeff /* 726171482Sjeff * If a page is dirty, then it is either being washed 727171482Sjeff * (but not yet cleaned) or it is still in the 728171482Sjeff * laundry. If it is still in the laundry, then we 729171482Sjeff * start the cleaning operation. 730171482Sjeff */ 731171482Sjeff written = vm_pageout_clean(m, 0); 732171482Sjeff 733166108Sjeff if (vp) 734171482Sjeff vput(vp); 735171482Sjeff 736166108Sjeff maxlaunder -= written; 737171482Sjeff } 738171482Sjeff } 739171482Sjeff 740171506Sjeff /* 741171482Sjeff * Compute the page shortage. If we are still very low on memory be 742171482Sjeff * sure that we will move a minimal amount of pages from active to 743171482Sjeff * inactive. 744171506Sjeff */ 745171482Sjeff 746166108Sjeff page_shortage = (cnt.v_inactive_target + cnt.v_cache_min) - 747171482Sjeff (cnt.v_free_count + cnt.v_inactive_count + cnt.v_cache_count); 748171482Sjeff if (page_shortage <= 0) { 749123433Sjeff if (pages_freed == 0) { 750171482Sjeff page_shortage = cnt.v_free_min - cnt.v_free_count; 751123433Sjeff } else { 752166108Sjeff page_shortage = 1; 753171482Sjeff } 754171482Sjeff } 755171482Sjeff if (addl_page_shortage) { 756171482Sjeff if (page_shortage < 0) 757171482Sjeff page_shortage = 0; 758171482Sjeff page_shortage += addl_page_shortage; 759171482Sjeff } 760171482Sjeff 761171482Sjeff pcount = cnt.v_active_count; 762171482Sjeff m = TAILQ_FIRST(&vm_page_queue_active); 763171482Sjeff while ((m != NULL) && (pcount-- > 0) && (page_shortage > 0)) { 764121790Sjeff int refcount; 765166108Sjeff 766121790Sjeff if (m->queue != PQ_ACTIVE) { 767121790Sjeff break; 768171482Sjeff } 769171482Sjeff 770171482Sjeff next = TAILQ_NEXT(m, pageq); 771121790Sjeff /* 772166108Sjeff * Don't deactivate pages that are busy. 773121790Sjeff */ 774166247Sjeff if ((m->busy != 0) || 775121790Sjeff (m->flags & PG_BUSY) || 776166247Sjeff (m->hold_count != 0)) { 777166247Sjeff s = splvm(); 778166108Sjeff TAILQ_REMOVE(&vm_page_queue_active, m, pageq); 779121790Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq); 780166108Sjeff splx(s); 781166247Sjeff m = next; 782166108Sjeff continue; 783166247Sjeff } 784166247Sjeff 785166137Sjeff /* 786121790Sjeff * The count for pagedaemon pages is done after checking the 787166137Sjeff * page for eligbility... 788166137Sjeff */ 789166137Sjeff cnt.v_pdpages++; 790166247Sjeff 791166137Sjeff refcount = 0; 792166137Sjeff if (m->object->ref_count != 0) { 793166247Sjeff if (m->flags & PG_REFERENCED) { 794121790Sjeff refcount += 1; 795166247Sjeff } 796166247Sjeff refcount += pmap_ts_referenced(VM_PAGE_TO_PHYS(m)); 797166247Sjeff if (refcount) { 798166247Sjeff m->act_count += ACT_ADVANCE + refcount; 799166247Sjeff if (m->act_count > ACT_MAX) 800166247Sjeff m->act_count = ACT_MAX; 801166247Sjeff } 802166247Sjeff } 803166247Sjeff 804166247Sjeff m->flags &= ~PG_REFERENCED; 805166247Sjeff 806171482Sjeff if (refcount && (m->object->ref_count != 0)) { 807165819Sjeff s = splvm(); 808166247Sjeff TAILQ_REMOVE(&vm_page_queue_active, m, pageq); 809166247Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq); 810171482Sjeff splx(s); 811121790Sjeff } else { 812121790Sjeff m->act_count -= min(m->act_count, ACT_DECLINE); 813171482Sjeff if (vm_pageout_algorithm_lru || 814171482Sjeff (m->object->ref_count == 0) || (m->act_count == 0)) { 815171482Sjeff --page_shortage; 816171482Sjeff if (m->object->ref_count == 0) { 817164936Sjulian vm_page_protect(m, VM_PROT_NONE); 818171482Sjeff if (m->dirty == 0) 819171482Sjeff vm_page_cache(m); 820171482Sjeff else 821171482Sjeff vm_page_deactivate(m); 822171482Sjeff } else { 823171482Sjeff vm_page_deactivate(m); 824171482Sjeff } 825171482Sjeff } else { 826171482Sjeff s = splvm(); 827171482Sjeff TAILQ_REMOVE(&vm_page_queue_active, m, pageq); 828171482Sjeff TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq); 829171482Sjeff splx(s); 830171482Sjeff } 831171482Sjeff } 832171482Sjeff m = next; 833171482Sjeff } 834171482Sjeff 835171482Sjeff s = splvm(); 836171482Sjeff /* 837171482Sjeff * We try to maintain some *really* free pages, this allows interrupt 838171482Sjeff * code to be guaranteed space. 839171482Sjeff */ 840171482Sjeff while (cnt.v_free_count < cnt.v_free_reserved) { 841171482Sjeff static int cache_rover = 0; 842171482Sjeff m = vm_page_list_find(PQ_CACHE, cache_rover); 843171482Sjeff if (!m) 844171482Sjeff break; 845171482Sjeff cache_rover = (cache_rover + PQ_PRIME2) & PQ_L2_MASK; 846171482Sjeff vm_page_free(m); 847171482Sjeff cnt.v_dfree++; 848171482Sjeff } 849171482Sjeff splx(s); 850171482Sjeff 851171482Sjeff /* 852171482Sjeff * If we didn't get enough free pages, and we have skipped a vnode 853171482Sjeff * in a writeable object, wakeup the sync daemon. And kick swapout 854171482Sjeff * if we did not get enough free pages. 855171482Sjeff */ 856171482Sjeff if ((cnt.v_cache_count + cnt.v_free_count) < 857171482Sjeff (cnt.v_free_target + cnt.v_cache_min) ) { 858171482Sjeff if (vnodes_skipped && 859171482Sjeff (cnt.v_cache_count + cnt.v_free_count) < cnt.v_free_min) { 860171482Sjeff if (!vfs_update_wakeup) { 861171482Sjeff vfs_update_wakeup = 1; 862171482Sjeff wakeup(&vfs_update_wakeup); 863171482Sjeff } 864121790Sjeff } 865121790Sjeff#if !defined(NO_SWAPPING) 866121790Sjeff if (vm_swapping_enabled && 867121790Sjeff (cnt.v_free_count + cnt.v_cache_count < cnt.v_free_target)) { 868164936Sjulian vm_req_vmdaemon(); 869121790Sjeff vm_pageout_req_swapout = 1; 870121790Sjeff } 871121790Sjeff#endif 872121790Sjeff } 873121790Sjeff 874121790Sjeff 875121790Sjeff /* 876121790Sjeff * make sure that we have swap space -- if we are low on memory and 877123231Speter * swap -- then kill the biggest process. 878121790Sjeff */ 879121790Sjeff if ((vm_swap_size == 0 || swap_pager_full) && 880171506Sjeff ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min)) { 881171506Sjeff bigproc = NULL; 882164936Sjulian bigsize = 0; 883121790Sjeff for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 884121790Sjeff /* 885121790Sjeff * if this is a system process, skip it 886121790Sjeff */ 887121790Sjeff if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) || 888171482Sjeff ((p->p_pid < 48) && (vm_swap_size != 0))) { 889171482Sjeff continue; 890171482Sjeff } 891164936Sjulian /* 892164936Sjulian * if the process is in a non-running type state, 893121790Sjeff * don't touch it. 894164936Sjulian */ 895121790Sjeff if (p->p_stat != SRUN && p->p_stat != SSLEEP) { 896171482Sjeff continue; 897165762Sjeff } 898164936Sjulian /* 899171482Sjeff * get the process size 900164936Sjulian */ 901123433Sjeff size = p->p_vmspace->vm_pmap.pm_stats.resident_count; 902165620Sjeff /* 903123433Sjeff * if the this process is bigger than the biggest one 904121790Sjeff * remember it. 905123433Sjeff */ 906171482Sjeff if (size > bigsize) { 907171482Sjeff bigproc = p; 908171482Sjeff bigsize = size; 909171482Sjeff } 910171482Sjeff } 911171482Sjeff if (bigproc != NULL) { 912171482Sjeff killproc(bigproc, "out of swap space"); 913171482Sjeff bigproc->p_estcpu = 0; 914123433Sjeff bigproc->p_nice = PRIO_MIN; 915171482Sjeff resetpriority(bigproc); 916171482Sjeff wakeup(&cnt.v_free_count); 917123433Sjeff } 918171482Sjeff } 919171482Sjeff return force_wakeup; 920171482Sjeff} 921171482Sjeff 922171482Sjeffstatic int 923171713Sjeffvm_pageout_free_page_calc(count) 924171713Sjeffvm_size_t count; 925171482Sjeff{ 926171482Sjeff if (count < cnt.v_page_count) 927171482Sjeff return 0; 928123433Sjeff /* 929171482Sjeff * free_reserved needs to include enough for the largest swap pager 930171482Sjeff * structures plus enough for any pv_entry structs when paging. 931171482Sjeff */ 932123685Sjeff if (cnt.v_page_count > 1024) 933171482Sjeff cnt.v_free_min = 4 + (cnt.v_page_count - 1024) / 200; 934171482Sjeff else 935171482Sjeff cnt.v_free_min = 4; 936171482Sjeff cnt.v_pageout_free_min = (2*MAXBSIZE)/PAGE_SIZE + 937171482Sjeff cnt.v_interrupt_free_min; 938171482Sjeff cnt.v_free_reserved = vm_pageout_page_count + 939166108Sjeff cnt.v_pageout_free_min + (count / 768) + PQ_L2_SIZE; 940171482Sjeff cnt.v_free_min += cnt.v_free_reserved; 941171482Sjeff return 1; 942166108Sjeff} 943171482Sjeff 944171482Sjeff 945171713Sjeff#ifdef unused 946171482Sjeffint 947166108Sjeffvm_pageout_free_pages(object, add) 948166108Sjeffvm_object_t object; 949171482Sjeffint add; 950171482Sjeff{ 951171482Sjeff return vm_pageout_free_page_calc(object->size); 952166108Sjeff} 953171482Sjeff#endif 954166108Sjeff 955171482Sjeff/* 956166108Sjeff * vm_pageout is the high level pageout daemon. 957166108Sjeff */ 958166108Sjeffstatic void 959166108Sjeffvm_pageout() 960171482Sjeff{ 961171482Sjeff /* 962171482Sjeff * Initialize some paging parameters. 963171482Sjeff */ 964171482Sjeff 965171482Sjeff cnt.v_interrupt_free_min = 2; 966171482Sjeff if (cnt.v_page_count < 2000) 967171482Sjeff vm_pageout_page_count = 8; 968171482Sjeff 969171482Sjeff vm_pageout_free_page_calc(cnt.v_page_count); 970171482Sjeff /* 971171482Sjeff * free_reserved needs to include enough for the largest swap pager 972171482Sjeff * structures plus enough for any pv_entry structs when paging. 973171482Sjeff */ 974171482Sjeff cnt.v_free_target = 3 * cnt.v_free_min + cnt.v_free_reserved; 975171482Sjeff 976171482Sjeff if (cnt.v_free_count > 1024) { 977171482Sjeff cnt.v_cache_max = (cnt.v_free_count - 1024) / 2; 978171482Sjeff cnt.v_cache_min = (cnt.v_free_count - 1024) / 8; 979171482Sjeff cnt.v_inactive_target = 2*cnt.v_cache_min + 192; 980171482Sjeff } else { 981171482Sjeff cnt.v_cache_min = 0; 982171482Sjeff cnt.v_cache_max = 0; 983171482Sjeff cnt.v_inactive_target = cnt.v_free_count / 4; 984171482Sjeff } 985171482Sjeff 986171482Sjeff /* XXX does not really belong here */ 987171482Sjeff if (vm_page_max_wired == 0) 988171482Sjeff vm_page_max_wired = cnt.v_free_count / 3; 989171482Sjeff 990171482Sjeff 991171482Sjeff swap_pager_swap_init(); 992171482Sjeff /* 993171482Sjeff * The pageout daemon is never done, so loop forever. 994171482Sjeff */ 995171482Sjeff while (TRUE) { 996171482Sjeff int inactive_target; 997171482Sjeff int s = splvm(); 998171482Sjeff if (!vm_pages_needed || 999171482Sjeff ((cnt.v_free_count + cnt.v_cache_count) > cnt.v_free_min)) { 1000171482Sjeff vm_pages_needed = 0; 1001171482Sjeff tsleep(&vm_pages_needed, PVM, "psleep", 0); 1002171482Sjeff } else if (!vm_pages_needed) { 1003171482Sjeff tsleep(&vm_pages_needed, PVM, "psleep", hz/10); 1004171482Sjeff } 1005171482Sjeff inactive_target = 1006171482Sjeff (cnt.v_page_count - cnt.v_wire_count) / 4; 1007171482Sjeff if (inactive_target < 2*cnt.v_free_min) 1008171482Sjeff inactive_target = 2*cnt.v_free_min; 1009171482Sjeff cnt.v_inactive_target = inactive_target; 1010171482Sjeff if (vm_pages_needed) 1011171482Sjeff cnt.v_pdwakeups++; 1012171482Sjeff vm_pages_needed = 0; 1013171482Sjeff splx(s); 1014171482Sjeff vm_pager_sync(); 1015171482Sjeff vm_pageout_scan(); 1016171482Sjeff vm_pager_sync(); 1017171482Sjeff wakeup(&cnt.v_free_count); 1018171482Sjeff } 1019171482Sjeff} 1020171482Sjeff 1021171482Sjeffvoid 1022171482Sjeffpagedaemon_wakeup() 1023171482Sjeff{ 1024171482Sjeff if (!vm_pages_needed && curproc != pageproc) { 1025171482Sjeff vm_pages_needed++; 1026171482Sjeff wakeup(&vm_pages_needed); 1027171482Sjeff } 1028171482Sjeff} 1029171482Sjeff 1030171482Sjeff#if !defined(NO_SWAPPING) 1031166108Sjeffstatic void 1032166108Sjeffvm_req_vmdaemon() 1033166108Sjeff{ 1034166108Sjeff static int lastrun = 0; 1035171482Sjeff 1036166108Sjeff if ((ticks > (lastrun + hz)) || (ticks < lastrun)) { 1037166108Sjeff wakeup(&vm_daemon_needed); 1038171506Sjeff lastrun = ticks; 1039171506Sjeff } 1040171506Sjeff} 1041171506Sjeff 1042171506Sjeffstatic void 1043171506Sjeffvm_daemon() 1044171506Sjeff{ 1045171506Sjeff vm_object_t object; 1046166108Sjeff struct proc *p; 1047171482Sjeff 1048166108Sjeff while (TRUE) { 1049166108Sjeff tsleep(&vm_daemon_needed, PUSER, "psleep", 0); 1050166108Sjeff if (vm_pageout_req_swapout) { 1051171482Sjeff swapout_procs(); 1052171482Sjeff vm_pageout_req_swapout = 0; 1053166229Sjeff } 1054166108Sjeff /* 1055166108Sjeff * scan the processes for exceeding their rlimits or if 1056171482Sjeff * process is swapped out -- deactivate pages 1057166108Sjeff */ 1058123433Sjeff 1059166108Sjeff for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 1060166108Sjeff quad_t limit; 1061166108Sjeff vm_offset_t size; 1062171482Sjeff 1063166229Sjeff /* 1064166108Sjeff * if this is a system process or if we have already 1065166108Sjeff * looked at this process, skip it. 1066171482Sjeff */ 1067166108Sjeff if (p->p_flag & (P_SYSTEM | P_WEXIT)) { 1068139334Sjeff continue; 1069123433Sjeff } 1070166108Sjeff /* 1071123433Sjeff * if the process is in a non-running type state, 1072166229Sjeff * don't touch it. 1073166108Sjeff */ 1074166108Sjeff if (p->p_stat != SRUN && p->p_stat != SSLEEP) { 1075171482Sjeff continue; 1076171506Sjeff } 1077171506Sjeff /* 1078171506Sjeff * get a limit 1079171506Sjeff */ 1080171506Sjeff limit = qmin(p->p_rlimit[RLIMIT_RSS].rlim_cur, 1081171506Sjeff p->p_rlimit[RLIMIT_RSS].rlim_max); 1082166108Sjeff 1083166108Sjeff /* 1084123433Sjeff * let processes that are swapped out really be 1085133427Sjeff * swapped out set the limit to nothing (will force a 1086166108Sjeff * swap-out.) 1087166108Sjeff */ 1088123433Sjeff if ((p->p_flag & P_INMEM) == 0) 1089171482Sjeff limit = 0; /* XXX */ 1090171482Sjeff 1091171482Sjeff size = p->p_vmspace->vm_pmap.pm_stats.resident_count * PAGE_SIZE; 1092171482Sjeff if (limit >= 0 && size >= limit) { 1093171482Sjeff vm_pageout_map_deactivate_pages(&p->p_vmspace->vm_map, 1094123433Sjeff (vm_pindex_t)(limit >> PAGE_SHIFT) ); 1095123433Sjeff } 1096121790Sjeff } 1097121790Sjeff 1098117326Sjeff /* 1099121790Sjeff * we remove cached objects that have no RSS... 1100117326Sjeff */ 1101164936Sjulianrestart: 1102164936Sjulian object = TAILQ_FIRST(&vm_object_cached_list); 1103110267Sjeff while (object) { 1104164936Sjulian /* 1105110267Sjeff * if there are no resident pages -- get rid of the object 1106171482Sjeff */ 1107165762Sjeff if (object->resident_page_count == 0) { 1108170787Sjeff vm_object_reference(object); 1109164936Sjulian pager_cache(object, FALSE); 1110165766Sjeff goto restart; 1111165762Sjeff } 1112170787Sjeff object = TAILQ_NEXT(object, cached_list); 1113165762Sjeff } 1114165762Sjeff } 1115165762Sjeff} 1116165762Sjeff#endif 1117110267Sjeff