Panic on kern_event.c
Sylvain GALLIANO
sg at efficientip.com
Tue Nov 20 10:56:10 UTC 2018
No issue using patched kernel on 2 servers (under stress test since +2
hours), Thanks !
Le mar. 20 nov. 2018 à 07:45, Mark Johnston <markj at freebsd.org> a écrit :
> 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