Date: Fri, 26 Jun 2009 17:36:43 +0400
From: Stanislav Sedov <stas@FreeBSD.org>
To: Thomas Backman <serenity@exscape.org>
Cc: freebsd-current@freebsd.org, Artem Belevich <fbsdlist@src.cx>
Subject: Re: ZFS : panic("sleeping thread")
Message-ID: <20090626173643.b4950bc8.stas@FreeBSD.org>
In-Reply-To: <AEA6B136-7464-4A8A-A683-69D651B4625B@exscape.org>
References: <ed91d4a80905271058mbc1fc68g184def5097080cbc@mail.gmail.com> <993B7B5B-1B6B-48A5-8425-6A1D071335A9@exscape.org> <20090626164639.71a34f62.stas@FreeBSD.org> <AEA6B136-7464-4A8A-A683-69D651B4625B@exscape.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Fri, 26 Jun 2009 14:59:18 +0200
Thomas Backman <serenity@exscape.org> mentioned:
> I could (and might, too), but unfortunately (well, I guess...) I
> haven't been able to reproduce this, despite writing a script to
> really stress test it. It's either pretty darn random, or I was simply
> wrong about the rollback being involved. I've only gotten it once
> since I started using -CURRENT in early May(?) so I don't think I
> could tell whether the patch helps or not. :(
>
I think this could be triggered by tailing the file on ZFS that is being
writed with reasonable disk activity.
BTW, file I sent previously was incorrect. I attached the rigth one.
Thanks!
--
Stanislav Sedov
ST4096-RIPE
[-- Attachment #2 --]
diff -r b446ba89e2b9 src/sys/kern/kern_event.c
--- a/src/sys/kern/kern_event.c Tue Jun 23 17:00:09 2009 +0400
+++ b/src/sys/kern/kern_event.c Fri Jun 26 17:32:43 2009 +0400
@@ -1608,17 +1608,18 @@
* first.
*/
void
-knote(struct knlist *list, long hint, int islocked)
+knote(struct knlist *list, long hint, int lockflags)
{
struct kqueue *kq;
struct knote *kn;
+ int error;
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);
/*
@@ -1633,17 +1634,28 @@
kq = kn->kn_kq;
if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) {
KQ_LOCK(kq);
- if ((kn->kn_status & KN_INFLUX) != KN_INFLUX) {
+ if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) {
+ KQ_UNLOCK(kq);
+ } else if ((lockflags & KNF_NOKQLOCK) != 0) {
+ kn->kn_status |= KN_INFLUX;
+ KQ_UNLOCK(kq);
+ error = kn->kn_fop->f_event(kn, hint);
+ KQ_LOCK(kq);
+ kn->kn_status &= ~KN_INFLUX;
+ 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_UNLOCK(kq);
}
kq = NULL;
}
- if (!islocked)
+ if ((lockflags & KNF_LISTLOCKED) == 0)
list->kl_unlock(list->kl_lockarg);
}
diff -r b446ba89e2b9 src/sys/sys/event.h
--- a/src/sys/sys/event.h Tue Jun 23 17:00:09 2009 +0400
+++ b/src/sys/sys/event.h Fri Jun 26 17:32:43 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 b446ba89e2b9 src/sys/sys/mount.h
--- a/src/sys/sys/mount.h Tue Jun 23 17:00:09 2009 +0400
+++ b/src/sys/sys/mount.h Fri Jun 26 17:32:43 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 b446ba89e2b9 src/sys/sys/vnode.h
--- a/src/sys/sys/vnode.h Tue Jun 23 17:00:09 2009 +0400
+++ b/src/sys/sys/vnode.h Fri Jun 26 17:32:43 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)
/*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090626173643.b4950bc8.stas>
