diff options
author | Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> | 2019-12-06 10:01:32 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-09 03:06:47 +0000 |
commit | 39087b289a3278bd02d28c1318d3cfb40c94e6db (patch) | |
tree | 2ea70f3065d5122326cf345a9b475311669322bf /devices/src/virtio/virtio_pci_device.rs | |
parent | d62df4aa6e58c85119077105ebfb81cf6dc617f2 (diff) | |
download | crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar.gz crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar.bz2 crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar.lz crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar.xz crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.tar.zst crosvm-39087b289a3278bd02d28c1318d3cfb40c94e6db.zip |
devices: clone the EventFds before activate
The interrupt_evt/interrupt_resample_evt/queue_evts were move to activate so the reset method has to return them back (although there is no virtio device implemented the reset method yet). Instead of move, another way is just clone these EventFds so that they don't need needed to be returned. The advantage of doing this can avoid changing every virtio device reset method (again, currently there is no virtio device implemented the reset method yet, but this method is going to used when needs to support the reset of a virtio device) for returning them, which can simplify the code. And reset method just needs to take care their own specific resources. The disadvantage is that, the clone of an EventFd is try_clone which might return error code (although this shouldn't happen). If in such case, the virtio device won't be activated. BUG=None TEST=launch crosvm guest with virtio devices(rng/balloon/blk/net). Change-Id: I6e55782c3ecc46bfa878aff24b85a58a7ed66365 Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1925682 Reviewed-by: Dylan Reid <dgreid@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'devices/src/virtio/virtio_pci_device.rs')
-rw-r--r-- | devices/src/virtio/virtio_pci_device.rs | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/devices/src/virtio/virtio_pci_device.rs b/devices/src/virtio/virtio_pci_device.rs index 9ace795..91e139b 100644 --- a/devices/src/virtio/virtio_pci_device.rs +++ b/devices/src/virtio/virtio_pci_device.rs @@ -12,7 +12,7 @@ use data_model::{DataInit, Le32}; use kvm::Datamatch; use libc::ERANGE; use resources::{Alloc, MmioType, SystemAllocator}; -use sys_util::{EventFd, GuestMemory, Result}; +use sys_util::{warn, EventFd, GuestMemory, Result}; use super::*; use crate::pci::{ @@ -318,6 +318,10 @@ impl VirtioPciDevice { self.settings_bar = settings_bar; Ok(()) } + + fn clone_queue_evts(&self) -> Result<Vec<EventFd>> { + self.queue_evts.iter().map(|e| e.try_clone()).collect() + } } impl PciDevice for VirtioPciDevice { @@ -573,8 +577,31 @@ impl PciDevice for VirtioPciDevice { if !self.device_activated && self.is_driver_ready() && self.are_queues_valid() { if let Some(interrupt_evt) = self.interrupt_evt.take() { + self.interrupt_evt = match interrupt_evt.try_clone() { + Ok(evt) => Some(evt), + Err(e) => { + warn!( + "{} failed to clone interrupt_evt: {}", + self.debug_label(), + e + ); + None + } + }; if let Some(interrupt_resample_evt) = self.interrupt_resample_evt.take() { + self.interrupt_resample_evt = match interrupt_resample_evt.try_clone() { + Ok(evt) => Some(evt), + Err(e) => { + warn!( + "{} failed to clone interrupt_resample_evt: {}", + self.debug_label(), + e + ); + None + } + }; if let Some(mem) = self.mem.take() { + self.mem = Some(mem.clone()); let interrupt = Interrupt::new( self.interrupt_status.clone(), interrupt_evt, @@ -583,13 +610,24 @@ impl PciDevice for VirtioPciDevice { self.common_config.msix_config, ); - self.device.activate( - mem, - interrupt, - self.queues.clone(), - self.queue_evts.split_off(0), - ); - self.device_activated = true; + match self.clone_queue_evts() { + Ok(queue_evts) => { + self.device.activate( + mem, + interrupt, + self.queues.clone(), + queue_evts, + ); + self.device_activated = true; + } + Err(e) => { + warn!( + "{} not activate due to failed to clone queue_evts: {}", + self.debug_label(), + e + ); + } + } } } } |