virtio-devices: Pass a list of tuples for virtqueues

Instead of passing separately a list of Queues and the equivalent list
of EventFds, we consolidate these two through a tuple along with the
queue index.

The queue index can be very useful if looking for the actual index
related to the queue, no matter if other queues have been enabled or
not.

It's also convenient to have the EventFd associated with the Queue so
that we don't have to carry two lists with the same amount of items.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2022-07-20 16:45:49 +02:00
parent 423c54eafe
commit 3f62a172b2
20 changed files with 154 additions and 145 deletions

View File

@@ -292,10 +292,9 @@ impl VirtioDevice for Blk {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
queue_evts: Vec<EventFd>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
@@ -307,7 +306,6 @@ impl VirtioDevice for Blk {
let mut handler = self.vu_common.activate(
mem,
queues,
queue_evts,
interrupt_cb,
self.common.acked_features,
slave_req_handler,

View File

@@ -504,10 +504,9 @@ impl VirtioDevice for Fs {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
queue_evts: Vec<EventFd>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());
// Initialize slave communication.
@@ -547,7 +546,6 @@ impl VirtioDevice for Fs {
let mut handler = self.vu_common.activate(
mem,
queues,
queue_evts,
interrupt_cb,
self.common.acked_features,
slave_req_handler,

View File

@@ -167,8 +167,7 @@ pub struct VhostUserEpollHandler<S: VhostUserMasterReqHandler> {
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
pub kill_evt: EventFd,
pub pause_evt: EventFd,
pub queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
pub queue_evts: Vec<EventFd>,
pub queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
pub virtio_interrupt: Arc<dyn VirtioInterrupt>,
pub acked_features: u64,
pub acked_protocol_features: u64,
@@ -224,10 +223,9 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
vhost_user
.reinitialize_vhost_user(
self.mem.memory().deref(),
self.queues.iter().map(vm_virtio::clone_queue).collect(),
self.queue_evts
self.queues
.iter()
.map(|q| q.try_clone().unwrap())
.map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap()))
.collect(),
&self.virtio_interrupt,
self.acked_features,
@@ -299,8 +297,7 @@ impl VhostUserCommon {
pub fn activate<T: VhostUserMasterReqHandler>(
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
queue_evts: Vec<EventFd>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
acked_features: u64,
slave_req_handler: Option<MasterReqHandler<T>>,
@@ -324,8 +321,10 @@ impl VhostUserCommon {
.unwrap()
.setup_vhost_user(
&mem.memory(),
queues.iter().map(vm_virtio::clone_queue).collect(),
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
queues
.iter()
.map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap()))
.collect(),
&interrupt_cb,
acked_features,
&slave_req_handler,
@@ -339,7 +338,6 @@ impl VhostUserCommon {
kill_evt,
pause_evt,
queues,
queue_evts,
virtio_interrupt: interrupt_cb,
acked_features,
acked_protocol_features: self.acked_protocol_features,

View File

@@ -272,18 +272,16 @@ impl VirtioDevice for Net {
&mut self,
mem: GuestMemoryAtomic<GuestMemoryMmap>,
interrupt_cb: Arc<dyn VirtioInterrupt>,
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
mut queue_evts: Vec<EventFd>,
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
) -> ActivateResult {
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
self.common.activate(&queues, &interrupt_cb)?;
self.guest_memory = Some(mem.clone());
let num_queues = queues.len();
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 {
let ctrl_queue_index = num_queues - 1;
let mut ctrl_queue = queues.remove(ctrl_queue_index);
let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index);
let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index);
ctrl_queue.set_event_idx(event_idx);
@@ -336,7 +334,6 @@ impl VirtioDevice for Net {
let mut handler = self.vu_common.activate(
mem,
queues,
queue_evts,
interrupt_cb,
backend_acked_features,
slave_req_handler,

View File

@@ -151,8 +151,7 @@ impl VhostUserHandle {
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
&mut self,
mem: &GuestMemoryMmap,
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
queue_evts: Vec<EventFd>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
acked_features: u64,
slave_req_handler: &Option<MasterReqHandler<S>>,
@@ -171,9 +170,9 @@ impl VhostUserHandle {
// Send set_vring_num here, since it could tell backends, like SPDK,
// how many virt queues to be handled, which backend required to know
// at early stage.
for (queue_index, queue) in queues.iter().enumerate() {
for (queue_index, queue, _) in queues.iter() {
self.vu
.set_vring_num(queue_index, queue.state.size)
.set_vring_num(*queue_index, queue.state.size)
.map_err(Error::VhostUserSetVringNum)?;
}
@@ -184,7 +183,7 @@ impl VhostUserHandle {
mmap_size: 0,
mmap_offset: 0,
num_queues: queues.len() as u16,
queue_size: queues[0].state.size,
queue_size: queues[0].1.state.size,
};
let (info, fd) = self
.vu
@@ -202,7 +201,7 @@ impl VhostUserHandle {
let num_queues = queues.len() as usize;
let mut vrings_info = Vec::new();
for (queue_index, queue) in queues.into_iter().enumerate() {
for (queue_index, queue, queue_evt) in queues.iter() {
let actual_size: usize = queue.state.size.try_into().unwrap();
let config_data = VringConfigData {
@@ -240,11 +239,11 @@ impl VhostUserHandle {
});
self.vu
.set_vring_addr(queue_index, &config_data)
.set_vring_addr(*queue_index, &config_data)
.map_err(Error::VhostUserSetVringAddr)?;
self.vu
.set_vring_base(
queue_index,
*queue_index,
queue
.avail_idx(Ordering::Acquire)
.map_err(Error::GetAvailableIndex)?
@@ -253,15 +252,15 @@ impl VhostUserHandle {
.map_err(Error::VhostUserSetVringBase)?;
if let Some(eventfd) =
virtio_interrupt.notifier(VirtioInterruptType::Queue(queue_index as u16))
virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16))
{
self.vu
.set_vring_call(queue_index, &eventfd)
.set_vring_call(*queue_index, &eventfd)
.map_err(Error::VhostUserSetVringCall)?;
}
self.vu
.set_vring_kick(queue_index, &queue_evts[queue_index])
.set_vring_kick(*queue_index, queue_evt)
.map_err(Error::VhostUserSetVringKick)?;
}
@@ -326,8 +325,7 @@ impl VhostUserHandle {
pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
&mut self,
mem: &GuestMemoryMmap,
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
queue_evts: Vec<EventFd>,
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
acked_features: u64,
acked_protocol_features: u64,
@@ -339,7 +337,6 @@ impl VhostUserHandle {
self.setup_vhost_user(
mem,
queues,
queue_evts,
virtio_interrupt,
acked_features,
slave_req_handler,