diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-07-26 19:37:14 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-07-26 19:37:14 +0000 |
commit | 34736e0579123f60efbe00cf506fd4b82e5b769a (patch) | |
tree | 1e8806da205009ef73327c70f28319fe7e5df798 /sys/uvm/uvm_pager.c | |
parent | 78e879ae8deee32b2668976fbffb5a125629ba39 (diff) |
Add support for disabling swap devices (swapctl -d).
Improve error handling on I/O errors to swap.
From NetBSD
Diffstat (limited to 'sys/uvm/uvm_pager.c')
-rw-r--r-- | sys/uvm/uvm_pager.c | 114 |
1 files changed, 58 insertions, 56 deletions
diff --git a/sys/uvm/uvm_pager.c b/sys/uvm/uvm_pager.c index cb836859f90..266e63a69be 100644 --- a/sys/uvm/uvm_pager.c +++ b/sys/uvm/uvm_pager.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_pager.c,v 1.11 2001/07/25 13:25:33 art Exp $ */ -/* $NetBSD: uvm_pager.c,v 1.24 1999/11/13 00:24:38 thorpej Exp $ */ +/* $OpenBSD: uvm_pager.c,v 1.12 2001/07/26 19:37:13 art Exp $ */ +/* $NetBSD: uvm_pager.c,v 1.25 2000/01/11 06:57:50 chs Exp $ */ /* * @@ -529,7 +529,7 @@ ReTry: simple_lock(&uobj->vmobjlock); if (*npages > 1 || pg == NULL) uvm_pager_dropcluster(uobj, pg, ppsp, npages, - PGO_PDFREECLUST, 0); + PGO_PDFREECLUST); /* if (uobj): object still locked, as per * return-state item #3 */ } @@ -543,12 +543,61 @@ ReTry: */ if (*npages > 1 || pg == NULL) { - if (uobj) + if (uobj) { simple_lock(&uobj->vmobjlock); - uvm_pager_dropcluster(uobj, pg, ppsp, npages, PGO_REALLOCSWAP, - swblk); - if (pg != NULL) - goto ReTry; + } + uvm_pager_dropcluster(uobj, pg, ppsp, npages, PGO_REALLOCSWAP); + + /* + * for failed swap-backed pageouts with a "pg", + * we need to reset pg's swslot to either: + * "swblk" (for transient errors, so we can retry), + * or 0 (for hard errors). + */ + + if (uobj == NULL && pg != NULL) { + int nswblk = (result == VM_PAGER_AGAIN) ? swblk : 0; + if (pg->pqflags & PQ_ANON) { + simple_lock(&pg->uanon->an_lock); + pg->uanon->an_swslot = nswblk; + simple_unlock(&pg->uanon->an_lock); + } else { + simple_lock(&pg->uobject->vmobjlock); + uao_set_swslot(pg->uobject, + pg->offset >> PAGE_SHIFT, + nswblk); + simple_unlock(&pg->uobject->vmobjlock); + } + } + if (result == VM_PAGER_AGAIN) { + + /* + * for transient failures, free all the swslots that + * we're not going to retry with. + */ + + if (uobj == NULL) { + if (pg) { + uvm_swap_free(swblk + 1, *npages - 1); + } else { + uvm_swap_free(swblk, *npages); + } + } + if (pg) { + ppsp[0] = pg; + *npages = 1; + goto ReTry; + } + } else if (uobj == NULL) { + + /* + * for hard errors on swap-backed pageouts, + * mark the swslots as bad. note that we do not + * free swslots that we mark bad. + */ + + uvm_swap_markbad(swblk, *npages); + } } /* @@ -582,35 +631,17 @@ ReTry: */ void -uvm_pager_dropcluster(uobj, pg, ppsp, npages, flags, swblk) +uvm_pager_dropcluster(uobj, pg, ppsp, npages, flags) struct uvm_object *uobj; /* IN */ struct vm_page *pg, **ppsp; /* IN, IN/OUT */ int *npages; /* IN/OUT */ int flags; - int swblk; /* valid if - (uobj == NULL && PGO_REALLOCSWAP) */ { int lcv; boolean_t obj_is_alive; struct uvm_object *saved_uobj; /* - * if we need to reallocate swap space for the cluster we are dropping - * (true if swap-backed and PGO_REALLOCSWAP) then free the old - * allocation now. save a block for "pg" if it is non-NULL. - * - * note that we will zap the object's pointer to swap in the "for" loop - * below... - */ - - if (uobj == NULL && (flags & PGO_REALLOCSWAP)) { - if (pg) - uvm_swap_free(swblk + 1, *npages - 1); - else - uvm_swap_free(swblk, *npages); - } - - /* * drop all pages but "pg" */ @@ -717,34 +748,5 @@ uvm_pager_dropcluster(uobj, pg, ppsp, npages, flags, swblk) else simple_unlock(&ppsp[lcv]->uobject->vmobjlock); } - - } - - /* - * drop to a cluster of 1 page ("pg") if requested - */ - - if (pg && (flags & PGO_PDFREECLUST) == 0) { - /* - * if we are not a successful pageout, we make a 1 page cluster. - */ - ppsp[0] = pg; - *npages = 1; - - /* - * assign new swap block to new cluster, if anon backed - */ - if (uobj == NULL && (flags & PGO_REALLOCSWAP)) { - if (pg->pqflags & PQ_ANON) { - simple_lock(&pg->uanon->an_lock); - pg->uanon->an_swslot = swblk; /* reassign */ - simple_unlock(&pg->uanon->an_lock); - } else { - simple_lock(&pg->uobject->vmobjlock); - uao_set_swslot(pg->uobject, - pg->offset >> PAGE_SHIFT, swblk); - simple_unlock(&pg->uobject->vmobjlock); - } - } } } |