libev-4.31 has just been released

Marc Lehmann schmorp at schmorp.de
Thu May 6 14:05:42 CEST 2021


On Wed, May 05, 2021 at 09:54:38AM -0400, Olivier Langlois <olivier at trillion01.com> wrote:
> I tend to disagree on the future of this new API. It seems to have a
> lot of potential.

I agree it has a lot of potential, but unless the kernel people get their
act together and fix the bugs that prevent it from actually working in
real-world prorgams and libraries, its potential as event backend is niche
applications.

And as long as epoll is considerably faster, the only reason to use it for
events would be simpler app design.

> As far as I can tell, it is only code clean up and optimizations but
> without more details, I find the claims hard to believe...

That is what I see as a problem here - the order of priorities for me is
always correctness first, not optimisations, spiffy benchmarks, or cool
features. I wish this were true for the people who designed epoll/linux
aio and io_uring, but sadly, it seems not the case - we get cool features
and cool claims of performance, but basic and groundbraking bugs remain,
such as io_uring reporting read events when an fd is only writable.

> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=625434dafdd97372d15de21972be4b682709e854

I stopped being interested in new features a few months ago. I was stoked
on io_uring just as you are, but after more than a year of waiting for
critical bugfixes to make the interface usable and only getting promises
and no action, I gave up on it and plan to only check it once a year or
so. Each time I see "cool new fetaure" my only reaction is "what about
fixing the bugs so I can actually use it?".

I kept bugging the io_uring author, and I suspect he stopped listening to
this annoying person.

The reason I was stoked is that I would really like to avoid epoll, but
for this, io_uring must be able to replace it, and not just be a toy for
synthetic benchmarks like linux aio before it.

i will seriously look at io_uring again once it works. Until then, you
can use io_uring in libev if you explicitly request it and you understand
that it doesn't work as a generic event backend - similar to how you can
use kqueue (broken) on osx as a backend inside a more normal select-based
backend.

> 2. Reuse the ev_io watcher type that I extend using its data pointer
> with an agreed content (struct ev_io_uring_buffer_read_params) to

The ev_io watcher type would obviously be the wrong watcher for this, it
would have to be a new watcher. Also, for this to ever end up in libev, it
would have to have emulation for non-io-uring backends.

And we already jhave that, it is called libeio, and my plan is to add
io_uring as a backend for (some, increasing amount of) IO reqests.

This is the right way to proceed, as libeio is quite portable (i.e. most
unix + windows systems) and emulates any missing features, while it can
avoid the buggy parts of io_uring.

That way you would get correct async I/O from libeio, and correct event
handling from libev.

Anything else I consider a dead end.

> 3. ev_io_uring code is currently littered with printf. I am currently
> trying to fix an odd behavior observed from io_uring:

Is that your code or are you talking about libev? If you want to seriously
work on io_uring in libev, you should use the CVS version.

I, again, strongly think libeio is the correct place for I/O related
requests, as it is not io_uring dependent.

> https://lore.kernel.org/io-uring/8992f5f989808798ad2666b0a3ef8ae8d777b7de.camel@trillion01.com/T/#u

I am not sure what the issue exactly is. As for #2, libev should already
handle this when receiving the event - it will not queue an event for a
watcher that does not want it.

As for #3, I don't understand your description.

As for OOB data, TLS does not use it for sure. The only protocols that
ever used oob data are telnet and ftp, although these only use the
out-of-abdn API, not out-of-band data. One reason for this is that TCP
does not support out of band data, only urgent data, which has different
semantics (urgent data is in-band, for one thing).

As for bugs, the libev backend is probably super buggy, as it hasn't been
tested seriously, as most of my programs crahs instantly due to kernel bugs.
In this state, I consider it pointless to even try to work on this backend.

> low hanging performance fruit. My end goal is having an async io_uring
> openssl BIO module 100% fed by libev.

openssl is a bitch in this regard, but imho doing it as a bio backend is
the right choice as it works arund most of the iodisynchrasies in openssl.

> Yes. I am going to do that. Check this email attachement.

Thanks!

> I was a big epoll user 10 years ago and well served by it. Ive stopped
> following its development when I delegated the implementation details
> to good libraries like libev. I wasn't aware at all that epoll was now
> allowing its users to queue things.

My primary issue with epoll is that you can gete vents for clsoed file
descriptors that you can never remove from your epoll set, forcing you to
destroy and recreate it from scratch, which is a performance disaster. That
and the uneven performance you get from it.

Otherwise, it would be quite fine :)

A large part of my excitement w.r.t. io_uring stems from me hoping I could
grandfather the epoll backend in favour of io_uring in newer kernels. Even
if io_uring would be some constant factor slower on operations, in
real-world performance-sensitive scenarios its improved queueing might
sitll make it competitive to epoll, enough to forget epoll.

Unfortunately, it's like the linux aio backend - great hgopes, destroyed
by a buggy and slow implementation and the obvious nob-goal of fixing
obvious bugs in favouir of cool features.

> > All of this points ot being the right solution to use iouring for the
> > things
> > only it can do (I/O) and using epoll with a submission queue for the
> > rest.
> > 
> This is a good point. I guess that the only way to find out is to try
> out those ideas. my bet isn't only on the queuing mechanic but also the
> elimination of system calls for performing the I/O that io_uring can
> offer.

Another reason for doing it separately would be that libev might have to
destroy/recreate the backend fd, which further complicates communication
with the app - what happens on partial reads and so on?

I think the small constant overhead of embedding io_uring into another
event loop (e.g. libeio into libev) is not going to be a problem in most
performance-sensitive scenarios.

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp at schmorp.de
      -=====/_/_//_/\_,_/ /_/\_\



More information about the libev mailing list