summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_swap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/uvm/uvm_swap.c')
-rw-r--r--sys/uvm/uvm_swap.c105
1 files changed, 47 insertions, 58 deletions
diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c
index fc1d6861de1..95ecb9e7828 100644
--- a/sys/uvm/uvm_swap.c
+++ b/sys/uvm/uvm_swap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_swap.c,v 1.43 2001/11/28 13:47:40 art Exp $ */
-/* $NetBSD: uvm_swap.c,v 1.47 2001/03/10 22:46:51 chs Exp $ */
+/* $OpenBSD: uvm_swap.c,v 1.44 2001/11/28 19:28:15 art Exp $ */
+/* $NetBSD: uvm_swap.c,v 1.52 2001/05/26 16:32:47 chs Exp $ */
/*
* Copyright (c) 1995, 1996, 1997 Matthew R. Green
@@ -63,7 +63,7 @@
/*
* swap space is managed in the following way:
- *
+ *
* each swap partition or file is described by a "swapdev" structure.
* each "swapdev" structure contains a "swapent" structure which contains
* information that is passed up to the user (via system calls).
@@ -74,7 +74,7 @@
* the system maintains a global data structure describing all swap
* partitions/files. there is a sorted LIST of "swappri" structures
* which describe "swapdev"'s at that priority. this LIST is headed
- * by the "swap_priority" global var. each "swappri" contains a
+ * by the "swap_priority" global var. each "swappri" contains a
* CIRCLEQ of "swapdev" structures at that priority.
*
* locking:
@@ -99,7 +99,7 @@
* userland controls and configures swap with the swapctl(2) system call.
* the sys_swapctl performs the following operations:
* [1] SWAP_NSWAP: returns the number of swap devices currently configured
- * [2] SWAP_STATS: given a pointer to an array of swapent structures
+ * [2] SWAP_STATS: given a pointer to an array of swapent structures
* (passed in via "arg") of a size passed in via "misc" ... we load
* the current swap config into the array.
* [3] SWAP_ON: given a pathname in arg (could be device or file) and a
@@ -227,16 +227,15 @@ LIST_HEAD(swap_priority, swappri);
static struct swap_priority swap_priority;
/* locks */
-lock_data_t swap_syscall_lock;
+struct lock swap_syscall_lock;
/*
* prototypes
*/
-static void swapdrum_add __P((struct swapdev *, int));
static struct swapdev *swapdrum_getsdp __P((int));
static struct swapdev *swaplist_find __P((struct vnode *, int));
-static void swaplist_insert __P((struct swapdev *,
+static void swaplist_insert __P((struct swapdev *,
struct swappri *, int));
static void swaplist_trim __P((void));
@@ -262,7 +261,7 @@ void uvm_swap_initcrypt __P((struct swapdev *, int));
/*
* uvm_swap_init: init the swap system data structures and locks
*
- * => called at boot time from init_main.c after the filesystems
+ * => called at boot time from init_main.c after the filesystems
* are brought up (which happens after uvm_init())
*/
void
@@ -288,7 +287,7 @@ uvm_swap_init()
/*
* create swap block resource map to map /dev/drum. the range
* from 1 to INT_MAX allows 2 gigablocks of swap space. note
- * that block 0 is reserved (used to indicate an allocation
+ * that block 0 is reserved (used to indicate an allocation
* failure, or no allocation).
*/
swapmap = extent_create("swapmap", 1, INT_MAX,
@@ -563,27 +562,6 @@ swaplist_trim()
}
/*
- * swapdrum_add: add a "swapdev"'s blocks into /dev/drum's area.
- *
- * => caller must hold swap_syscall_lock
- * => uvm.swap_data_lock should be unlocked (we may sleep)
- */
-static void
-swapdrum_add(sdp, npages)
- struct swapdev *sdp;
- int npages;
-{
- u_long result;
-
- if (extent_alloc(swapmap, npages, EX_NOALIGN, 0, EX_NOBOUNDARY,
- EX_WAITOK, &result))
- panic("swapdrum_add");
-
- sdp->swd_drumoffset = result;
- sdp->swd_drumsize = npages;
-}
-
-/*
* swapdrum_getsdp: given a page offset in /dev/drum, convert it back
* to the "swapdev" that maps that section of the drum.
*
@@ -596,16 +574,19 @@ swapdrum_getsdp(pgno)
{
struct swapdev *sdp;
struct swappri *spp;
-
+
for (spp = LIST_FIRST(&swap_priority); spp != NULL;
spp = LIST_NEXT(spp, spi_swappri))
for (sdp = CIRCLEQ_FIRST(&spp->spi_swapdev);
sdp != (void *)&spp->spi_swapdev;
- sdp = CIRCLEQ_NEXT(sdp, swd_next))
+ sdp = CIRCLEQ_NEXT(sdp, swd_next)) {
+ if (sdp->swd_flags & SWF_FAKE)
+ continue;
if (pgno >= sdp->swd_drumoffset &&
pgno < (sdp->swd_drumoffset + sdp->swd_drumsize)) {
return sdp;
}
+ }
return NULL;
}
@@ -646,7 +627,7 @@ sys_swapctl(p, v, retval)
/*
* we handle the non-priv NSWAP and STATS request first.
*
- * SWAP_NSWAP: return number of config'd swap devices
+ * SWAP_NSWAP: return number of config'd swap devices
* [can also be obtained with uvmexp sysctl]
*/
if (SCARG(uap, cmd) == SWAP_NSWAP) {
@@ -660,9 +641,9 @@ sys_swapctl(p, v, retval)
/*
* SWAP_STATS: get stats on current # of configured swap devs
*
- * note that the swap_priority list can't change as long
+ * note that the swap_priority list can't change as long
* as we are holding the swap_syscall_lock. we don't want
- * to grab the uvm.swap_data_lock because we may fault&sleep during
+ * to grab the uvm.swap_data_lock because we may fault&sleep during
* copyout() and we don't want to be holding that lock then!
*/
if (SCARG(uap, cmd) == SWAP_STATS
@@ -678,7 +659,7 @@ sys_swapctl(p, v, retval)
for (sdp = CIRCLEQ_FIRST(&spp->spi_swapdev);
sdp != (void *)&spp->spi_swapdev && misc-- > 0;
sdp = CIRCLEQ_NEXT(sdp, swd_next)) {
- sdp->swd_inuse =
+ sdp->swd_inuse =
btodb((u_int64_t)sdp->swd_npginuse <<
PAGE_SHIFT);
error = copyout(&sdp->swd_se, sep,
@@ -698,7 +679,8 @@ sys_swapctl(p, v, retval)
count++;
#if defined(COMPAT_13)
if (SCARG(uap, cmd) == SWAP_OSTATS)
- ((struct oswapent *)sep)++;
+ sep = (struct swapent *)
+ ((struct oswapent *)sep + 1);
else
#endif
sep++;
@@ -710,7 +692,7 @@ sys_swapctl(p, v, retval)
*retval = count;
error = 0;
goto out;
- }
+ }
/*
* all other requests require superuser privs. verify.
@@ -797,14 +779,16 @@ sys_swapctl(p, v, retval)
*/
priority = SCARG(uap, misc);
+ sdp = malloc(sizeof *sdp, M_VMSWAP, M_WAITOK);
+ spp = malloc(sizeof *spp, M_VMSWAP, M_WAITOK);
simple_lock(&uvm.swap_data_lock);
- if ((sdp = swaplist_find(vp, 0)) != NULL) {
+ if (swaplist_find(vp, 0) != NULL) {
error = EBUSY;
simple_unlock(&uvm.swap_data_lock);
+ free(sdp, M_VMSWAP);
+ free(spp, M_VMSWAP);
break;
}
- sdp = malloc(sizeof *sdp, M_VMSWAP, M_WAITOK);
- spp = malloc(sizeof *spp, M_VMSWAP, M_WAITOK);
memset(sdp, 0, sizeof(*sdp));
sdp->swd_flags = SWF_FAKE; /* placeholder only */
sdp->swd_vp = vp;
@@ -905,6 +889,7 @@ swap_on(p, sdp)
struct vnode *vp;
int error, npages, nblocks, size;
long addr;
+ u_long result;
struct vattr va;
#if defined(NFSCLIENT)
extern int (**nfsv2_vnodeop_p) __P((void *));
@@ -1033,9 +1018,9 @@ swap_on(p, sdp)
}
/*
- * if the vnode we are swapping to is the root vnode
+ * if the vnode we are swapping to is the root vnode
* (i.e. we are swapping to the miniroot) then we want
- * to make sure we don't overwrite it. do a statfs to
+ * to make sure we don't overwrite it. do a statfs to
* find its size and skip over it.
*/
if (vp == rootvp) {
@@ -1050,7 +1035,7 @@ swap_on(p, sdp)
if (rootpages > size)
panic("swap_on: miniroot larger than swap?");
- if (extent_alloc_region(sdp->swd_ex, addr,
+ if (extent_alloc_region(sdp->swd_ex, addr,
rootpages, EX_WAITOK))
panic("swap_on: unable to preserve miniroot");
@@ -1080,9 +1065,14 @@ swap_on(p, sdp)
/*
* now add the new swapdev to the drum and enable.
*/
- simple_lock(&uvm.swap_data_lock);
- swapdrum_add(sdp, npages);
+ if (extent_alloc(swapmap, npages, EX_NOALIGN, 0, EX_NOBOUNDARY,
+ EX_WAITOK, &result))
+ panic("swapdrum_add");
+
+ sdp->swd_drumoffset = (int)result;
+ sdp->swd_drumsize = npages;
sdp->swd_npages = size;
+ simple_lock(&uvm.swap_data_lock);
sdp->swd_flags &= ~SWF_FAKE; /* going live */
sdp->swd_flags |= (SWF_INUSE|SWF_ENABLE);
uvmexp.swpages += size;
@@ -1131,7 +1121,7 @@ swap_off(p, sdp)
sdp->swd_drumoffset + sdp->swd_drumsize) ||
anon_swap_off(sdp->swd_drumoffset,
sdp->swd_drumoffset + sdp->swd_drumsize)) {
-
+
simple_lock(&uvm.swap_data_lock);
sdp->swd_flags |= SWF_ENABLE;
simple_unlock(&uvm.swap_data_lock);
@@ -1161,6 +1151,7 @@ swap_off(p, sdp)
if (swaplist_find(sdp->swd_vp, 1) == NULL)
panic("swap_off: swapdev not in list\n");
swaplist_trim();
+ simple_unlock(&uvm.swap_data_lock);
/*
* free all resources!
@@ -1169,7 +1160,6 @@ swap_off(p, sdp)
EX_WAITOK);
extent_destroy(sdp->swd_ex);
free(sdp, M_VMSWAP);
- simple_unlock(&uvm.swap_data_lock);
return (0);
}
@@ -1336,7 +1326,7 @@ sw_reg_strategy(sdp, bp, bn)
&vp, &nbn, &nra);
if (error == 0 && nbn == (daddr_t)-1) {
- /*
+ /*
* this used to just set error, but that doesn't
* do the right thing. Instead, it causes random
* memory errors. The panic() should remain until
@@ -1578,7 +1568,7 @@ uvm_swap_alloc(nslots, lessok)
*/
if (uvmexp.nswapdev < 1)
return 0;
-
+
/*
* lock data lock, convert slots into blocks, and enter loop
*/
@@ -1682,8 +1672,8 @@ uvm_swap_free(startslot, nslots)
}
/*
- * convert drum slot offset back to sdp, free the blocks
- * in the extent, and return. must hold pri lock to do
+ * convert drum slot offset back to sdp, free the blocks
+ * in the extent, and return. must hold pri lock to do
* lookup and access the extent.
*/
@@ -1765,7 +1755,7 @@ uvm_swap_get(page, swslot, flags)
uvmexp.swpgonly--;
simple_unlock(&uvm.swap_data_lock);
- result = uvm_swap_io(&page, swslot, 1, B_READ |
+ result = uvm_swap_io(&page, swslot, 1, B_READ |
((flags & PGO_SYNCIO) ? 0 : B_ASYNC));
if (result != 0) {
@@ -1906,7 +1896,7 @@ uvm_swap_io(pps, startslot, npages, flags)
}
#endif /* UVM_SWAP_ENCRYPT */
- /*
+ /*
* now allocate a buf for the i/o.
* [make sure we don't put the pagedaemon to sleep...]
*/
@@ -1962,9 +1952,8 @@ uvm_swap_io(pps, startslot, npages, flags)
splx(s);
bp->b_bufsize = bp->b_bcount = npages << PAGE_SHIFT;
- /*
- * for pageouts we must set "dirtyoff" [NFS client code needs it].
- * and we bump v_numoutput (counter of number of active outputs).
+ /*
+ * bump v_numoutput (counter of number of active outputs).
*/
if (write) {
#ifdef UVM_SWAP_ENCRYPT