Module Name: src Committed By: rmind Date: Wed Aug 31 22:16:54 UTC 2011
Modified Files: src/sys/miscfs/genfs: genfs_io.c Log Message: genfs_do_directio: acquire the lock of page owner for now and fix PR/45177. Will be revisited to avoid locking dance and be more efficient, e.g. we can use unmanaged-mapping by allocating with colouring in mind. To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.50 src/sys/miscfs/genfs/genfs_io.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/miscfs/genfs/genfs_io.c diff -u src/sys/miscfs/genfs/genfs_io.c:1.49 src/sys/miscfs/genfs/genfs_io.c:1.50 --- src/sys/miscfs/genfs/genfs_io.c:1.49 Sun Jun 12 03:35:58 2011 +++ src/sys/miscfs/genfs/genfs_io.c Wed Aug 31 22:16:54 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_io.c,v 1.49 2011/06/12 03:35:58 rmind Exp $ */ +/* $NetBSD: genfs_io.c,v 1.50 2011/08/31 22:16:54 rmind Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.49 2011/06/12 03:35:58 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.50 2011/08/31 22:16:54 rmind Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1748,6 +1748,8 @@ int error, rv, poff, koff; const int pgoflags = PGO_CLEANIT | PGO_SYNCIO | PGO_JOURNALLOCKED | (rw == UIO_WRITE ? PGO_FREE : 0); + struct vm_page *pg; + kmutex_t *slock; /* * For writes, verify that this range of the file already has fully @@ -1804,13 +1806,22 @@ kva = uvm_km_alloc(kernel_map, klen, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA); puva = trunc_page(uva); - mutex_enter(vp->v_interlock); for (poff = 0; poff < klen; poff += PAGE_SIZE) { rv = pmap_extract(upm, puva + poff, &pa); KASSERT(rv); + pg = PHYS_TO_VM_PAGE(pa); + +retry1: /* XXX: Rework to not use managed-mappings.. */ + mutex_enter(&uvm_pageqlock); + slock = uvmpd_trylockowner(pg); + mutex_exit(&uvm_pageqlock); + if (slock == NULL) { + kpause("gendiolk", false, 1, slock); + goto retry1; + } pmap_enter(kpm, kva + poff, pa, prot, prot | PMAP_WIRED); + mutex_exit(slock); } - mutex_exit(vp->v_interlock); pmap_update(kpm); /* @@ -1825,9 +1836,24 @@ * Tear down the kernel mapping. */ - mutex_enter(vp->v_interlock); - pmap_remove(kpm, kva, kva + klen); - mutex_exit(vp->v_interlock); + for (koff = 0; koff < klen; koff += PAGE_SIZE) { + vaddr_t sva = kva + koff; + + rv = pmap_extract(kpm, sva, &pa); + KASSERT(rv); + pg = PHYS_TO_VM_PAGE(pa); + +retry2: /* XXX: Rework to not use managed-mappings.. */ + mutex_enter(&uvm_pageqlock); + slock = uvmpd_trylockowner(pg); + mutex_exit(&uvm_pageqlock); + if (slock == NULL) { + kpause("gendiolk", false, 1, slock); + goto retry2; + } + pmap_remove(kpm, sva, sva + PAGE_SIZE); + mutex_exit(slock); + } pmap_update(kpm); uvm_km_free(kernel_map, kva, klen, UVM_KMF_VAONLY); @@ -1838,4 +1864,3 @@ uvm_vsunlock(vs, (void *)uva, len); return error; } -