summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_pager.c
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2001-07-26 19:37:14 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2001-07-26 19:37:14 +0000
commit34736e0579123f60efbe00cf506fd4b82e5b769a (patch)
tree1e8806da205009ef73327c70f28319fe7e5df798 /sys/uvm/uvm_pager.c
parent78e879ae8deee32b2668976fbffb5a125629ba39 (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.c114
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);
- }
- }
}
}