Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Apr 2004 20:38:58 -0400
From:      "Brian F. Feldman" <green@freebsd.org>
To:        Robert Watson <rwatson@freebsd.org>, Seigo Tanimura <tanimura@tanimura.dyndns.org>, Pawel Jakub Dawidek <pjd@freebsd.org>, freebsd-arch@freebsd.org
Subject:    Re: locking down kqueue (was some other completely unrelated topic) 
Message-ID:  <200404160038.i3G0cwni020043@green.homeunix.org>
In-Reply-To: Message from John-Mark Gurney <gurney_j@efn.org>  of "Thu, 15 Apr 2004 15:39:20 PDT." <20040415223920.GT567@funkthat.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
John-Mark Gurney <gurney_j@efn.org> wrote:
> Brian F. Feldman wrote this message on Thu, Apr 15, 2004 at 16:36 -0400:
> > Nothing is currently designed to work with anything even remotely not 
> > looking like spl(), so we have to either flatten it out (using workqueues) 
> > or change semantics so that when KNOTE() is called it acts like the closure 
> > that we pretend it is.  Of course, the easy way to do this is with a worker 
> > queue/condvar/mutex/thread.  What other ways do we have available to turn
> > KNOTE() into a closure, bearing in mind that the entire point of the 
> > mechanism is that there is no memory allocation at the time of event 
> > generation -- only when events are defined (by the user or recursively by 
> > other events).
> 
> The proc case should be treated special as it is an [ab]use of the kevent
> system with following children...  I'm looking at it more..

It's stupid, hopeless, and an abomination.  I'm removing it.  The only way 
it can possibly work to report failure to the "parent" knote at the same 
time is if KNOTE() and kqueue_register() have the exact same locks -- not 
gonna happen if there are ANY non-global kqueue locks at all!  I'm going to 
replace it with what it SHOULD have been: implemented, at the end of 
kevent() after kqueue_scan() as a shortcut that doesn't leave the kernel but 
does not do any of the horrible, evil, SINGLE special case that makes me 
have to try to do this to accomodate it:

                if (kn->kn_fop->f_event(kn, hint) ||
                    kn->kn_kq->kq_state & KQ_UPCALL) {
                        int enqueued = 0, upcall;

                        upcall = kn->kn_kq->kq_state & KQ_UPCALL;
                        KNOTE_ACTIVATE(kn, enqueued);
                        if (upcall || enqueued) {
                                struct kevent upkev;
                                long uperrnote;

                                if (upcall) {
                                        upkev = kn->kn_kq->kq_upcall;
                                        uperrnote = kn->kn_kq->kq_uperror;
                                        kn->kn_kq->kq_state &= ~KQ_UPCALL;
                                }
                                mtx_unlock(&knote_mtx);
                                mtx_unlock(&kn->kn_kq->kq_mtx);
                                mtx_unlock(&klist_mtx);
                                if (upcall) {
                                        if (kqueue_register(kn->kn_kq,
                                            &upkev, curthread) != 0) {
                                        }
                                }


-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green@FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404160038.i3G0cwni020043>