-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider changing the vhost-user-backend API #279
Comments
@mtjhrc sorry for my late reply. I think this work will be great! I was looking to support macOS/BSD and our dependency on Linux specific stuff like epoll/eventfd is the biggest thing to be solved. Your work may simplify that.
I think it's fine, but we should help our user (vhost-device, virtiofsd, etc.) to adapt easily their code.
Sure, no objection on my side. |
I think being able to unify out-of-process and in-process device implementations alone is already worth the effort. 👍 |
I don't have a macOS machine, but this is definitely something I am keeping in mind. |
FYI I'll talk about it at FOSDEM next year: https://fosdem.org/2025/schedule/event/fosdem-2025-5100-can-qemu-and-vhost-user-devices-be-used-on-macos-and-bsd-/ I can mention your work ;-) |
FWIW: libepoll-shim can be used on BSD and macOS. |
@alyssais Thanks, I was thinking also on https://github.com/smol-rs/polling |
Background
Hi, I have been working on a
vhost-user-gpu
with @dorindabassey and we ran into some complications.I think there are some things about how
VhostUserBackend
is designed and generally the API model that are not great for the GPU device, and in general for other devices too - personally I am also familiar withvirtio-net
andvirtio-console
devices because I worked on them inlibkrun
. The goal would be to make writing new devices and mainting existing ones easier by making the API more flexible.Current API can be clunky to use in some cases:
Currently the
vhost-user-backend
handles spawning worker threads for the device, and calls thehandle_event
callback on that thread. I don't think this model is good, because it leads to some difficulties when programming.Here are the main issues:
1. Where to store the data of a worker thread
Consider you have a worker thread that wants to have some variables only available to this single thread, this is currently difficult to do. Basically you have a couple of options:
Mutex
/RwLock
- for example virtio-sound does this. I feel like this adds unnecessary complexity, and unless I am missing something, we could get rid of some of the extra locking (by using theGuestMemoryAtomic
we already have).!Send
- suchRutabaga
/virglrenderer
context in thevhost-user-gpu
, your only option is to lazy initialize the struct (putting something!Send
inside aMutex
doesn't help), and usethread_local!
or useunsafe
to work around this.2. Adding file descriptors for polling after starting the backend
vhost-user-gpu
we needed to add a file descriptor to be signaled byhandle_event
insidehandle_event
this is very akward to do. If you want to do this you firt need to pass the epoll handler created by the daemon to the device backend. Inhandle_event
you now have access to the epoll, but but you have to be careful, because you cannot use theVhostUserBackendMut
trait and the convenient lock around the whole struct, because ifhandle_event
is called while the lock is held, you would deadlock yourself whennum_queues
is called here:vhost/vhost-user-backend/src/event_loop.rs
Line 117 in 176f44a
3.
VhostUserBackend
vsVhostUserBackendMut
In general the split
VhostUserBackend
andVhostUserBackendMut
traits doesn't seem to me like a good design choice. I feel like when you specify that you want 1 worker thread and you use theVhostUserBackendMut
trait it mostly works fine (except the!Send
problem), but if you want 2 worker threads or something more complex, you have to change over toVhostUserBackend
and use manual locking. Another problem is that if you don't switch to using theVhostUserBackend
trait you would have 2 worker threads, but thehandle_event
could never run at the same time because it is behind a lock leading to a non-obvious performance bug.More flexible event handling API
My main idea is to just let the device spawn it's own worker threads and use epoll directly in them instead of having the
handle_event
callback. This would basically change the event system from "push" to "poll". I think this would be a lot more flexible, because it would allow:One of the problems with the current implementation, is that since
handle_event
is a method and a callback the type systems basically forcesself
to beSend
+Sync
, which in practise forces you to lock everything, which could be avoided.Consider having devices also be usable as in-process devices by VMMs
Since I am proposing changing the API it could be beneficial to make a bit more breaking changes and also allow consuming the devices as in-process devices. Actually we aren't that far from this, but this would of course require some more thoughs about the abstractions.
This could be useful for libkrun and other VMMs (anyone else interested?)
Questions
I can create a more detailed proposals of APIs, but first I wanted to see:
The text was updated successfully, but these errors were encountered: