vm_zeroidle.c revision 79265
179265Sdillon/*- 279265Sdillon * Copyright (c) 1994 John Dyson 379265Sdillon * Copyright (c) 2001 Matt Dillon 479265Sdillon * 579265Sdillon * All rights reserved. Terms for use and redistribution 679265Sdillon * are covered by the BSD Copyright as found in /usr/src/COPYRIGHT. 779265Sdillon * 879265Sdillon * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 979265Sdillon * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ 1079265Sdillon * $FreeBSD: head/sys/vm/vm_zeroidle.c 79265 2001-07-05 01:32:42Z dillon $ 1179265Sdillon */ 1279265Sdillon 1379265Sdillon#include "opt_npx.h" 1479265Sdillon#ifdef PC98 1579265Sdillon#include "opt_pc98.h" 1679265Sdillon#endif 1779265Sdillon#include "opt_reset.h" 1879265Sdillon#include "opt_isa.h" 1979265Sdillon 2079265Sdillon#include <sys/param.h> 2179265Sdillon#include <sys/systm.h> 2279265Sdillon#include <sys/malloc.h> 2379265Sdillon#include <sys/proc.h> 2479265Sdillon#include <sys/bio.h> 2579265Sdillon#include <sys/buf.h> 2679265Sdillon#include <sys/vnode.h> 2779265Sdillon#include <sys/vmmeter.h> 2879265Sdillon#include <sys/kernel.h> 2979265Sdillon#include <sys/ktr.h> 3079265Sdillon#include <sys/mutex.h> 3179265Sdillon#include <sys/smp.h> 3279265Sdillon#include <sys/sysctl.h> 3379265Sdillon#include <sys/unistd.h> 3479265Sdillon 3579265Sdillon#include <machine/cpu.h> 3679265Sdillon#include <machine/md_var.h> 3779265Sdillon#include <machine/pcb.h> 3879265Sdillon#include <machine/pcb_ext.h> 3979265Sdillon#include <machine/vm86.h> 4079265Sdillon 4179265Sdillon#include <vm/vm.h> 4279265Sdillon#include <vm/vm_param.h> 4379265Sdillon#include <sys/lock.h> 4479265Sdillon#include <vm/vm_kern.h> 4579265Sdillon#include <vm/vm_page.h> 4679265Sdillon#include <vm/vm_map.h> 4779265Sdillon#include <vm/vm_extern.h> 4879265Sdillon 4979265Sdillon#include <sys/user.h> 5079265Sdillon 5179265Sdillon#ifdef PC98 5279265Sdillon#include <pc98/pc98/pc98.h> 5379265Sdillon#else 5479265Sdillon#include <i386/isa/isa.h> 5579265Sdillon#endif 5679265Sdillon 5779265SdillonSYSCTL_DECL(_vm_stats_misc); 5879265Sdillon 5979265Sdillonstatic int cnt_prezero; 6079265Sdillon 6179265SdillonSYSCTL_INT(_vm_stats_misc, OID_AUTO, 6279265Sdillon cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, ""); 6379265Sdillon 6479265Sdillon/* 6579265Sdillon * Implement the pre-zeroed page mechanism. 6679265Sdillon * This routine is called from the idle loop. 6779265Sdillon */ 6879265Sdillon 6979265Sdillon#define ZIDLE_LO(v) ((v) * 2 / 3) 7079265Sdillon#define ZIDLE_HI(v) ((v) * 4 / 5) 7179265Sdillon 7279265Sdillonint 7379265Sdillonvm_page_zero_idle(void) 7479265Sdillon{ 7579265Sdillon static int free_rover; 7679265Sdillon static int zero_state; 7779265Sdillon vm_page_t m; 7879265Sdillon 7979265Sdillon /* 8079265Sdillon * Attempt to maintain approximately 1/2 of our free pages in a 8179265Sdillon * PG_ZERO'd state. Add some hysteresis to (attempt to) avoid 8279265Sdillon * generally zeroing a page when the system is near steady-state. 8379265Sdillon * Otherwise we might get 'flutter' during disk I/O / IPC or 8479265Sdillon * fast sleeps. We also do not want to be continuously zeroing 8579265Sdillon * pages because doing so may flush our L1 and L2 caches too much. 8679265Sdillon */ 8779265Sdillon 8879265Sdillon if (zero_state && vm_page_zero_count >= ZIDLE_LO(cnt.v_free_count)) 8979265Sdillon return(0); 9079265Sdillon if (vm_page_zero_count >= ZIDLE_HI(cnt.v_free_count)) 9179265Sdillon return(0); 9279265Sdillon 9379265Sdillon if (mtx_trylock(&Giant)) { 9479265Sdillon zero_state = 0; 9579265Sdillon m = vm_pageq_find(PQ_FREE, free_rover, FALSE); 9679265Sdillon if (m != NULL && (m->flags & PG_ZERO) == 0) { 9779265Sdillon vm_page_queues[m->queue].lcnt--; 9879265Sdillon TAILQ_REMOVE(&vm_page_queues[m->queue].pl, m, pageq); 9979265Sdillon m->queue = PQ_NONE; 10079265Sdillon pmap_zero_page(VM_PAGE_TO_PHYS(m)); 10179265Sdillon vm_page_flag_set(m, PG_ZERO); 10279265Sdillon m->queue = PQ_FREE + m->pc; 10379265Sdillon vm_page_queues[m->queue].lcnt++; 10479265Sdillon TAILQ_INSERT_TAIL(&vm_page_queues[m->queue].pl, m, 10579265Sdillon pageq); 10679265Sdillon ++vm_page_zero_count; 10779265Sdillon ++cnt_prezero; 10879265Sdillon if (vm_page_zero_count >= ZIDLE_HI(cnt.v_free_count)) 10979265Sdillon zero_state = 1; 11079265Sdillon } 11179265Sdillon free_rover = (free_rover + PQ_PRIME2) & PQ_L2_MASK; 11279265Sdillon mtx_unlock(&Giant); 11379265Sdillon return (1); 11479265Sdillon } 11579265Sdillon return(0); 11679265Sdillon} 11779265Sdillon 118