Introduce uvm_swapisfull(), which computes the available swap space by

taking into account swap devices that are in the process of being removed.
This commit is contained in:
pk 2003-08-11 16:33:30 +00:00
parent 9088831850
commit 5869d91cb9
6 changed files with 42 additions and 27 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_extern.h,v 1.83 2003/08/07 16:34:48 agc Exp $ */
/* $NetBSD: uvm_extern.h,v 1.84 2003/08/11 16:33:30 pk Exp $ */
/*
*
@ -279,6 +279,7 @@ struct uvmexp {
/* swap */
int nswapdev; /* number of configured swap devices in system */
int swpages; /* number of PAGE_SIZE'ed swap pages */
int swpgavail; /* number of swap pages currently available */
int swpginuse; /* number of swap pages in use */
int swpgonly; /* number of swap pages in use, not also in RAM */
int nswget; /* number of times fault calls uvm_swap_get() */

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_fault.c,v 1.82 2003/05/03 17:57:50 yamt Exp $ */
/* $NetBSD: uvm_fault.c,v 1.83 2003/08/11 16:33:31 pk Exp $ */
/*
*
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.82 2003/05/03 17:57:50 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.83 2003/08/11 16:33:31 pk Exp $");
#include "opt_uvmhist.h"
@ -1159,8 +1159,7 @@ ReFault:
uvm_anfree(anon);
}
uvmfault_unlockall(&ufi, amap, uobj, oanon);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (anon == NULL || uvmexp.swpgonly == uvmexp.swpages) {
if (anon == NULL || uvm_swapisfull()) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
uvmexp.fltnoanon++;
@ -1224,8 +1223,7 @@ ReFault:
if (anon != oanon)
simple_unlock(&anon->an_lock);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (uvmexp.swpgonly == uvmexp.swpages) {
if (uvm_swapisfull()) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
/* XXX instrumentation */
@ -1529,8 +1527,7 @@ Case2:
/* unlock and fail ... */
uvmfault_unlockall(&ufi, amap, uobj, NULL);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (anon == NULL || uvmexp.swpgonly == uvmexp.swpages) {
if (anon == NULL || uvm_swapisfull()) {
UVMHIST_LOG(maphist, " promote: out of VM",
0,0,0,0);
uvmexp.fltnoanon++;
@ -1639,8 +1636,7 @@ Case2:
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
uvmfault_unlockall(&ufi, amap, uobj, anon);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (uvmexp.swpgonly == uvmexp.swpages) {
if (uvm_swapisfull()) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
/* XXX instrumentation */

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_km.c,v 1.62 2003/05/10 21:10:23 thorpej Exp $ */
/* $NetBSD: uvm_km.c,v 1.63 2003/08/11 16:33:31 pk Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -134,7 +134,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.62 2003/05/10 21:10:23 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.63 2003/08/11 16:33:31 pk Exp $");
#include "opt_uvmhist.h"
@ -443,8 +443,7 @@ uvm_km_kmemalloc(map, obj, size, flags)
if (__predict_false(pg == NULL)) {
if ((flags & UVM_KMF_NOWAIT) ||
((flags & UVM_KMF_CANFAIL) &&
uvmexp.swpgonly == uvmexp.swpages)) {
((flags & UVM_KMF_CANFAIL) && uvm_swapisfull())) {
/* free everything! */
uvm_unmap(map, kva, kva + size);
return (0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_pdaemon.c,v 1.51 2003/04/23 00:55:22 tls Exp $ */
/* $NetBSD: uvm_pdaemon.c,v 1.52 2003/08/11 16:33:32 pk Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.51 2003/04/23 00:55:22 tls Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.52 2003/08/11 16:33:32 pk Exp $");
#include "opt_uvmhist.h"
@ -608,8 +608,7 @@ uvmpd_scan_inactive(pglst)
* the inactive queue.
*/
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (uvmexp.swpgonly == uvmexp.swpages) {
if (uvm_swapisfull()) {
dirtyreacts++;
uvm_pageactivate(p);
simple_unlock(slock);
@ -790,8 +789,8 @@ uvmpd_scan(void)
swap_shortage = 0;
if (uvmexp.free < uvmexp.freetarg &&
uvmexp.swpginuse == uvmexp.swpages &&
uvmexp.swpgonly < uvmexp.swpages &&
uvmexp.swpginuse >= uvmexp.swpgavail &&
!uvm_swapisfull() &&
pages_freed == 0) {
swap_shortage = uvmexp.freetarg - uvmexp.free;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_swap.c,v 1.80 2003/06/29 22:32:51 fvdl Exp $ */
/* $NetBSD: uvm_swap.c,v 1.81 2003/08/11 16:33:30 pk Exp $ */
/*
* Copyright (c) 1995, 1996, 1997 Matthew R. Green
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.80 2003/06/29 22:32:51 fvdl Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.81 2003/08/11 16:33:30 pk Exp $");
#include "fs_nfs.h"
#include "opt_uvmhist.h"
@ -978,6 +978,7 @@ swap_on(p, sdp)
sdp->swd_flags &= ~SWF_FAKE; /* going live */
sdp->swd_flags |= (SWF_INUSE|SWF_ENABLE);
uvmexp.swpages += size;
uvmexp.swpgavail += size;
simple_unlock(&uvm.swap_data_lock);
return (0);
@ -1005,11 +1006,14 @@ swap_off(p, sdp)
struct proc *p;
struct swapdev *sdp;
{
int npages = sdp->swd_npages;
UVMHIST_FUNC("swap_off"); UVMHIST_CALLED(pdhist);
UVMHIST_LOG(pdhist, " dev=%x", sdp->swd_dev,0,0,0);
UVMHIST_LOG(pdhist, " dev=%x, npages=%d", sdp->swd_dev,npages,0,0);
/* disable the swap area being removed */
sdp->swd_flags &= ~SWF_ENABLE;
uvmexp.swpgavail -= npages;
simple_unlock(&uvm.swap_data_lock);
/*
@ -1026,6 +1030,7 @@ swap_off(p, sdp)
simple_lock(&uvm.swap_data_lock);
sdp->swd_flags |= SWF_ENABLE;
uvmexp.swpgavail += npages;
simple_unlock(&uvm.swap_data_lock);
return ENOMEM;
}
@ -1042,10 +1047,10 @@ swap_off(p, sdp)
}
/* remove anons from the system */
uvm_anon_remove(sdp->swd_npages);
uvm_anon_remove(npages);
simple_lock(&uvm.swap_data_lock);
uvmexp.swpages -= sdp->swd_npages;
uvmexp.swpages -= npages;
if (swaplist_find(sdp->swd_vp, 1) == NULL)
panic("swap_off: swapdev not in list");
@ -1520,6 +1525,19 @@ ReTry: /* XXXMRG */
return 0;
}
boolean_t
uvm_swapisfull(void)
{
boolean_t rv;
simple_lock(&uvm.swap_data_lock);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
rv = (uvmexp.swpgonly >= uvmexp.swpgavail);
simple_unlock(&uvm.swap_data_lock);
return (rv);
}
/*
* uvm_swap_markbad: keep track of swap ranges where we've had i/o errors
*
@ -1632,6 +1650,7 @@ uvm_swap_get(page, swslot, flags)
if (swslot == SWSLOT_BAD) {
return EIO;
}
error = uvm_swap_io(&page, swslot, 1, B_READ |
((flags & PGO_SYNCIO) ? 0 : B_ASYNC));
if (error == 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_swap.h,v 1.7 2003/07/21 00:54:43 mrg Exp $ */
/* $NetBSD: uvm_swap.h,v 1.8 2003/08/11 16:33:31 pk Exp $ */
/*
* Copyright (c) 1997 Matthew R. Green
@ -45,6 +45,7 @@ int uvm_swap_alloc(int *, boolean_t);
void uvm_swap_free(int, int);
void uvm_swap_markbad(int, int);
void uvm_swap_stats(int, struct swapent *, int, register_t *);
boolean_t uvm_swapisfull(void);
#endif /* _KERNEL */