From d474eaaa5fa26915fc4389a789e833f4e0159c0c Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Thu, 6 Aug 1998 08:33:19 +0000 Subject: [PATCH] Protect all modifications to paging_in_progress with splvm(). The i386 managed to avoid corruption of this variable by luck (the compiler used a memory read-modify-write instruction which wasn't interruptable) but other architectures cannot. With this change, I am now able to 'make buildworld' on the alpha (sfx: the crowd goes wild...) --- sys/kern/vfs_bio.c | 10 +++++++--- sys/kern/vfs_cluster.c | 8 ++++++-- sys/vm/vm_fault.c | 6 +++--- sys/vm/vm_map.c | 6 +++--- sys/vm/vm_object.c | 10 +++++----- sys/vm/vm_object.h | 13 ++++++++++++- sys/vm/vm_pageout.c | 4 ++-- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index ee0e53c36d2c..e1cb45a4b875 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -11,7 +11,7 @@ * 2. Absolutely no warranty of function or purpose is made by the author * John S. Dyson. * - * $Id: vfs_bio.c,v 1.166 1998/07/08 01:04:27 julian Exp $ + * $Id: vfs_bio.c,v 1.167 1998/07/13 07:05:55 bde Exp $ */ /* @@ -2104,7 +2104,7 @@ SYSCTL_PROC(_kern, KERN_UPDATEINTERVAL, update, CTLTYPE_INT|CTLFLAG_RW, void vfs_unbusy_pages(struct buf * bp) { - int i; + int i, s; if (bp->b_flags & B_VMIO) { struct vnode *vp = bp->b_vp; @@ -2123,7 +2123,9 @@ vfs_unbusy_pages(struct buf * bp) bp->b_pages[i] = m; pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); } + s = splvm(); --obj->paging_in_progress; + splx(s); m->flags &= ~PG_ZERO; PAGE_BWAKEUP(m); } @@ -2221,7 +2223,7 @@ vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, int pageno, vm_page_t m) void vfs_busy_pages(struct buf * bp, int clear_modify) { - int i,s; + int i, s; if (bp->b_flags & B_VMIO) { struct vnode *vp = bp->b_vp; @@ -2248,7 +2250,9 @@ vfs_busy_pages(struct buf * bp, int clear_modify) m->flags &= ~PG_ZERO; if ((bp->b_flags & B_CLUSTER) == 0) { + s = splvm(); obj->paging_in_progress++; + splx(s); m->busy++; } diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index 0ab55fa85e8d..94da3f7e054e 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -33,7 +33,7 @@ * SUCH DAMAGE. * * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 - * $Id: vfs_cluster.c,v 1.65 1998/07/11 10:45:45 bde Exp $ + * $Id: vfs_cluster.c,v 1.66 1998/07/29 17:38:14 bde Exp $ */ #include "opt_debug_cluster.h" @@ -309,7 +309,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) { struct buf *bp, *tbp; daddr_t bn; - int i, inc, j; + int i, inc, j, s; #ifdef DIAGNOSTIC if (size != vp->v_mount->mnt_stat.f_iosize) @@ -417,8 +417,10 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) for (j = 0; j < tbp->b_npages; j += 1) { vm_page_t m; m = tbp->b_pages[j]; + s = splvm(); ++m->busy; ++m->object->paging_in_progress; + splx(s); if ((bp->b_npages == 0) || (bp->b_pages[bp->b_npages-1] != m)) { bp->b_pages[bp->b_npages] = m; @@ -782,8 +784,10 @@ cluster_wbuild(vp, size, start_lbn, len) for (j = 0; j < tbp->b_npages; j += 1) { m = tbp->b_pages[j]; + s = splvm(); ++m->busy; ++m->object->paging_in_progress; + splx(s); if ((bp->b_npages == 0) || (bp->b_pages[bp->b_npages - 1] != m)) { bp->b_pages[bp->b_npages] = m; diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 850dfdc335c7..f07423468160 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -66,7 +66,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_fault.c,v 1.84 1998/07/11 12:07:52 bde Exp $ + * $Id: vm_fault.c,v 1.85 1998/07/22 09:38:04 dg Exp $ */ /* @@ -241,7 +241,7 @@ RetryFault:; * they will stay around as well. */ vm_object_reference(fs.first_object); - fs.first_object->paging_in_progress++; + vm_object_pip_add(fs.first_object, 1); fs.vp = vnode_pager_lock(fs.first_object); if ((fault_type & VM_PROT_WRITE) && @@ -525,7 +525,7 @@ RetryFault:; vm_object_pip_wakeup(fs.object); } fs.object = next_object; - fs.object->paging_in_progress++; + vm_object_pip_add(fs.object, 1); } } diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index faf144fd6474..398a9eba24b9 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_map.c,v 1.131 1998/07/11 11:30:43 bde Exp $ + * $Id: vm_map.c,v 1.132 1998/07/14 12:14:58 bde Exp $ */ /* @@ -2001,7 +2001,7 @@ vm_map_split(entry) } if (orig_object->type == OBJT_SWAP) { - orig_object->paging_in_progress++; + vm_object_pip_add(orig_object, 1); /* * copy orig_object pages into new_object * and destroy unneeded pages in @@ -2778,7 +2778,7 @@ vm_freeze_copyopts(object, froma, toa) continue; } - robject->paging_in_progress++; + vm_object_pip_add(robject, 1); for (idx = 0; idx < robject->size; idx++) { diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 3d9ae5a06c71..1af903f20c1e 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_object.c,v 1.124 1998/07/11 11:30:45 bde Exp $ + * $Id: vm_object.c,v 1.125 1998/07/14 12:26:15 bde Exp $ */ /* @@ -1102,9 +1102,9 @@ vm_object_collapse(object) */ if (backing_object->type == OBJT_SWAP) { - backing_object->paging_in_progress++; + vm_object_pip_add(backing_object, 1); if (object->type == OBJT_SWAP) { - object->paging_in_progress++; + vm_object_pip_add(object, 1); /* * copy shadow object pages into ours * and destroy unneeded pages in @@ -1118,7 +1118,7 @@ vm_object_collapse(object) OFF_TO_IDX(object->backing_object_offset), TRUE); vm_object_pip_wakeup(object); } else { - object->paging_in_progress++; + vm_object_pip_add(object, 1); /* * move the shadow backing_object's pager data to * "object" and convert "object" type to OBJT_SWAP. @@ -1314,7 +1314,7 @@ vm_object_page_remove(object, start, end, clean_only) all = ((end == 0) && (start == 0)); - object->paging_in_progress++; + vm_object_pip_add(object, 1); again: size = end - start; if (all || size > 4 || size >= object->size / 4) { diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index e700d5321a69..4855a8027be8 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -61,7 +61,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_object.h,v 1.48 1998/04/29 04:28:12 dyson Exp $ + * $Id: vm_object.h,v 1.49 1998/05/04 17:12:53 dyson Exp $ */ /* @@ -160,10 +160,21 @@ extern vm_object_t kmem_object; #endif /* KERNEL */ #ifdef KERNEL + +static __inline void +vm_object_pip_add(vm_object_t object, int i) +{ + int s = splvm(); + object->paging_in_progress += i; + splx(s); +} + static __inline void vm_object_pip_wakeup(vm_object_t object) { + int s = splvm(); object->paging_in_progress--; + splx(s); if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) { object->flags &= ~OBJ_PIPWNT; wakeup(object); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 205b877ef086..ce39df586bf1 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -65,7 +65,7 @@ * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * - * $Id: vm_pageout.c,v 1.122 1998/06/02 05:39:13 dyson Exp $ + * $Id: vm_pageout.c,v 1.123 1998/07/10 17:58:35 alex Exp $ */ /* @@ -367,7 +367,7 @@ vm_pageout_flush(mc, count, flags) } object = mc[0]->object; - object->paging_in_progress += count; + vm_object_pip_add(object, count); vm_pager_put_pages(object, mc, count, (flags | ((object == kernel_object) ? OBJPC_SYNC : 0)),