freebsd-current

[Prev] Thread [Next]  |  [Prev] Date [Next]

Re: ZFS : panic("sleeping thread") Stanislav Sedov Fri Jun 26 06:00:43 2009

On Thu, 18 Jun 2009 13:49:46 +0200
Thomas Backman <[EMAIL PROTECTED]> mentioned:

> Anyone have any updates on this? I just got a "sleeping thread" panic  
> in ZFS after doing a zfs rollback. Unfortunately, "panic" in the  
> debugger resulted in "dump device too small" (despite being RAM-sized)  
> so I don't have a BT... However the BT I got in the debugger was *not*  
> the same as yours. There was no _sx_xlock in it, but that's pretty  
> much all I know about it. :(
> 

Hi, Thomas!

Can you, please, try with the following patch? Thanks!

---------------------------------------------------------------------------

diff -r a707b4dd87cf src/sys/kern/kern_event.c
--- a/src/sys/kern/kern_event.c Fri Jun 26 13:49:09 2009 +0400
+++ b/src/sys/kern/kern_event.c Fri Jun 26 16:45:15 2009 +0400
@@ -1608,7 +1608,7 @@
  * first.
  */
 void
-knote(struct knlist *list, long hint, int islocked)
+knote(struct knlist *list, long hint, int lockflags)
 {
        struct kqueue *kq;
        struct knote *kn;
@@ -1617,9 +1617,9 @@
        if (list == NULL)
                return;
 
-       KNL_ASSERT_LOCK(list, islocked);
+       KNL_ASSERT_LOCK(list, lockflags & KNF_LISTLOCKED);
 
-       if (!islocked) 
+       if ((lockflags & KNF_LISTLOCKED) == 0)
                list->kl_lock(list->kl_lockarg); 
 
        /*
@@ -1636,7 +1636,7 @@
                        KQ_LOCK(kq);
                        if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
                                KQ_UNLOCK(kq);
-                       } else {
+                       } else if ((lockflags & KNF_NOKQLOCK) != 0) {
                                kn->kn_status |= KN_INFLUX;
                                KQ_UNLOCK(kq);
                                error = kn->kn_fop->f_event(kn, hint);
@@ -1645,11 +1645,17 @@
                                if (error)
                                        KNOTE_ACTIVATE(kn, 1);
                                KQ_UNLOCK_FLUX(kq);
+                       } else {
+                               kn->kn_status |= KN_HASKQLOCK;
+                               if (kn->kn_fop->f_event(kn, hint))
+                                       KNOTE_ACTIVATE(kn, 1);
+                               kn->kn_status &= ~KN_HASKQLOCK;
+                               KQ_UNLOCK(kq);
                        }
                }
                kq = NULL;
        }
-       if (!islocked)
+       if ((lockflags & KNF_LISTLOCKED) == 0)
                list->kl_unlock(list->kl_lockarg); 
 }
 
diff -r a707b4dd87cf src/sys/sys/event.h
--- a/src/sys/sys/event.h       Fri Jun 26 13:49:09 2009 +0400
+++ b/src/sys/sys/event.h       Fri Jun 26 16:45:15 2009 +0400
@@ -135,8 +135,14 @@
 MALLOC_DECLARE(M_KQUEUE);
 #endif
 
-#define KNOTE(list, hist, lock)                knote(list, hist, lock)
-#define KNOTE_LOCKED(list, hint)       knote(list, hint, 1)
+/*
+ * Flags for knote call
+ */
+#define        KNF_LISTLOCKED  0x0001                  /* knlist is locked */
+#define        KNF_NOKQLOCK    0x0002                  /* do not keep KQ_LOCK 
*/
+
+#define KNOTE(list, hist, flags)       knote(list, hist, flags)
+#define KNOTE_LOCKED(list, hint)       knote(list, hint, KNF_LISTLOCKED)
 #define KNOTE_UNLOCKED(list, hint)     knote(list, hint, 0)
 
 #define        KNLIST_EMPTY(list)              SLIST_EMPTY(&(list)->kl_list)
@@ -204,7 +210,7 @@
 struct proc;
 struct knlist;
 
-extern void    knote(struct knlist *list, long hint, int islocked);
+extern void    knote(struct knlist *list, long hint, int lockflags);
 extern void    knote_fork(struct knlist *list, int pid);
 extern void    knlist_add(struct knlist *knl, struct knote *kn, int islocked);
 extern void    knlist_remove(struct knlist *knl, struct knote *kn, int 
islocked);
diff -r a707b4dd87cf src/sys/sys/mount.h
--- a/src/sys/sys/mount.h       Fri Jun 26 13:49:09 2009 +0400
+++ b/src/sys/sys/mount.h       Fri Jun 26 16:45:15 2009 +0400
@@ -633,7 +633,7 @@
 #define VFS_KNOTE_LOCKED(vp, hint) do                                  \
 {                                                                      \
        if (((vp)->v_vflag & VV_NOKNOTE) == 0)                          \
-               VN_KNOTE((vp), (hint), 1);                              \
+               VN_KNOTE((vp), (hint), KNF_LISTLOCKED);                 \
 } while (0)
 
 #define VFS_KNOTE_UNLOCKED(vp, hint) do                                        
\
diff -r a707b4dd87cf src/sys/sys/vnode.h
--- a/src/sys/sys/vnode.h       Fri Jun 26 13:49:09 2009 +0400
+++ b/src/sys/sys/vnode.h       Fri Jun 26 16:45:15 2009 +0400
@@ -222,9 +222,10 @@
 #define VN_KNOTE(vp, b, a)                                     \
        do {                                                    \
                if (!VN_KNLIST_EMPTY(vp))                       \
-                       KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b), (a)); \
+                       KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b), \
+                           (a) | KNF_NOKQLOCK);                \
        } while (0)
-#define        VN_KNOTE_LOCKED(vp, b)          VN_KNOTE(vp, b, 1)
+#define        VN_KNOTE_LOCKED(vp, b)          VN_KNOTE(vp, b, KNF_LISTLOCKED)
 #define        VN_KNOTE_UNLOCKED(vp, b)        VN_KNOTE(vp, b, 0)
 
 /*

---------------------------------------------------------------------------------

-- 
Stanislav Sedov
ST4096-RIPE
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"