Module Name: src Committed By: riz Date: Fri Apr 6 17:44:21 UTC 2012
Modified Files: src/sys/dev [netbsd-6]: vnd.c vndvar.h Log Message: Pull up following revision(s) (requested by hannken in ticket #162): sys/dev/vnd.c: revision 1.220 sys/dev/vndvar.h: revision 1.32 When backed by a sparse file limit the number of pending requests. Should fix PR #45829: "writing to vnd on sparse file blocks on pager_map" where the pager_map gets exhausted by requests enqueued on a vnd device and the device worker thread blocks on putpages() needing the map. While here always sync the underlying vnode before calling biodone(). XXX: vnd should be converted to mutex/condvar. To generate a diff of this commit: cvs rdiff -u -r1.219 -r1.219.8.1 src/sys/dev/vnd.c cvs rdiff -u -r1.31 -r1.31.8.1 src/sys/dev/vndvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/vnd.c diff -u src/sys/dev/vnd.c:1.219 src/sys/dev/vnd.c:1.219.8.1 --- src/sys/dev/vnd.c:1.219 Fri Oct 14 09:23:30 2011 +++ src/sys/dev/vnd.c Fri Apr 6 17:44:21 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vnd.c,v 1.219 2011/10/14 09:23:30 hannken Exp $ */ +/* $NetBSD: vnd.c,v 1.219.8.1 2012/04/06 17:44:21 riz Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.219 2011/10/14 09:23:30 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.219.8.1 2012/04/06 17:44:21 riz Exp $"); #if defined(_KERNEL_OPT) #include "opt_vnd.h" @@ -156,6 +156,8 @@ struct vndxfer { #define VNDLABELDEV(dev) \ (MAKEDISKDEV(major((dev)), vndunit((dev)), RAW_PART)) +#define VND_MAXPENDING(vnd) ((vnd)->sc_maxactive * 4) + /* called by main() at boot time */ void vndattach(int); @@ -496,6 +498,13 @@ vndstrategy(struct buf *bp) if (vnddebug & VDB_FOLLOW) printf("vndstrategy(%p): unit %d\n", bp, unit); #endif + if ((vnd->sc_flags & VNF_USE_VN_RDWR)) { + KASSERT(vnd->sc_pending >= 0 && + vnd->sc_pending <= VND_MAXPENDING(vnd)); + while (vnd->sc_pending == VND_MAXPENDING(vnd)) + tsleep(&vnd->sc_pending, PRIBIO, "vndpc", 0); + vnd->sc_pending++; + } bufq_put(vnd->sc_tab, bp); wakeup(&vnd->sc_tab); splx(s); @@ -587,6 +596,12 @@ vndthread(void *arg) tsleep(&vnd->sc_tab, PRIBIO, "vndbp", 0); continue; }; + if ((vnd->sc_flags & VNF_USE_VN_RDWR)) { + KASSERT(vnd->sc_pending > 0 && + vnd->sc_pending <= VND_MAXPENDING(vnd)); + if (vnd->sc_pending-- == VND_MAXPENDING(vnd)) + wakeup(&vnd->sc_pending); + } splx(s); flags = obp->b_flags; #ifdef DEBUG @@ -722,13 +737,9 @@ handle_with_rdwr(struct vnd_softc *vnd, IO_ADV_ENCODE(POSIX_FADV_NOREUSE), vnd->sc_cred, &resid, NULL); bp->b_resid = resid; - /* Keep mapped pages below threshold. */ mutex_enter(vp->v_interlock); - if (vp->v_uobj.uo_npages > 1024*1024 / PAGE_SIZE) - (void) VOP_PUTPAGES(vp, 0, 0, - PGO_ALLPAGES | PGO_CLEANIT | PGO_FREE | PGO_SYNCIO); - else - mutex_exit(vp->v_interlock); + (void) VOP_PUTPAGES(vp, 0, 0, + PGO_ALLPAGES | PGO_CLEANIT | PGO_FREE | PGO_SYNCIO); /* We need to increase the number of outputs on the vnode if * there was any write to it. */ Index: src/sys/dev/vndvar.h diff -u src/sys/dev/vndvar.h:1.31 src/sys/dev/vndvar.h:1.31.8.1 --- src/sys/dev/vndvar.h:1.31 Wed Jun 29 09:12:42 2011 +++ src/sys/dev/vndvar.h Fri Apr 6 17:44:21 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vndvar.h,v 1.31 2011/06/29 09:12:42 hannken Exp $ */ +/* $NetBSD: vndvar.h,v 1.31.8.1 2012/04/06 17:44:21 riz Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. @@ -113,6 +113,7 @@ struct vnd_softc { kauth_cred_t sc_cred; /* credentials */ int sc_maxactive; /* max # of active requests */ struct bufq_state *sc_tab; /* transfer queue */ + int sc_pending; /* number of pending transfers */ int sc_active; /* number of active transfers */ struct disk sc_dkdev; /* generic disk device info */ struct vndgeom sc_geom; /* virtual geometry */