Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev When backed by a sparse file limit the number of pen...



details:   https://anonhg.NetBSD.org/src/rev/a2248d9e554e
branches:  trunk
changeset: 778442:a2248d9e554e
user:      hannken <hannken%NetBSD.org@localhost>
date:      Mon Mar 26 16:28:08 2012 +0000

description:
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.

diffstat:

 sys/dev/vnd.c    |  27 +++++++++++++++++++--------
 sys/dev/vndvar.h |   3 ++-
 2 files changed, 21 insertions(+), 9 deletions(-)

diffs (87 lines):

diff -r b4f1b34edd89 -r a2248d9e554e sys/dev/vnd.c
--- a/sys/dev/vnd.c     Mon Mar 26 15:13:20 2012 +0000
+++ b/sys/dev/vnd.c     Mon Mar 26 16:28:08 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vnd.c,v 1.219 2011/10/14 09:23:30 hannken Exp $        */
+/*     $NetBSD: vnd.c,v 1.220 2012/03/26 16:28:08 hannken 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.220 2012/03/26 16:28:08 hannken Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_vnd.h"
@@ -156,6 +156,8 @@
 #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 @@
        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 @@
                        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 @@
            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. */
diff -r b4f1b34edd89 -r a2248d9e554e sys/dev/vndvar.h
--- a/sys/dev/vndvar.h  Mon Mar 26 15:13:20 2012 +0000
+++ b/sys/dev/vndvar.h  Mon Mar 26 16:28:08 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vndvar.h,v 1.31 2011/06/29 09:12:42 hannken Exp $      */
+/*     $NetBSD: vndvar.h,v 1.32 2012/03/26 16:28:08 hannken Exp $      */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -113,6 +113,7 @@
        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 */



Home | Main Index | Thread Index | Old Index