NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/55663 (Support for EVFILT_USER in kqueue(2))



The following reply was made to PR kern/55663; it has been noted by GNATS.

From: Ruslan Nikolaev <nruslan_devel%yahoo.com@localhost>
To: "jnemeth%netbsd.org@localhost" <jnemeth%netbsd.org@localhost>, 
	"kern-bug-people%netbsd.org@localhost" <kern-bug-people%netbsd.org@localhost>, 
	"netbsd-bugs%netbsd.org@localhost" <netbsd-bugs%netbsd.org@localhost>, 
	"gnats-admin%netbsd.org@localhost" <gnats-admin%netbsd.org@localhost>, 
	"gnats-bugs%netbsd.org@localhost" <gnats-bugs%netbsd.org@localhost>
Cc: 
Subject: Re: kern/55663 (Support for EVFILT_USER in kqueue(2))
Date: Tue, 20 Oct 2020 20:31:34 +0000 (UTC)

 I greatly apologize for the delay. Recently, I had so many things to do...
 Please keep in mind that my understanding may be incomplete since I have no=
 t really introduced this feature, I just ported it from FreeBSD/OpenBSD. In=
  fact, I have far more experience with epoll() rather than kqueue(). So, le=
 t me start the discussion with the motivation first, and then we can go to =
 specific technical details (in a separate email which I will try to prepare=
  next as needed).
 
 1. Why is it needed?
 
 Quite a few applications use it. To be specific, please consider Nginx. Alt=
 hough, it *does* compile under NetBSD, several critical features are missin=
 g without EVFILT_USER.
 
 Take a look at https://nginx.googlesource.com/nginx/+/refs/heads/master/src=
 /core/ngx_thread_pool.c:
 
 static ngx_int_t
 ngx_thread_pool_init_worker(ngx_cycle_t *cycle)
 {
 ...
 =C2=A0=C2=A0=C2=A0 if (ngx_notify_init =3D=3D NULL || ngx_notify =3D=3D NUL=
 L) {
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ngx_log_error(NGX_LOG_ALERT, cyc=
 le->log, 0,
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0 "the configured event method cannot be used with thread pools");
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return NGX_ERROR;
 =C2=A0=C2=A0=C2=A0 }
 
 ...
 
 
 Note that if ngx_notify is *NOT* initialized to some function, Nginx will n=
 ot support the thread pool mode, which is arguably a very important Nginx f=
 eature that boosts performance greatly!
 
 So, where is this function initialized? For kqueue, Nginx provides https://=
 nginx.googlesource.com/nginx/+/refs/heads/master/src/event/modules/ngx_kque=
 ue_module.c
 
 Note these lines:
 static ngx_event_module_t=C2=A0 ngx_kqueue_module_ctx =3D {
 ...
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NULL,=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /*=
  delete an connection */
 #ifdef EVFILT_USER
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ngx_kqueue_notify_init,=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /* init a notify =
 */
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ngx_kqueue_notify,=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0 /* trigger a notify */
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NULL,=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /*=
  close a notify */
 #else
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NULL,=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /*=
  init a notify */
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NULL,=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /*=
  trigger a notify */
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NULL,=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 /*=
  close a notify */
 #endif
 ...
 
 So, in other words, Nginx compiles and runs but lacks the thread pool suppo=
 rt, which is an important feature. I am not saying that they could not have=
  implemented it differently, but quite a few applications just assume you h=
 ave EVFILT_USER and do not provide any good fallback.
 If we can just implement EVFILT_USER as in FreeBSD (regardless of its merit=
 s), that would take care of those cases completely.
 
 As another example, see the bug report for mySQL: http://gnats.netbsd.org/5=
 4627
 Without EVFILT_USER, it will even have uninitialized data
 
 2. Regarding the EVFILT_USER itself, the FreeBSD man page says the followin=
 g:
 
 EVFILT_USER=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Establishes a user event identifi=
 ed by ident which is
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 not associated with any kernel mechanism but is trig-
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 gered by user level code.=C2=A0 The lower 24 bits of =
 the
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 fflags may be used for user defined flags and manipu-
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 lated using the following:
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFNOP=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0 Ignore the input fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFAND=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0 Bitwise AND fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFOR=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0 Bitwise OR fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFCOPY=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0 Copy fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFCTRLMASK=C2=A0=C2=A0=C2=A0=C2=A0 Control mask =
 for fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_FFLAGSMASK=C2=A0=C2=A0=C2=A0=C2=A0 User defined =
 flag mask for
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fflags.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 A user event is triggered for output with the follow-
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 ing:
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 NOTE_TRIGGER=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0 Cause the event to be triggered.
 
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 On return, fflags contains the users defined flags in
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0=C2=A0 the lower 24 bits.
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
 =A0=C2=A0=C2=A0 =C2=A0
 Please let me know if EVFILT_USER may sound interesting for NetBSD. If so, =
 I can try to recollect technical details (it has been really a while). But =
 for the most part it was based on OpenBSD's patch (with some adaptations fo=
 r NetBSD): https://www.mail-archive.com/tech%openbsd.org@localhost/msg42433.html
 
 
 Thanks,
 Ruslan
 



Home | Main Index | Thread Index | Old Index