This is the Kernel Dev Room, just a reminder from time to time.
Ready for our next talk, Renzo and Luca are going to talk about LibVPol, create synthetic
events for poll select and friends.
Hello, I'm Luca Bassi, I'm a student from University of Bologna and today with Professor
Renzo Davoli from University of Bologna we will present the LibVPol library.
Many programs use the poll and select system calls to wait for events triggered by file
descriptor of events.
So you can write a library to be like a natural stack or device and you can implement your
drop-in replacement function of a system call and use some dynamic library magic to
rename the verb t's system call request to their virtual implementation.
t seems all good but there is a big caveat that this approach doesn't allow to mix the
normal file descriptor using the real file descriptor with the library one to use in the
same select and poll and similar system calls.
So Professor Renzo Davoli developed the LibVPol library that is a library that permits to
define file descriptor whose IO events can be generated at user level.
This permits to generate synthetic events for the standard Linux poll select, poll select,
etc. system calls and with this library it's possible to mix the real file descriptor with
the ones provided by libraries as a parameter of the poll select, etc. system calls.
The API of LibVPol is very simple, it's three methods.
Vupol create to create Vupol file descriptor, Vupol CTL to change the set of pending events
reported by the Vupol file descriptor and Vupol close to close the file descriptor.
To work with the LibVPol library needs kernel support for a complete implementation of this
feature.
There is two possible support to LibVPol, a kernel patch extending the eventfd system
call and a kernel model that implement a virtual device, exponent dev slash vupol.
The library also provides a fallback implementation but is feature limited and for full support
they need a patched kernel or the kernel model implementing the virtual devices.
So we had a problem, the problem was to mix a real file descriptor and a file descriptor
code file descriptor created by library implementing stacks, implementing virtual devices.
We decided to do the nice API for the library but unfortunately it is impossible to have
this implementation complete without having a kernel support.
The first idea was to extend the feature of eventfd.
In fact if you try to code a library like that and you look around the system code and
you step into the manual of eventfd the title set create a file descriptor for event notification.
That's it.
But unfortunately it is not providing ways to create, to set arbitrarily, pull in, pull
out, pull out.
That's just some way to synchronize processes using counters.
So it was chosen because of the finish of the feature.
The kernel patch adds to eventfd a third semantics because eventfd has already two semantics,
the normal semantics and the semaphore semantics that is able to implement a service like the
standard semaphores up, down, and down in the kernel.
We had a third way, a third way, a third semantics, a loophole.
There should be another way to implement it.
So following the standard naming of system codes we have a loophole create, loophole,
control and so on.
It would be possible to create, to propose the adding of two different system codes,
loophole fd create and loophole fd control.
But the idea is that we feel that eventfd is the most clear and straightforward way
to implement this feature.
So out of these extension words we can create the eventfd with the new flag saying we want
the semantics of the pole.
Then following the semantics of eventfd we have read and write, read, return the current
stage of rendering.
We use the 64-bit buffer of eventfd as a bitmap of a set.
Write is used to change the set of events for the file descriptor.
For example you can add the pole in and pole pre using these system codes.
So the operation flag add mod del is specified by setting the mod request bits.
We had a problem, we had a proposal of solution but we needed to have it working quite fast,
quite good.
We needed it for our process.
So we proposed, we developed another way to have the same service to implement this service
as a virtual device.
So we have implemented it.
If you download, if you install the LibrePole package from Debian Ubuntu you get this module
and this module is installed using decay MS.
So you can have the service by adding the package after the kernel module.
Here the implementation, so we use the LibrePole, the user-level library tries one after the
other.
If there is eventfd patch it uses eventfd patch.
Otherwise if there is the LibrePole device it uses the Ubipole device.
At the last resort it uses an emulation.
For the device it is possible to open the device and the generation of events is performed
by IO control like it's usual for devices.
Examples.
We work in Internet of Threats.
The idea of giving each process the ability to have their own stack inside the process
itself so that this process can be a network node by itself.
People Peacock's Net is a library which implements a user-level network implementation.
Peacock's Net is based off Peacot TCP.
There is Peacot TCP plus a glue layer that creates the abstraction of a library-based
network stack.
We have added LibrePole, we use LibrePole in Peacock's Net so that you can write programs
like a terminal emulator which has a main event loop waiting for standard input to send
data on the socket and to wait for the socket to send to write on the terminal output.
So it wouldn't be possible using other stuff or tricky solution based on unisockets or
bytes to synchronize but it would be just on purpose for this.
Instead of using LibrePole and extension of the kernel or the device gives a general
purpose solution so that we are working to port even LWP as a user-level stack implementation
so that we can mix and create applications that can use different stack implementations.
Maybe we can create gateways between network streams coming from different network implementations.
So to summarize we had a problem to have a file descriptor, real file descriptor and
virtual file descriptor working together in PulseSelector, E-Pole and whatever POLU you
can invent in the future.
Providing POLIN POLAR POPLE and all the POLU events you can create in the future.
We have proposed a library giving a nice and easily straightforward interface and we have
implemented the proposed implementation and implemented a proposal to be accepted in the kernel.
A device driver and an extension to say existing system code. If you want obviously all the
source code is publicly available on GitHub.
Okay, I think that's all of the questions.
I wasn't sure if there were any slides but does this need each individual event loop library to add support for this?
Or can you use this with existing event loop libraries like for example SystemD has an event loop library
but we need to add explicit support to be able to use V-Pole file descriptors?
Or can you plug this in without needing to modify existing event loop libraries to use it?
So you create a V-Pole file descriptor and you want to use it with an event loop.
Does the event loop need to do anything special?
No, absolutely. That's the point.
Instead of creating something special to use the POL selector, you use this method.
You use the standard, clean syntax of the selector POL or whatever event you're waiting for.
System code you won't not use. That's the point.
So instead of creating unpublished solutions for the use of that application,
this is a general purpose solution for all applications needing to work with select POL.
Because you can add extra services to provide the same semantics, the same method to unblock,
to signal, and for this system codes.
Maybe one more question.
Please.
Is there any...
There's also the new interface in the Linux kernel as IOU ring.
Is there anything needed to make this work with IOU ring as well?
Or I'm not sure if you've looked at that.
I'm not sure.
So I'll check and please send the mail or send feedback.
I probably missed this, but why didn't you, for example, consider proposing a new E-POL extension?
Like a new E-POL system call, for example?
It's not an extension for E-POL.
I use the standard E-POL like POL or the other.
It's a way to signal to POL or E-POL that's never occurred.
A common solution for this is to create, for example, a pipe and waiting for a red event on a pipe.
And you know that if you receive a red event on a pipe, it means that something has happened.
Instead of having this, you can use, you can write a flight description behaving like an event driver,
so that you can port your code as is.
Because if the driver would have to send POL and VAL,
you can synthesize POL and VAL and your E-POL or POL can work in the standard way.
With that extra code, it's just to simulate something because it's not possible to do what LibbyPOL does.
Another question.
As I understand it correctly, it simulates somehow the source of events somehow.
But how does it scale?
Because you use just one system call in the case of the I.O. control.
It's just a system call or using write.
It's just another system call somehow.
So it doesn't probably not scale, right?
So if you want to generate thousands of events, triggering events, it requires a system call each.
I say it does scale.
It scales as a poll of scales.
Because you can use as many fider skaters.
For each fider skater, you can have all the events you need.
In which means you think there are problems with scaling?
Yeah, I mean a poll or an E-POL or whatever scales somehow.
But the mechanism on your side to trigger this requires one system call.
So here you see another write on the slides.
Another one, the other slides.
If you saw the write, it's just a system call or using the I.O. control.
It's just another system call to trigger this.
So you have one event.
The solution with the device, you mean using the I.O. control.
Yeah, to trigger the event, probably we can do it offline later.
Here the last line.
No, no, on the previous slide.
This one, the write call.
Here, right?
You see this?
This is a system call, the write is a system call.
And if you trigger it, it requires a system call.
But each aesthetic event requires one system call, right?
No.
And if I want to simulate millions of...
No, no, you don't need the call for each event because it's a bitmap.
So you can set the bitmap of an event.
You want to be added or set or cleaned.
So with one call, you set all the events for one FD.
Obviously for different FD, you need different...
Right.
Next.
Thanks. We're out of time.
Thank you for your talk.
Thank you.
And we'll have a five minute break.
Thank you.