tech-kern archive

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

Re: netbsd-5 deadlocks when memory is low



Masao Uebayashi <uebayasi%gmail.com@localhost> wrote:

> > I do not see any kernel thread stuck anymore, so is that the problem?
> No, it isn't.

While we are at that, here are the change I did to avoid ioflush getting
stuck in PUFFS. That is against netbsd-5 with not-yet-pulled-up
pn->pn_sizemtx change (the patch was edited for the sake of
readability). Does it looks reasonable? If it is I will port that to
-current and commit.

I wonder if I have to check for updateproc, or just for any kernel
thread (with something like l->l_proc->p_flag == PK_SYSTEM)

Index: sys/fs/puffs/puffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/puffs/puffs_vnops.c,v
retrieving revision 1.129.4.9
diff -u -p -d -r1.129.4.9 puffs_vnops.c
--- sys/fs/puffs/puffs_vnops.c  17 Jul 2011 15:36:03 -0000
1.129.4.9
+++ sys/fs/puffs/puffs_vnops.c  17 Sep 2011 03:39:52 -0000
@@ -50,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: puffs_vnops.
 #include <miscfs/genfs/genfs.h>
 #include <miscfs/specfs/specdev.h>
 
+extern struct lwp *updateproc;
+
 int    puffs_vnop_lookup(void *);
 int    puffs_vnop_create(void *);
 int    puffs_vnop_access(void *);
@@ -1342,13 +1369,26 @@ puffs_vnop_fsync(void *v)
        } */ *ap = v;
        PUFFS_MSG_VARS(vn, fsync);
        struct vnode *vp = ap->a_vp;
        struct puffs_node *pn = VPTOPP(vp);
        struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
        int error, dofaf;
 
-        mutex_enter(&pn->pn_sizemtx);
+       /*
+        * Make sure ioflush does not get stuck in low
+        * memory conditions: it should not wait for the
+        * mutex.
+        */
+       if (curlwp == updateproc) {
+               if (mutex_tryenter(&pn->pn_sizemtx) == 0)
+                       return EDEADLK;
+       } else {
+               mutex_enter(&pn->pn_sizemtx);
+       }
+
        error = flushvncache(vp, ap->a_offlo, ap->a_offhi,
            (ap->a_flags & FSYNC_WAIT) == FSYNC_WAIT);
        if (error)
@@ -2209,12 +2256,13 @@ puffs_vnop_strategy(void *v)
        struct buf *bp;
        size_t argsize;
        size_t tomove, moved;
-       int error, dofaf, dobiodone;
+       int error, dofaf, cansleep, dobiodone;
 
        pmp = MPTOPUFFSMP(vp->v_mount);
        bp = ap->a_bp;
        error = 0;
        dofaf = 0;
+       cansleep = 0;
        pn = VPTOPP(vp);
        park_rw = NULL; /* explicit */
        dobiodone = 1;
@@ -2252,8 +2300,9 @@ puffs_vnop_strategy(void *v)
        /* allocate transport structure */
        tomove = PUFFS_TOMOVE(bp->b_bcount, pmp);
        argsize = sizeof(struct puffs_vnmsg_rw);
+       cansleep = (dofaf || (curlwp == updateproc)) ? 0 : 1; 
        error = puffs_msgmem_alloc(argsize + tomove, &park_rw,
-           (void *)&rw_msg, dofaf ? 0 : 1);
+           (void *)&rw_msg, cansleep);
        if (error)
                goto out;
        RWARGS(rw_msg, 0, tomove, bp->b_blkno << DEV_BSHIFT, FSCRED);

-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index