tech-kern archive

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

dk_rawlock and vn_close



hi
I just got this panic while rebooting a server with dk(4) on raid(4):
(see comments inline)

syncing disks... done
unmounting file systems...Mutex error: mutex_destroy: assertion failed: 
!MUTEX_OWNED(mtx->mtx_owner) && !MUTEX_HAS_WAITERS(mtx)

lock address : 0x00000000c43f9268 type     :     sleep/adaptive
initialized  : 0x00000000c0352aa4
shared holds :                  0 exclusive:                  1
shares wanted:                  0 exclusive:                  0
current cpu  :                  0 last held:                  0
current lwp  : 0x00000000d195bae0 last held: 0x00000000d195bae0
last locked  : 0x00000000c02fdd66 unlocked : 0x00000000c02fddb6
owner field  : 0x00000000d195bae0 wait/spin:                0/0

# 0x00000000c02fdd66 is mutex_enter(&sc->sc_parent->dk_rawlock) in dkclose()

Turnstile chain at 0xc071faa0.
=> No active turnstile for this lock.

panic: LOCKDEBUG
fatal breakpoint trap in supervisor mode
trap type 1 code 0 eip c03f355c cs 8 eflags 246 cr2 bbbe8218 ilevel 0
Stopped in pid 25742.1 (halt) at        netbsd:breakpoint+0x4:  popl    %ebp
db{0}> tr
breakpoint(c0645b22,ce8fb928,c06a38c0,c035c8bf,0,1,0,0,ce8fb928,8) at 
netbsd:breakpoint+0x4
panic(c0645b24,c0641886,c0516bba,c0641704,c0641704,1516bba,0,c43f9268,c43f9210,1)
 at netbsd:panic+0x1b0
lockdebug_abort1(c0641704,1,c0516bba,c0641704,0,c43f9210,ce8fb98c,c032a9ce,c43f9268,c0516bba)
 at netbsd:lockdebug_abort1+0xbb
mutex_abort(c43f9268,c0516bba,c0641704,c0352948,c43f9274,c43f9238,ce8fb9ac,c0186927,c43f9268,c0698f00)
 at netbsd:mutex_abort+0x2e
mutex_destroy(c43f9268,c0698f00,0,c050cd40,1223,d195bae0,ce8fb9dc,c0351394,1223,3)
 at netbsd:mutex_destroy+0x7e
raidclose(1223,3,6000,d195bae0,6000,3,6,3,cfe6ac40,0) at netbsd:raidclose+0x137
#this is the call to disk_detach() or disk_destroy() in raidclose()

dev_close(1223,3,6000,d195bae0,0,0,ce8fba2c,1223,6000,0) at 
netbsd:bdev_close+0x84
spec_close(ce8fba38,20002,ce8fba4c,c03a8808,cfe6ac40,c05181c0,cfe6ac40,3,ffffffff,3)
 at netbsd:spec_close+0x24b
VOP_CLOSE(cfe6ac40,3,ffffffff,c4433c00,c4433c00,0,ce8fba9c,c02fde00,cfe6ac40,3) 
at netbsd:VOP_CLOSE+0x6c
vn_close(cfe6ac40,3,ffffffff,c02aaa6f,0,d195bae0,0,c0516240,a800,d195bae0) at 
netbsd:vn_close+0x4e
dkclose(a800,3,6000,d195bae0,6000,3,6,3,cf7fd8a4,0) at netbsd:dkclose+0xe0
bdev_close(a800,3,6000,d195bae0,0,0,ce8fbb1c,a800,6000,0) at 
netbsd:bdev_close+0x84
spec_close(ce8fbb28,20002,ce8fbb3c,c03a8808,cf7fd8a4,c05181c0,cf7fd8a4,3,ffffffff,c5634000)
 at netbsd:spec_close+0x24b
