1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #include <sys/param.h> 31 #include <sys/types.h> 32 #include <sys/sysmacros.h> 33 #include <sys/systm.h> 34 #include <sys/proc.h> 35 #include <sys/cpuvar.h> 36 #include <sys/var.h> 37 #include <sys/tuneable.h> 38 #include <sys/cmn_err.h> 39 #include <sys/buf.h> 40 #include <sys/disp.h> 41 #include <sys/vmsystm.h> 42 #include <sys/vmparam.h> 43 #include <sys/class.h> 44 #include <sys/vtrace.h> 45 #include <sys/modctl.h> 46 #include <sys/debug.h> 47 #include <sys/tnf_probe.h> 48 #include <sys/procfs.h> 49 50 #include <vm/seg.h> 51 #include <vm/seg_kp.h> 52 #include <vm/as.h> 53 #include <vm/rm.h> 54 #include <vm/seg_kmem.h> 55 #include <sys/callb.h> 56 57 pgcnt_t avefree; /* 5 sec moving average of free memory */ 58 pgcnt_t avefree30; /* 30 sec moving average of free memory */ 59 60 /* 61 * Memory scheduler. 62 */ 63 void 64 sched() 65 { 66 kthread_id_t t; 67 callb_cpr_t cprinfo; 68 kmutex_t swap_cpr_lock; 69 70 mutex_init(&swap_cpr_lock, NULL, MUTEX_DEFAULT, NULL); 71 CALLB_CPR_INIT(&cprinfo, &swap_cpr_lock, callb_generic_cpr, "sched"); 72 73 for (;;) { 74 if (avenrun[0] >= 2 * FSCALE && 75 (MAX(avefree, avefree30) < desfree) && 76 (pginrate + pgoutrate > maxpgio || avefree < minfree)) { 77 /* 78 * Unload all unloadable modules, free all other memory 79 * resources we can find, then look for a thread to 80 * hardswap. 81 */ 82 modreap(); 83 segkp_cache_free(); 84 } 85 86 t = curthread; 87 thread_lock(t); 88 t->t_schedflag |= (TS_ALLSTART & ~TS_CSTART); 89 t->t_whystop = PR_SUSPENDED; 90 t->t_whatstop = SUSPEND_NORMAL; 91 (void) new_mstate(t, LMS_SLEEP); 92 mutex_enter(&swap_cpr_lock); 93 CALLB_CPR_SAFE_BEGIN(&cprinfo); 94 mutex_exit(&swap_cpr_lock); 95 thread_stop(t); /* change to stop state and drop lock */ 96 swtch(); 97 mutex_enter(&swap_cpr_lock); 98 CALLB_CPR_SAFE_END(&cprinfo, &swap_cpr_lock); 99 mutex_exit(&swap_cpr_lock); 100 } 101 }