summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-10-29 05:42:28 +0000
committeralc <alc@FreeBSD.org>2003-10-29 05:42:28 +0000
commit4307e55d6c9333394c2fcef18b61d89a043e83eb (patch)
tree1645a6c3cf9c9a668da118dbe408625524b96f9d /sys
parent409cf5f514ad9056b7dac76a11c4844021c2be2b (diff)
downloadFreeBSD-src-4307e55d6c9333394c2fcef18b61d89a043e83eb.zip
FreeBSD-src-4307e55d6c9333394c2fcef18b61d89a043e83eb.tar.gz
- Avoid a race in swaponsomething(): Calculate the new swdevt's first and
end swblk and insert this new swdevt into the list of swap devices in the same critical section.
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/swap_pager.c31
1 files changed, 14 insertions, 17 deletions
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 2bc4cc3..a7edae2 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -2118,24 +2118,10 @@ done2:
static void
swaponsomething(struct vnode *vp, void *id, u_long nblks, sw_strategy_t *strategy, sw_close_t *close, udev_t udev)
{
- struct swdevt *sp;
+ struct swdevt *sp, *tsp;
swblk_t dvbase;
u_long mblocks;
- dvbase = 0;
- mtx_lock(&sw_dev_mtx);
- TAILQ_FOREACH(sp, &swtailq, sw_list) {
- if (sp->sw_end >= dvbase) {
- /*
- * We put one uncovered page between the devices
- * in order to definitively prevent any cross-device
- * I/O requests
- */
- dvbase = sp->sw_end + 1;
- }
- }
- mtx_unlock(&sw_dev_mtx);
-
/*
* If we go beyond this, we get overflows in the radix
* tree bitmap code.
@@ -2162,8 +2148,6 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, sw_strategy_t *strateg
sp->sw_flags = 0;
sp->sw_nblks = nblks;
sp->sw_used = 0;
- sp->sw_first = dvbase;
- sp->sw_end = dvbase + nblks;
sp->sw_strategy = strategy;
sp->sw_close = close;
@@ -2174,7 +2158,20 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, sw_strategy_t *strateg
*/
blist_free(sp->sw_blist, 2, nblks - 2);
+ dvbase = 0;
mtx_lock(&sw_dev_mtx);
+ TAILQ_FOREACH(tsp, &swtailq, sw_list) {
+ if (tsp->sw_end >= dvbase) {
+ /*
+ * We put one uncovered page between the devices
+ * in order to definitively prevent any cross-device
+ * I/O requests
+ */
+ dvbase = tsp->sw_end + 1;
+ }
+ }
+ sp->sw_first = dvbase;
+ sp->sw_end = dvbase + nblks;
TAILQ_INSERT_TAIL(&swtailq, sp, sw_list);
mtx_unlock(&sw_dev_mtx);
nswapdev++;
OpenPOWER on IntegriCloud