Panic on kern_event.c
Mark Johnston
markj at freebsd.org
Tue Nov 20 06:45:06 UTC 2018
On Mon, Nov 19, 2018 at 10:26:51AM +0100, Sylvain GALLIANO wrote:
> With this latest patch, after stressing syslog-ng few minutes, it do not
> log anymore and a simple kill do not work (I have to do kill -9)
Thanks for your patience. I finally managed to reproduce the problem
and can see the bug now. Please try this patch instead.
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index d9c670e29d60..0be765a040ed 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1538,6 +1538,10 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
kn_enter_flux(kn);
error = knote_attach(kn, kq);
+ if ((kev->flags & EV_ENABLE) != 0)
+ kn->kn_status &= ~KN_DISABLED;
+ else if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
KQ_UNLOCK(kq);
if (error != 0) {
tkn = kn;
@@ -1570,6 +1574,11 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
KNOTE_ACTIVATE(kn, 1);
}
+ if ((kev->flags & EV_ENABLE) != 0)
+ kn->kn_status &= ~KN_DISABLED;
+ else if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
+
/*
* The user may change some filter values after the initial EV_ADD,
* but doing so will not reset any filter which has already been
@@ -1595,11 +1604,9 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
* kn_knlist.
*/
done_ev_add:
- if ((kev->flags & EV_ENABLE) != 0)
- kn->kn_status &= ~KN_DISABLED;
- else if ((kev->flags & EV_DISABLE) != 0)
- kn->kn_status |= KN_DISABLED;
-
+ /*
+ * KN_DISABLED will be stable while the knote is in flux.
+ */
if ((kn->kn_status & KN_DISABLED) == 0)
event = kn->kn_fop->f_event(kn, 0);
else
@@ -1861,6 +1868,8 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
}
TAILQ_REMOVE(&kq->kq_head, kn, kn_tqe);
+ KASSERT(kn == marker || (kn->kn_status & KN_QUEUED) != 0,
+ ("knote %p not queued", kn));
if ((kn->kn_status & KN_DISABLED) == KN_DISABLED) {
kn->kn_status &= ~KN_QUEUED;
kq->kq_count--;
More information about the freebsd-current
mailing list