VOP_CLOSE(cf7fd8a4,3,ffffffff,0,0,c55bf3cc,0,cfead000,cfead000,cfead024) at 
netbsd:VOP_CLOSE+0x6c
ffs_unmount(cfead000,80000,0,0,0,0,ce8fbbbc,c03a66ef,cfead000,80000) at 
netbsd:ffs_unmount+0x132
VFS_UNMOUNT(cfead000,80000,d020a300,0,1100,c039421a,1,cfead000,cfeac000,d195bae0)
 at netbsd:VFS_UNMOUNT+0x26
dounmount(cfead000,80000,d195bae0,0,ce8fbbf8,0,0,d195bae0,ce8fbd00,c069f500) at 
netbsd:dounmount+0x13f
vfs_unmountall(d195bae0,0,0,c03135fd,cd586630,8,ce8fbc2c,c03f9d1b,0,d195bae0) 
at netbsd:vfs_unmountall+0x63
vfs_shutdown(0,d195bae0,0,0,ce8fbd00,0,ce8fbcdc,c034b434,8,0) at 
netbsd:vfs_shutdown+0x85
cpu_reboot(8,0,0,0,0,0,ce8fbc9c,c03e5332,23,ce8fbcc0) at netbsd:cpu_reboot+0x13b
sys_reboot(d195bae0,ce8fbd00,ce8fbd28,ce8fbd40,c03e5332,d00e8b9c,1,8,0,bfbfeee8)
 at netbsd:sys_reboot+0x74
syscall(ce8fbd48,b3,ab,1f,1f,1,d,bfbfeee8,0,256) at netbsd:syscall+0xc8


I'm not sure how it's supposed to work, but I guess that dkclose()
should release the parent's lock before calling vn_close() on the
parent ? Would the attached patch be correct ?

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: dk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dk.c,v
retrieving revision 1.42.6.2
diff -u -r1.42.6.2 dk.c
--- dk.c        30 Jan 2010 19:00:46 -0000      1.42.6.2
+++ dk.c        27 Jul 2010 22:16:22 -0000
@@ -476,17 +476,18 @@
 
        /* Clean up the parent. */
        mutex_enter(&sc->sc_dk.dk_openlock);
-       mutex_enter(&sc->sc_parent->dk_rawlock);
        if (sc->sc_dk.dk_openmask) {
+               mutex_enter(&sc->sc_parent->dk_rawlock);
                if (sc->sc_parent->dk_rawopens-- == 1) {
                        KASSERT(sc->sc_parent->dk_rawvp != NULL);
+                       mutex_exit(&sc->sc_parent->dk_rawlock);
                        (void) vn_close(sc->sc_parent->dk_rawvp, FREAD | FWRITE,
                            NOCRED);
                        sc->sc_parent->dk_rawvp = NULL;
-               }
+               } else
+                       mutex_exit(&sc->sc_parent->dk_rawlock);
                sc->sc_dk.dk_openmask = 0;
        }
-       mutex_exit(&sc->sc_parent->dk_rawlock);
        mutex_exit(&sc->sc_dk.dk_openlock);
 
        /* Announce our departure. */
@@ -968,7 +969,6 @@
        KASSERT(sc->sc_dk.dk_openmask != 0);
 
        mutex_enter(&sc->sc_dk.dk_openlock);
-       mutex_enter(&sc->sc_parent->dk_rawlock);
 
        if (fmt == S_IFCHR)
                sc->sc_dk.dk_copenmask &= ~1;
@@ -978,15 +978,17 @@
            sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
 
        if (sc->sc_dk.dk_openmask == 0) {
+               mutex_enter(&sc->sc_parent->dk_rawlock);
                if (sc->sc_parent->dk_rawopens-- == 1) {
                        KASSERT(sc->sc_parent->dk_rawvp != NULL);
+                       mutex_exit(&sc->sc_parent->dk_rawlock);
                        error = vn_close(sc->sc_parent->dk_rawvp,
                            FREAD | FWRITE, NOCRED);
                        sc->sc_parent->dk_rawvp = NULL;
-               }
+               } else
+                       mutex_exit(&sc->sc_parent->dk_rawlock);
        }
 
-       mutex_exit(&sc->sc_parent->dk_rawlock);
        mutex_exit(&sc->sc_dk.dk_openlock);
 
        return (error);


Home | Main Index | Thread Index | Old Index