From cc1fd6a93d1475867ff2e88fb029a898424372d0 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Sat, 25 Apr 2020 20:56:01 -0500 Subject: [PATCH 1/1] FBSD: Lock vm object before vm_page_undirty We must write-lock the underlying vm object before calling vm_page_undirty; otherwise vm_page_undirty asserts if INVARIANTS is defined. For example: kernel: panic: Lock vm object not exclusively locked @ /usr/src/sys/vm/vm_page.c:4487 kernel: kernel: cpuid = 0 kernel: time = 1587858280 kernel: KDB: stack backtrace: kernel: #0 0xffffffff80bf0c07 at kdb_backtrace+0x67 kernel: #1 0xffffffff80ba7f8d at vpanic+0x19d kernel: #2 0xffffffff80ba7d73 at panic+0x43 kernel: #3 0xffffffff80ba3a7e at __rw_assert+0x17e kernel: #4 0xffffffff828da525 at vm_page_undirty+0x15 kernel: #5 0xffffffff828da33e at afs_vop_putpages+0x36e kernel: #6 0xffffffff811ef0ae at VOP_PUTPAGES_APV+0x8e kernel: #7 0xffffffff80ef4c2d at vnode_pager_putpages+0x7d kernel: #8 0xffffffff80ee77cf at vm_pageout_flush+0xff kernel: #9 0xffffffff80edd1b9 at vm_object_page_collect_flush+0x239 kernel: #10 0xffffffff80edce99 at vm_object_page_clean+0x179 kernel: #11 0xffffffff828d681c at osi_VM_StoreAllSegments+0x18c kernel: #12 0xffffffff828508cd at afs_StoreAllSegments+0x9d kernel: #13 0xffffffff8287ae0e at afs_StoreOnLastReference+0x17e kernel: #14 0xffffffff8287c3a5 at afs_close+0x245 kernel: #15 0xffffffff828d7766 at afs_vop_close+0x166 kernel: #16 0xffffffff811eb7a8 at VOP_CLOSE_APV+0x88 kernel: #17 0xffffffff80c80ba3 at vn_close1+0xe3 So, lock the vm object before undirtying our pages in afs_vop_putpages. Change-Id: Ifd047e3caf8c2b3e624aaf2bbdb1235a8c38a414 Reviewed-on: https://gerrit.openafs.org/14162 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- src/afs/FBSD/osi_vnodeops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index e314e4c..2a0c2ab 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -743,11 +743,13 @@ afs_vop_putpages(struct vop_putpages_args *ap) relpbuf(bp, &afs_pbuf_freecnt); if (!code) { + AFS_VM_OBJECT_WLOCK(vp->v_object); size = ap->a_count - uio.uio_resid; for (i = 0; i < round_page(size) / PAGE_SIZE; i++) { ap->a_rtvals[i] = VM_PAGER_OK; vm_page_undirty(ap->a_m[i]); } + AFS_VM_OBJECT_WUNLOCK(vp->v_object); } return ap->a_rtvals[0]; } -- 1.9.4