mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 02:55:45 +00:00
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:
parent
423c54eafe
commit
3f62a172b2
@ -84,9 +84,8 @@ fuzz_target!(|bytes| {
|
|||||||
q.state.ready = true;
|
q.state.ready = true;
|
||||||
q.state.size = QUEUE_SIZE / 2;
|
q.state.size = QUEUE_SIZE / 2;
|
||||||
|
|
||||||
let queue_evts: Vec<EventFd> = vec![EventFd::new(0).unwrap()];
|
let evt = EventFd::new(0).unwrap();
|
||||||
let queue_fd = queue_evts[0].as_raw_fd();
|
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(evt.as_raw_fd())) };
|
||||||
let queue_evt = unsafe { EventFd::from_raw_fd(libc::dup(queue_fd)) };
|
|
||||||
|
|
||||||
let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
|
let shm = memfd_create(&ffi::CString::new("fuzz").unwrap(), 0).unwrap();
|
||||||
let disk_file: File = unsafe { File::from_raw_fd(shm) };
|
let disk_file: File = unsafe { File::from_raw_fd(shm) };
|
||||||
@ -110,8 +109,7 @@ fuzz_target!(|bytes| {
|
|||||||
.activate(
|
.activate(
|
||||||
guest_memory,
|
guest_memory,
|
||||||
Arc::new(NoopVirtioInterrupt {}),
|
Arc::new(NoopVirtioInterrupt {}),
|
||||||
vec![q],
|
vec![(0, q, evt)],
|
||||||
queue_evts,
|
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
@ -542,17 +542,23 @@ impl VirtioDevice for Balloon {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
let inflate_queue_evt = queue_evts.remove(0);
|
let mut virtqueues = Vec::new();
|
||||||
let deflate_queue_evt = queue_evts.remove(0);
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
virtqueues.push(queue);
|
||||||
|
let inflate_queue_evt = queue_evt;
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
virtqueues.push(queue);
|
||||||
|
let deflate_queue_evt = queue_evt;
|
||||||
let reporting_queue_evt =
|
let reporting_queue_evt =
|
||||||
if self.common.feature_acked(VIRTIO_BALLOON_F_REPORTING) && !queue_evts.is_empty() {
|
if self.common.feature_acked(VIRTIO_BALLOON_F_REPORTING) && !queues.is_empty() {
|
||||||
Some(queue_evts.remove(0))
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
virtqueues.push(queue);
|
||||||
|
Some(queue_evt)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -563,7 +569,7 @@ impl VirtioDevice for Balloon {
|
|||||||
error!("failed to clone resize EventFd: {:?}", e);
|
error!("failed to clone resize EventFd: {:?}", e);
|
||||||
ActivateError::BadActivate
|
ActivateError::BadActivate
|
||||||
})?,
|
})?,
|
||||||
queues,
|
queues: virtqueues,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
inflate_queue_evt,
|
inflate_queue_evt,
|
||||||
deflate_queue_evt,
|
deflate_queue_evt,
|
||||||
|
@ -587,18 +587,16 @@ impl VirtioDevice for Block {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
|
|
||||||
let disk_image_id = build_disk_image_id(&self.disk_path);
|
let disk_image_id = build_disk_image_id(&self.disk_path);
|
||||||
self.update_writeback();
|
self.update_writeback();
|
||||||
|
|
||||||
let mut epoll_threads = Vec::new();
|
let mut epoll_threads = Vec::new();
|
||||||
for i in 0..queues.len() {
|
for i in 0..queues.len() {
|
||||||
let queue_evt = queue_evts.remove(0);
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
let queue = queues.remove(0);
|
|
||||||
let queue_size = queue.state.size;
|
let queue_size = queue.state.size;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
|
@ -490,10 +490,9 @@ impl VirtioDevice for Console {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
self.resizer
|
self.resizer
|
||||||
.acked_features
|
.acked_features
|
||||||
.store(self.common.acked_features, Ordering::Relaxed);
|
.store(self.common.acked_features, Ordering::Relaxed);
|
||||||
@ -507,13 +506,21 @@ impl VirtioDevice for Console {
|
|||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
let input_evt = EventFd::new(EFD_NONBLOCK).unwrap();
|
let input_evt = EventFd::new(EFD_NONBLOCK).unwrap();
|
||||||
|
|
||||||
|
let mut virtqueues = Vec::new();
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
virtqueues.push(queue);
|
||||||
|
let input_queue_evt = queue_evt;
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
virtqueues.push(queue);
|
||||||
|
let output_queue_evt = queue_evt;
|
||||||
|
|
||||||
let mut handler = ConsoleEpollHandler {
|
let mut handler = ConsoleEpollHandler {
|
||||||
queues,
|
queues: virtqueues,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
in_buffer: self.in_buffer.clone(),
|
in_buffer: self.in_buffer.clone(),
|
||||||
endpoint: self.endpoint.clone(),
|
endpoint: self.endpoint.clone(),
|
||||||
input_queue_evt: queue_evts.remove(0),
|
input_queue_evt,
|
||||||
output_queue_evt: queue_evts.remove(0),
|
output_queue_evt,
|
||||||
input_evt,
|
input_evt,
|
||||||
config_evt: self.resizer.config_evt.try_clone().unwrap(),
|
config_evt: self.resizer.config_evt.try_clone().unwrap(),
|
||||||
resize_pipe: self.resize_pipe.as_ref().map(|p| p.try_clone().unwrap()),
|
resize_pipe: self.resize_pipe.as_ref().map(|p| p.try_clone().unwrap()),
|
||||||
|
@ -107,8 +107,7 @@ pub trait VirtioDevice: Send {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_evt: Arc<dyn VirtioInterrupt>,
|
interrupt_evt: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult;
|
) -> ActivateResult;
|
||||||
|
|
||||||
/// Optionally deactivates this device and returns ownership of the guest memory map, interrupt
|
/// Optionally deactivates this device and returns ownership of the guest memory map, interrupt
|
||||||
@ -251,19 +250,9 @@ impl VirtioCommon {
|
|||||||
|
|
||||||
pub fn activate(
|
pub fn activate(
|
||||||
&mut self,
|
&mut self,
|
||||||
queues: &[Queue<GuestMemoryAtomic<GuestMemoryMmap>>],
|
queues: &[(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)],
|
||||||
queue_evts: &[EventFd],
|
|
||||||
interrupt_cb: &Arc<dyn VirtioInterrupt>,
|
interrupt_cb: &Arc<dyn VirtioInterrupt>,
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
if queues.len() != queue_evts.len() {
|
|
||||||
error!(
|
|
||||||
"Cannot activate: length mismatch: queue_evts={} queues={}",
|
|
||||||
queue_evts.len(),
|
|
||||||
queues.len()
|
|
||||||
);
|
|
||||||
return Err(ActivateError::BadActivate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if queues.len() < self.min_queues.into() {
|
if queues.len() < self.min_queues.into() {
|
||||||
error!(
|
error!(
|
||||||
"Number of enabled queues lower than min: {} vs {}",
|
"Number of enabled queues lower than min: {} vs {}",
|
||||||
@ -290,7 +279,7 @@ impl VirtioCommon {
|
|||||||
self.interrupt_cb = Some(interrupt_cb.clone());
|
self.interrupt_cb = Some(interrupt_cb.clone());
|
||||||
|
|
||||||
let mut tmp_queue_evts: Vec<EventFd> = Vec::new();
|
let mut tmp_queue_evts: Vec<EventFd> = Vec::new();
|
||||||
for queue_evt in queue_evts.iter() {
|
for (_, _, queue_evt) in queues.iter() {
|
||||||
// Save the queue EventFD as we need to return it on reset
|
// Save the queue EventFD as we need to return it on reset
|
||||||
// but clone it to pass into the thread.
|
// but clone it to pass into the thread.
|
||||||
tmp_queue_evts.push(queue_evt.try_clone().map_err(|e| {
|
tmp_queue_evts.push(queue_evt.try_clone().map_err(|e| {
|
||||||
|
@ -1052,13 +1052,20 @@ impl VirtioDevice for Iommu {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
|
let mut virtqueues = Vec::new();
|
||||||
|
let mut queue_evts = Vec::new();
|
||||||
|
for (_, queue, queue_evt) in queues {
|
||||||
|
virtqueues.push(queue);
|
||||||
|
queue_evts.push(queue_evt);
|
||||||
|
}
|
||||||
|
|
||||||
let mut handler = IommuEpollHandler {
|
let mut handler = IommuEpollHandler {
|
||||||
queues,
|
queues: virtqueues,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
queue_evts,
|
queue_evts,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
|
@ -1004,20 +1004,22 @@ impl VirtioDevice for Mem {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
|
||||||
let mut handler = MemEpollHandler {
|
let mut handler = MemEpollHandler {
|
||||||
host_addr: self.host_addr,
|
host_addr: self.host_addr,
|
||||||
host_fd: self.host_fd,
|
host_fd: self.host_fd,
|
||||||
blocks_state: Arc::clone(&self.blocks_state),
|
blocks_state: Arc::clone(&self.blocks_state),
|
||||||
config: self.config.clone(),
|
config: self.config.clone(),
|
||||||
resize: self.resize.clone(),
|
resize: self.resize.clone(),
|
||||||
queue: queues.remove(0),
|
queue,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
queue_evt: queue_evts.remove(0),
|
queue_evt,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
hugepages: self.hugepages,
|
hugepages: self.hugepages,
|
||||||
|
@ -585,17 +585,15 @@ impl VirtioDevice for Net {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
|
|
||||||
let num_queues = queues.len();
|
let num_queues = queues.len();
|
||||||
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
|
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 {
|
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 {
|
||||||
let ctrl_queue_index = num_queues - 1;
|
let ctrl_queue_index = num_queues - 1;
|
||||||
let mut ctrl_queue = queues.remove(ctrl_queue_index);
|
let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index);
|
||||||
let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index);
|
|
||||||
|
|
||||||
ctrl_queue.set_event_idx(event_idx);
|
ctrl_queue.set_event_idx(event_idx);
|
||||||
|
|
||||||
@ -641,11 +639,13 @@ impl VirtioDevice for Net {
|
|||||||
let tx = TxVirtio::new();
|
let tx = TxVirtio::new();
|
||||||
let rx_tap_listening = false;
|
let rx_tap_listening = false;
|
||||||
|
|
||||||
let mut queue_pair = vec![queues.remove(0), queues.remove(0)];
|
let (_, queue_0, queue_evt_0) = queues.remove(0);
|
||||||
|
let (_, queue_1, queue_evt_1) = queues.remove(0);
|
||||||
|
let mut queue_pair = vec![queue_0, queue_1];
|
||||||
queue_pair[0].set_event_idx(event_idx);
|
queue_pair[0].set_event_idx(event_idx);
|
||||||
queue_pair[1].set_event_idx(event_idx);
|
queue_pair[1].set_event_idx(event_idx);
|
||||||
|
|
||||||
let queue_evt_pair = vec![queue_evts.remove(0), queue_evts.remove(0)];
|
let queue_evt_pair = vec![queue_evt_0, queue_evt_1];
|
||||||
|
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
|
@ -379,21 +379,23 @@ impl VirtioDevice for Pmem {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
if let Some(disk) = self.disk.as_ref() {
|
if let Some(disk) = self.disk.as_ref() {
|
||||||
let disk = disk.try_clone().map_err(|e| {
|
let disk = disk.try_clone().map_err(|e| {
|
||||||
error!("failed cloning pmem disk: {}", e);
|
error!("failed cloning pmem disk: {}", e);
|
||||||
ActivateError::BadActivate
|
ActivateError::BadActivate
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
|
||||||
let mut handler = PmemEpollHandler {
|
let mut handler = PmemEpollHandler {
|
||||||
queue: queues.remove(0),
|
queue,
|
||||||
disk,
|
disk,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
queue_evt: queue_evts.remove(0),
|
queue_evt,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
access_platform: self.common.access_platform.clone(),
|
access_platform: self.common.access_platform.clone(),
|
||||||
|
@ -35,7 +35,7 @@ const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE];
|
|||||||
const QUEUE_AVAIL_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1;
|
const QUEUE_AVAIL_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1;
|
||||||
|
|
||||||
struct RngEpollHandler {
|
struct RngEpollHandler {
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queue: Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||||
random_file: File,
|
random_file: File,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queue_evt: EventFd,
|
queue_evt: EventFd,
|
||||||
@ -46,7 +46,7 @@ struct RngEpollHandler {
|
|||||||
|
|
||||||
impl RngEpollHandler {
|
impl RngEpollHandler {
|
||||||
fn process_queue(&mut self) -> bool {
|
fn process_queue(&mut self) -> bool {
|
||||||
let queue = &mut self.queues[0];
|
let queue = &mut self.queue;
|
||||||
|
|
||||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||||
let mut used_count = 0;
|
let mut used_count = 0;
|
||||||
@ -219,10 +219,9 @@ impl VirtioDevice for Rng {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
if let Some(file) = self.random_file.as_ref() {
|
if let Some(file) = self.random_file.as_ref() {
|
||||||
@ -230,11 +229,14 @@ impl VirtioDevice for Rng {
|
|||||||
error!("failed cloning rng source: {}", e);
|
error!("failed cloning rng source: {}", e);
|
||||||
ActivateError::BadActivate
|
ActivateError::BadActivate
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
|
||||||
let mut handler = RngEpollHandler {
|
let mut handler = RngEpollHandler {
|
||||||
queues,
|
queue,
|
||||||
random_file,
|
random_file,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
queue_evt: queue_evts.remove(0),
|
queue_evt,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
access_platform: self.common.access_platform.clone(),
|
access_platform: self.common.access_platform.clone(),
|
||||||
|
@ -385,8 +385,7 @@ mod tests {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
_interrupt_evt: Arc<dyn VirtioInterrupt>,
|
_interrupt_evt: Arc<dyn VirtioInterrupt>,
|
||||||
_queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
_queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
_queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -292,8 +292,8 @@ pub struct VirtioPciDeviceActivator {
|
|||||||
memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||||
device: Arc<Mutex<dyn VirtioDevice>>,
|
device: Arc<Mutex<dyn VirtioDevice>>,
|
||||||
device_activated: Arc<AtomicBool>,
|
device_activated: Arc<AtomicBool>,
|
||||||
queues: Option<Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>>,
|
#[allow(clippy::type_complexity)]
|
||||||
queue_evts: Option<Vec<EventFd>>,
|
queues: Option<Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>>,
|
||||||
barrier: Option<Arc<Barrier>>,
|
barrier: Option<Arc<Barrier>>,
|
||||||
id: String,
|
id: String,
|
||||||
}
|
}
|
||||||
@ -304,7 +304,6 @@ impl VirtioPciDeviceActivator {
|
|||||||
self.memory.take().unwrap(),
|
self.memory.take().unwrap(),
|
||||||
self.interrupt.take().unwrap(),
|
self.interrupt.take().unwrap(),
|
||||||
self.queues.take().unwrap(),
|
self.queues.take().unwrap(),
|
||||||
self.queue_evts.take().unwrap(),
|
|
||||||
)?;
|
)?;
|
||||||
self.device_activated.store(true, Ordering::SeqCst);
|
self.device_activated.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
@ -700,7 +699,6 @@ impl VirtioPciDevice {
|
|||||||
|
|
||||||
fn prepare_activator(&mut self, barrier: Option<Arc<Barrier>>) -> VirtioPciDeviceActivator {
|
fn prepare_activator(&mut self, barrier: Option<Arc<Barrier>>) -> VirtioPciDeviceActivator {
|
||||||
let mut queues = Vec::new();
|
let mut queues = Vec::new();
|
||||||
let mut queue_evts = Vec::new();
|
|
||||||
|
|
||||||
for (queue_index, queue) in self.queues.iter().enumerate() {
|
for (queue_index, queue) in self.queues.iter().enumerate() {
|
||||||
if !queue.state.ready {
|
if !queue.state.ready {
|
||||||
@ -711,8 +709,11 @@ impl VirtioPciDevice {
|
|||||||
error!("Queue {} is not valid", queue_index);
|
error!("Queue {} is not valid", queue_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
queues.push(vm_virtio::clone_queue(queue));
|
queues.push((
|
||||||
queue_evts.push(self.queue_evts[queue_index].try_clone().unwrap());
|
queue_index,
|
||||||
|
vm_virtio::clone_queue(queue),
|
||||||
|
self.queue_evts[queue_index].try_clone().unwrap(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtioPciDeviceActivator {
|
VirtioPciDeviceActivator {
|
||||||
@ -721,7 +722,6 @@ impl VirtioPciDevice {
|
|||||||
device: self.device.clone(),
|
device: self.device.clone(),
|
||||||
queues: Some(queues),
|
queues: Some(queues),
|
||||||
device_activated: self.device_activated.clone(),
|
device_activated: self.device_activated.clone(),
|
||||||
queue_evts: Some(queue_evts),
|
|
||||||
barrier,
|
barrier,
|
||||||
id: self.id.clone(),
|
id: self.id.clone(),
|
||||||
}
|
}
|
||||||
|
@ -145,8 +145,7 @@ impl Vdpa {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: &GuestMemoryMmap,
|
_mem: &GuestMemoryMmap,
|
||||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_features(self.common.acked_features)
|
.set_features(self.common.acked_features)
|
||||||
@ -155,11 +154,11 @@ impl Vdpa {
|
|||||||
.set_backend_features(self.backend_features)
|
.set_backend_features(self.backend_features)
|
||||||
.map_err(Error::SetBackendFeatures)?;
|
.map_err(Error::SetBackendFeatures)?;
|
||||||
|
|
||||||
for (queue_index, queue) in queues.iter().enumerate() {
|
for (queue_index, queue, queue_evt) in queues.iter() {
|
||||||
let queue_max_size = queue.max_size();
|
let queue_max_size = queue.max_size();
|
||||||
let queue_size = queue.state.size;
|
let queue_size = queue.state.size;
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_vring_num(queue_index, queue_size)
|
.set_vring_num(*queue_index, queue_size)
|
||||||
.map_err(Error::SetVringNum)?;
|
.map_err(Error::SetVringNum)?;
|
||||||
|
|
||||||
let config_data = VringConfigData {
|
let config_data = VringConfigData {
|
||||||
@ -194,11 +193,11 @@ impl Vdpa {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_vring_addr(queue_index, &config_data)
|
.set_vring_addr(*queue_index, &config_data)
|
||||||
.map_err(Error::SetVringAddr)?;
|
.map_err(Error::SetVringAddr)?;
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_vring_base(
|
.set_vring_base(
|
||||||
queue_index,
|
*queue_index,
|
||||||
queue
|
queue
|
||||||
.avail_idx(Ordering::Acquire)
|
.avail_idx(Ordering::Acquire)
|
||||||
.map_err(Error::GetAvailableIndex)?
|
.map_err(Error::GetAvailableIndex)?
|
||||||
@ -207,15 +206,15 @@ impl Vdpa {
|
|||||||
.map_err(Error::SetVringBase)?;
|
.map_err(Error::SetVringBase)?;
|
||||||
|
|
||||||
if let Some(eventfd) =
|
if let Some(eventfd) =
|
||||||
virtio_interrupt.notifier(VirtioInterruptType::Queue(queue_index as u16))
|
virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16))
|
||||||
{
|
{
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_vring_call(queue_index, &eventfd)
|
.set_vring_call(*queue_index, &eventfd)
|
||||||
.map_err(Error::SetVringCall)?;
|
.map_err(Error::SetVringCall)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vhost
|
self.vhost
|
||||||
.set_vring_kick(queue_index, &queue_evts[queue_index])
|
.set_vring_kick(*queue_index, queue_evt)
|
||||||
.map_err(Error::SetVringKick)?;
|
.map_err(Error::SetVringKick)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,10 +296,9 @@ impl VirtioDevice for Vdpa {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
virtio_interrupt: Arc<dyn VirtioInterrupt>,
|
virtio_interrupt: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.activate_vdpa(&mem.memory(), &virtio_interrupt, queues, queue_evts)
|
self.activate_vdpa(&mem.memory(), &virtio_interrupt, queues)
|
||||||
.map_err(ActivateError::ActivateVdpa)?;
|
.map_err(ActivateError::ActivateVdpa)?;
|
||||||
|
|
||||||
// Store the virtio interrupt handler as we need to return it on reset
|
// Store the virtio interrupt handler as we need to return it on reset
|
||||||
|
@ -292,10 +292,9 @@ impl VirtioDevice for Blk {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
self.guest_memory = Some(mem.clone());
|
self.guest_memory = Some(mem.clone());
|
||||||
|
|
||||||
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
|
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
|
||||||
@ -307,7 +306,6 @@ impl VirtioDevice for Blk {
|
|||||||
let mut handler = self.vu_common.activate(
|
let mut handler = self.vu_common.activate(
|
||||||
mem,
|
mem,
|
||||||
queues,
|
queues,
|
||||||
queue_evts,
|
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
self.common.acked_features,
|
self.common.acked_features,
|
||||||
slave_req_handler,
|
slave_req_handler,
|
||||||
|
@ -504,10 +504,9 @@ impl VirtioDevice for Fs {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
self.guest_memory = Some(mem.clone());
|
self.guest_memory = Some(mem.clone());
|
||||||
|
|
||||||
// Initialize slave communication.
|
// Initialize slave communication.
|
||||||
@ -547,7 +546,6 @@ impl VirtioDevice for Fs {
|
|||||||
let mut handler = self.vu_common.activate(
|
let mut handler = self.vu_common.activate(
|
||||||
mem,
|
mem,
|
||||||
queues,
|
queues,
|
||||||
queue_evts,
|
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
self.common.acked_features,
|
self.common.acked_features,
|
||||||
slave_req_handler,
|
slave_req_handler,
|
||||||
|
@ -167,8 +167,7 @@ pub struct VhostUserEpollHandler<S: VhostUserMasterReqHandler> {
|
|||||||
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
pub mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
pub kill_evt: EventFd,
|
pub kill_evt: EventFd,
|
||||||
pub pause_evt: EventFd,
|
pub pause_evt: EventFd,
|
||||||
pub queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
pub queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
pub queue_evts: Vec<EventFd>,
|
|
||||||
pub virtio_interrupt: Arc<dyn VirtioInterrupt>,
|
pub virtio_interrupt: Arc<dyn VirtioInterrupt>,
|
||||||
pub acked_features: u64,
|
pub acked_features: u64,
|
||||||
pub acked_protocol_features: u64,
|
pub acked_protocol_features: u64,
|
||||||
@ -224,10 +223,9 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
|||||||
vhost_user
|
vhost_user
|
||||||
.reinitialize_vhost_user(
|
.reinitialize_vhost_user(
|
||||||
self.mem.memory().deref(),
|
self.mem.memory().deref(),
|
||||||
self.queues.iter().map(vm_virtio::clone_queue).collect(),
|
self.queues
|
||||||
self.queue_evts
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|q| q.try_clone().unwrap())
|
.map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap()))
|
||||||
.collect(),
|
.collect(),
|
||||||
&self.virtio_interrupt,
|
&self.virtio_interrupt,
|
||||||
self.acked_features,
|
self.acked_features,
|
||||||
@ -299,8 +297,7 @@ impl VhostUserCommon {
|
|||||||
pub fn activate<T: VhostUserMasterReqHandler>(
|
pub fn activate<T: VhostUserMasterReqHandler>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
acked_features: u64,
|
acked_features: u64,
|
||||||
slave_req_handler: Option<MasterReqHandler<T>>,
|
slave_req_handler: Option<MasterReqHandler<T>>,
|
||||||
@ -324,8 +321,10 @@ impl VhostUserCommon {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.setup_vhost_user(
|
.setup_vhost_user(
|
||||||
&mem.memory(),
|
&mem.memory(),
|
||||||
queues.iter().map(vm_virtio::clone_queue).collect(),
|
queues
|
||||||
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
|
.iter()
|
||||||
|
.map(|(i, q, e)| (*i, vm_virtio::clone_queue(q), e.try_clone().unwrap()))
|
||||||
|
.collect(),
|
||||||
&interrupt_cb,
|
&interrupt_cb,
|
||||||
acked_features,
|
acked_features,
|
||||||
&slave_req_handler,
|
&slave_req_handler,
|
||||||
@ -339,7 +338,6 @@ impl VhostUserCommon {
|
|||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
queues,
|
queues,
|
||||||
queue_evts,
|
|
||||||
virtio_interrupt: interrupt_cb,
|
virtio_interrupt: interrupt_cb,
|
||||||
acked_features,
|
acked_features,
|
||||||
acked_protocol_features: self.acked_protocol_features,
|
acked_protocol_features: self.acked_protocol_features,
|
||||||
|
@ -272,18 +272,16 @@ impl VirtioDevice for Net {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
mut queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
self.guest_memory = Some(mem.clone());
|
self.guest_memory = Some(mem.clone());
|
||||||
|
|
||||||
let num_queues = queues.len();
|
let num_queues = queues.len();
|
||||||
let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into());
|
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 {
|
if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && num_queues % 2 != 0 {
|
||||||
let ctrl_queue_index = num_queues - 1;
|
let ctrl_queue_index = num_queues - 1;
|
||||||
let mut ctrl_queue = queues.remove(ctrl_queue_index);
|
let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index);
|
||||||
let ctrl_queue_evt = queue_evts.remove(ctrl_queue_index);
|
|
||||||
|
|
||||||
ctrl_queue.set_event_idx(event_idx);
|
ctrl_queue.set_event_idx(event_idx);
|
||||||
|
|
||||||
@ -336,7 +334,6 @@ impl VirtioDevice for Net {
|
|||||||
let mut handler = self.vu_common.activate(
|
let mut handler = self.vu_common.activate(
|
||||||
mem,
|
mem,
|
||||||
queues,
|
queues,
|
||||||
queue_evts,
|
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
backend_acked_features,
|
backend_acked_features,
|
||||||
slave_req_handler,
|
slave_req_handler,
|
||||||
|
@ -151,8 +151,7 @@ impl VhostUserHandle {
|
|||||||
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mem: &GuestMemoryMmap,
|
mem: &GuestMemoryMmap,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||||
acked_features: u64,
|
acked_features: u64,
|
||||||
slave_req_handler: &Option<MasterReqHandler<S>>,
|
slave_req_handler: &Option<MasterReqHandler<S>>,
|
||||||
@ -171,9 +170,9 @@ impl VhostUserHandle {
|
|||||||
// Send set_vring_num here, since it could tell backends, like SPDK,
|
// Send set_vring_num here, since it could tell backends, like SPDK,
|
||||||
// how many virt queues to be handled, which backend required to know
|
// how many virt queues to be handled, which backend required to know
|
||||||
// at early stage.
|
// at early stage.
|
||||||
for (queue_index, queue) in queues.iter().enumerate() {
|
for (queue_index, queue, _) in queues.iter() {
|
||||||
self.vu
|
self.vu
|
||||||
.set_vring_num(queue_index, queue.state.size)
|
.set_vring_num(*queue_index, queue.state.size)
|
||||||
.map_err(Error::VhostUserSetVringNum)?;
|
.map_err(Error::VhostUserSetVringNum)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +183,7 @@ impl VhostUserHandle {
|
|||||||
mmap_size: 0,
|
mmap_size: 0,
|
||||||
mmap_offset: 0,
|
mmap_offset: 0,
|
||||||
num_queues: queues.len() as u16,
|
num_queues: queues.len() as u16,
|
||||||
queue_size: queues[0].state.size,
|
queue_size: queues[0].1.state.size,
|
||||||
};
|
};
|
||||||
let (info, fd) = self
|
let (info, fd) = self
|
||||||
.vu
|
.vu
|
||||||
@ -202,7 +201,7 @@ impl VhostUserHandle {
|
|||||||
let num_queues = queues.len() as usize;
|
let num_queues = queues.len() as usize;
|
||||||
|
|
||||||
let mut vrings_info = Vec::new();
|
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 actual_size: usize = queue.state.size.try_into().unwrap();
|
||||||
|
|
||||||
let config_data = VringConfigData {
|
let config_data = VringConfigData {
|
||||||
@ -240,11 +239,11 @@ impl VhostUserHandle {
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.vu
|
self.vu
|
||||||
.set_vring_addr(queue_index, &config_data)
|
.set_vring_addr(*queue_index, &config_data)
|
||||||
.map_err(Error::VhostUserSetVringAddr)?;
|
.map_err(Error::VhostUserSetVringAddr)?;
|
||||||
self.vu
|
self.vu
|
||||||
.set_vring_base(
|
.set_vring_base(
|
||||||
queue_index,
|
*queue_index,
|
||||||
queue
|
queue
|
||||||
.avail_idx(Ordering::Acquire)
|
.avail_idx(Ordering::Acquire)
|
||||||
.map_err(Error::GetAvailableIndex)?
|
.map_err(Error::GetAvailableIndex)?
|
||||||
@ -253,15 +252,15 @@ impl VhostUserHandle {
|
|||||||
.map_err(Error::VhostUserSetVringBase)?;
|
.map_err(Error::VhostUserSetVringBase)?;
|
||||||
|
|
||||||
if let Some(eventfd) =
|
if let Some(eventfd) =
|
||||||
virtio_interrupt.notifier(VirtioInterruptType::Queue(queue_index as u16))
|
virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16))
|
||||||
{
|
{
|
||||||
self.vu
|
self.vu
|
||||||
.set_vring_call(queue_index, &eventfd)
|
.set_vring_call(*queue_index, &eventfd)
|
||||||
.map_err(Error::VhostUserSetVringCall)?;
|
.map_err(Error::VhostUserSetVringCall)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vu
|
self.vu
|
||||||
.set_vring_kick(queue_index, &queue_evts[queue_index])
|
.set_vring_kick(*queue_index, queue_evt)
|
||||||
.map_err(Error::VhostUserSetVringKick)?;
|
.map_err(Error::VhostUserSetVringKick)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,8 +325,7 @@ impl VhostUserHandle {
|
|||||||
pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
|
pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mem: &GuestMemoryMmap,
|
mem: &GuestMemoryMmap,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||||
acked_features: u64,
|
acked_features: u64,
|
||||||
acked_protocol_features: u64,
|
acked_protocol_features: u64,
|
||||||
@ -339,7 +337,6 @@ impl VhostUserHandle {
|
|||||||
self.setup_vhost_user(
|
self.setup_vhost_user(
|
||||||
mem,
|
mem,
|
||||||
queues,
|
queues,
|
||||||
queue_evts,
|
|
||||||
virtio_interrupt,
|
virtio_interrupt,
|
||||||
acked_features,
|
acked_features,
|
||||||
slave_req_handler,
|
slave_req_handler,
|
||||||
|
@ -432,15 +432,21 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
|
let mut virtqueues = Vec::new();
|
||||||
|
let mut queue_evts = Vec::new();
|
||||||
|
for (_, queue, queue_evt) in queues {
|
||||||
|
virtqueues.push(queue);
|
||||||
|
queue_evts.push(queue_evt);
|
||||||
|
}
|
||||||
|
|
||||||
let mut handler = VsockEpollHandler {
|
let mut handler = VsockEpollHandler {
|
||||||
mem,
|
mem,
|
||||||
queues,
|
queues: virtqueues,
|
||||||
queue_evts,
|
queue_evts,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
@ -591,7 +597,6 @@ mod tests {
|
|||||||
GuestMemoryAtomic::new(ctx.mem.clone()),
|
GuestMemoryAtomic::new(ctx.mem.clone()),
|
||||||
Arc::new(NoopVirtioInterrupt {}),
|
Arc::new(NoopVirtioInterrupt {}),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
Vec::new(),
|
|
||||||
);
|
);
|
||||||
match bad_activate {
|
match bad_activate {
|
||||||
Err(ActivateError::BadActivate) => (),
|
Err(ActivateError::BadActivate) => (),
|
||||||
@ -606,14 +611,21 @@ mod tests {
|
|||||||
memory.clone(),
|
memory.clone(),
|
||||||
Arc::new(NoopVirtioInterrupt {}),
|
Arc::new(NoopVirtioInterrupt {}),
|
||||||
vec![
|
vec![
|
||||||
Queue::new(memory.clone(), 256),
|
(
|
||||||
Queue::new(memory.clone(), 256),
|
0,
|
||||||
Queue::new(memory, 256),
|
Queue::new(memory.clone(), 256),
|
||||||
],
|
EventFd::new(EFD_NONBLOCK).unwrap(),
|
||||||
vec![
|
),
|
||||||
EventFd::new(EFD_NONBLOCK).unwrap(),
|
(
|
||||||
EventFd::new(EFD_NONBLOCK).unwrap(),
|
1,
|
||||||
EventFd::new(EFD_NONBLOCK).unwrap(),
|
Queue::new(memory.clone(), 256),
|
||||||
|
EventFd::new(EFD_NONBLOCK).unwrap(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
Queue::new(memory, 256),
|
||||||
|
EventFd::new(EFD_NONBLOCK).unwrap(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -47,7 +47,7 @@ const WATCHDOG_TIMER_INTERVAL: i64 = 15;
|
|||||||
const WATCHDOG_TIMEOUT: u64 = WATCHDOG_TIMER_INTERVAL as u64 + 5;
|
const WATCHDOG_TIMEOUT: u64 = WATCHDOG_TIMER_INTERVAL as u64 + 5;
|
||||||
|
|
||||||
struct WatchdogEpollHandler {
|
struct WatchdogEpollHandler {
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
queue: Queue<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queue_evt: EventFd,
|
queue_evt: EventFd,
|
||||||
kill_evt: EventFd,
|
kill_evt: EventFd,
|
||||||
@ -61,7 +61,7 @@ impl WatchdogEpollHandler {
|
|||||||
// The main queue is very simple - the driver "pings" the device by passing it a (write-only)
|
// The main queue is very simple - the driver "pings" the device by passing it a (write-only)
|
||||||
// descriptor. In response the device writes a 1 into the descriptor and returns it to the driver
|
// descriptor. In response the device writes a 1 into the descriptor and returns it to the driver
|
||||||
fn process_queue(&mut self) -> bool {
|
fn process_queue(&mut self) -> bool {
|
||||||
let queue = &mut self.queues[0];
|
let queue = &mut self.queue;
|
||||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||||
let mut used_count = 0;
|
let mut used_count = 0;
|
||||||
for mut desc_chain in queue.iter().unwrap() {
|
for mut desc_chain in queue.iter().unwrap() {
|
||||||
@ -291,10 +291,9 @@ impl VirtioDevice for Watchdog {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
queues: Vec<Queue<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
mut queues: Vec<(usize, Queue<GuestMemoryAtomic<GuestMemoryMmap>>, EventFd)>,
|
||||||
mut queue_evts: Vec<EventFd>,
|
|
||||||
) -> ActivateResult {
|
) -> ActivateResult {
|
||||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
self.common.activate(&queues, &interrupt_cb)?;
|
||||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||||
|
|
||||||
let reset_evt = self.reset_evt.try_clone().map_err(|e| {
|
let reset_evt = self.reset_evt.try_clone().map_err(|e| {
|
||||||
@ -307,10 +306,12 @@ impl VirtioDevice for Watchdog {
|
|||||||
ActivateError::BadActivate
|
ActivateError::BadActivate
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let (_, queue, queue_evt) = queues.remove(0);
|
||||||
|
|
||||||
let mut handler = WatchdogEpollHandler {
|
let mut handler = WatchdogEpollHandler {
|
||||||
queues,
|
queue,
|
||||||
interrupt_cb,
|
interrupt_cb,
|
||||||
queue_evt: queue_evts.remove(0),
|
queue_evt,
|
||||||
kill_evt,
|
kill_evt,
|
||||||
pause_evt,
|
pause_evt,
|
||||||
timer,
|
timer,
|
||||||
|
Loading…
Reference in New Issue
Block a user