tech-kern archive

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

Re: panic due to lost vnode flag



On Thu, Oct 22, 2009 at 07:03:53PM +0200, Bernd Ernesti wrote:
> On Thu, Oct 22, 2009 at 01:30:36PM +0200, Matthias Drochner wrote:
> > 
> > Hi -
> > I'm getting a diagnostic panic occasionally, when I
> > do some compilations cuncurrently:
> > kernel diagnostic assertion "vp->v_iflag & VI_TEXT" failed:
> > file "../../../../kern/exec_subr.c", line 162
> 
> [..]
> 
> > This is i386/-current on a dual-core box.
> > Any ideas?
> 
> Unfortunally no. I opened the pr$41245 in August and you are now the
> third one who has this problem.

Could all thoses who have the problem try the attached patch (against
netbsd-5 but should apply without much problems to HEAD) ?

-- 
Manuel Bouyer, LIP6, Universite Paris VI.           
Manuel.Bouyer%lip6.fr@localhost
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.357.4.5
diff -u -p -u -r1.357.4.5 vfs_subr.c
--- kern/vfs_subr.c     21 Jul 2009 00:31:58 -0000      1.357.4.5
+++ kern/vfs_subr.c     23 Oct 2009 14:26:43 -0000
@@ -370,6 +370,17 @@ try_nextlist:
        vp->v_freelisthd = NULL;
        mutex_exit(&vnode_free_list_lock);
 
+       if (vp->v_usecount != 0) {
+               /*
+                * was referenced again before we got the interlock
+                * Don't return to freelist - the holder of the last
+                * reference will destroy it.
+                */
+               vrelel(vp, 0); /* releases vp->v_interlock */
+               mutex_enter(&vnode_free_list_lock);
+               goto retry;
+       }
+
        /*
         * The vnode is still associated with a file system, so we must
         * clean it out before reusing it.  We need to add a reference
@@ -1288,6 +1299,22 @@ vget(vnode_t *vp, int flags)
                vrelel(vp, 0);
                return ENOENT;
        }
+
+       if ((vp->v_iflag & VI_INACTNOW) != 0) {
+               /*
+                * if it's being desactived, wait for it to complete.
+                * Make sure to not return a clean vnode.
+                */
+                if ((flags & LK_NOWAIT) != 0) {
+                       vrelel(vp, 0);
+                       return EBUSY;
+               }
+               vwait(vp, VI_INACTNOW);
+               if ((vp->v_iflag & VI_CLEAN) != 0) {
+                       vrelel(vp, 0);
+                       return ENOENT;
+               }
+       }
        if (flags & LK_TYPE_MASK) {
                error = vn_lock(vp, flags | LK_INTERLOCK);
                if (error != 0) {
@@ -1428,6 +1455,7 @@ vrelel(vnode_t *vp, int flags)
                                cv_signal(&vrele_cv); 
                        mutex_exit(&vrele_lock);
                        mutex_exit(&vp->v_interlock);
+                       cv_broadcast(&vp->v_cv);
                        return;
                }
 
@@ -1454,6 +1482,7 @@ vrelel(vnode_t *vp, int flags)
                if (!recycle) {
                        if (vtryrele(vp)) {
                                mutex_exit(&vp->v_interlock);
+                               cv_broadcast(&vp->v_cv);
                                return;
                        }
 
@@ -1489,6 +1518,7 @@ vrelel(vnode_t *vp, int flags)
        if (atomic_dec_uint_nv(&vp->v_usecount) != 0) {
                /* Gained another reference while being reclaimed. */
                mutex_exit(&vp->v_interlock);
+               cv_broadcast(&vp->v_cv);
                return;
        }
 
@@ -1520,6 +1550,7 @@ vrelel(vnode_t *vp, int flags)
                TAILQ_INSERT_TAIL(vp->v_freelisthd, vp, v_freelist);
                mutex_exit(&vnode_free_list_lock);
                mutex_exit(&vp->v_interlock);
+               cv_broadcast(&vp->v_cv);
        }
 }
 
Index: ufs/ufs/ufs_ihash.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_ihash.c,v
retrieving revision 1.26.10.1
diff -u -p -u -r1.26.10.1 ufs_ihash.c
--- ufs/ufs/ufs_ihash.c 28 Sep 2009 01:43:02 -0000      1.26.10.1
+++ ufs/ufs/ufs_ihash.c 23 Oct 2009 14:26:43 -0000
@@ -152,6 +152,7 @@ ufs_ihashget(dev_t dev, ino_t inum, int 
                                mutex_exit(&ufs_ihash_lock);
                                if (vget(vp, flags | LK_INTERLOCK))
                                        goto loop;
+#if 0
                                if (VTOI(vp) != ip ||
                                    ip->i_number != inum || ip->i_dev != dev) {
                                        /* lost race against vclean() */
@@ -161,6 +162,7 @@ ufs_ihashget(dev_t dev, ino_t inum, int 
                                        vp = NULL;
                                        goto loop;
                                }
+#endif
                        }
                        return (vp);
                }


Home | Main Index | Thread Index | Old Index