Re: ZFS : panic("sleeping thread")

From: Stanislav Sedov <stas_at_FreeBSD.org>
Date: Fri, 26 Jun 2009 16:46:39 +0400
On Thu, 18 Jun 2009 13:49:46 +0200
Thomas Backman <serenity_at_exscape.org> 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
_at__at_ -1608,7 +1608,7 _at__at_
  * first.
  */
 void
-knote(struct knlist *list, long hint, int islocked)
+knote(struct knlist *list, long hint, int lockflags)
 {
 	struct kqueue *kq;
 	struct knote *kn;
_at__at_ -1617,9 +1617,9 _at__at_
 	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); 
 
 	/*
_at__at_ -1636,7 +1636,7 _at__at_
 			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);
_at__at_ -1645,11 +1645,17 _at__at_
 				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
_at__at_ -135,8 +135,14 _at__at_
 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)
_at__at_ -204,7 +210,7 _at__at_
 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
_at__at_ -633,7 +633,7 _at__at_
 #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
_at__at_ -222,9 +222,10 _at__at_
 #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
Received on Fri Jun 26 2009 - 10:46:41 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:50 UTC