mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-07-16 14:17:16 +00:00
vhost_user_backend: Make some trait functions as mutable
Let's be realistic, the trait VhostUserBackend will need to have mutable self for some functions like handle_event, process_queue and set_config, which is the reason why this commit needs to introduce a RwLock on the backend instance that was passed around as a simple Arc. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
d4f7f73bc8
commit
36de390caf
@ -66,12 +66,12 @@ pub trait VhostUserBackend: Send + Sync + 'static {
|
|||||||
/// listeners onto specific file descriptors. The library can handle
|
/// listeners onto specific file descriptors. The library can handle
|
||||||
/// virtqueues on its own, but does not know what to do with events
|
/// virtqueues on its own, but does not know what to do with events
|
||||||
/// happening on custom listeners.
|
/// happening on custom listeners.
|
||||||
fn handle_event(&self, device_event: u16, evset: epoll::Events) -> Result<bool>;
|
fn handle_event(&mut self, device_event: u16, evset: epoll::Events) -> Result<bool>;
|
||||||
|
|
||||||
/// This function is responsible for the actual processing that needs to
|
/// This function is responsible for the actual processing that needs to
|
||||||
/// happen when one of the virtqueues is available.
|
/// happen when one of the virtqueues is available.
|
||||||
fn process_queue(
|
fn process_queue(
|
||||||
&self,
|
&mut self,
|
||||||
q_idx: u16,
|
q_idx: u16,
|
||||||
avail_desc: &DescriptorChain,
|
avail_desc: &DescriptorChain,
|
||||||
mem: &GuestMemoryMmap,
|
mem: &GuestMemoryMmap,
|
||||||
@ -81,7 +81,7 @@ pub trait VhostUserBackend: Send + Sync + 'static {
|
|||||||
fn get_config(&self, offset: u32, size: u32) -> Vec<u8>;
|
fn get_config(&self, offset: u32, size: u32) -> Vec<u8>;
|
||||||
|
|
||||||
/// Set virtio device configuration.
|
/// Set virtio device configuration.
|
||||||
fn set_config(&self, offset: u32, buf: &[u8]);
|
fn set_config(&mut self, offset: u32, buf: &[u8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This structure is the public API the backend is allowed to interact with
|
/// This structure is the public API the backend is allowed to interact with
|
||||||
@ -225,7 +225,7 @@ impl Vring {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct VringEpollHandler<S: VhostUserBackend> {
|
struct VringEpollHandler<S: VhostUserBackend> {
|
||||||
backend: Arc<S>,
|
backend: Arc<RwLock<S>>,
|
||||||
vrings: Vec<Arc<RwLock<Vring>>>,
|
vrings: Vec<Arc<RwLock<Vring>>>,
|
||||||
mem: Option<GuestMemoryMmap>,
|
mem: Option<GuestMemoryMmap>,
|
||||||
epoll_fd: RawFd,
|
epoll_fd: RawFd,
|
||||||
@ -244,6 +244,8 @@ impl<S: VhostUserBackend> VringEpollHandler<S> {
|
|||||||
for avail_desc in vring.queue.iter(&mem) {
|
for avail_desc in vring.queue.iter(&mem) {
|
||||||
let used_len = self
|
let used_len = self
|
||||||
.backend
|
.backend
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
.process_queue(q_idx, &avail_desc, &mem)
|
.process_queue(q_idx, &avail_desc, &mem)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -277,7 +279,11 @@ impl<S: VhostUserBackend> VringEpollHandler<S> {
|
|||||||
|
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
_ => self.backend.handle_event(device_event, evset),
|
_ => self
|
||||||
|
.backend
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.handle_event(device_event, evset),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +382,7 @@ impl<S: VhostUserBackend> VringWorker<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct VhostUserHandler<S: VhostUserBackend> {
|
struct VhostUserHandler<S: VhostUserBackend> {
|
||||||
backend: Arc<S>,
|
backend: Arc<RwLock<S>>,
|
||||||
vring_handler: Arc<RwLock<VringEpollHandler<S>>>,
|
vring_handler: Arc<RwLock<VringEpollHandler<S>>>,
|
||||||
owned: bool,
|
owned: bool,
|
||||||
features_acked: bool,
|
features_acked: bool,
|
||||||
@ -393,7 +399,7 @@ impl<S: VhostUserBackend> VhostUserHandler<S> {
|
|||||||
let num_queues = backend.num_queues();
|
let num_queues = backend.num_queues();
|
||||||
let max_queue_size = backend.max_queue_size();
|
let max_queue_size = backend.max_queue_size();
|
||||||
|
|
||||||
let arc_backend = Arc::new(backend);
|
let arc_backend = Arc::new(RwLock::new(backend));
|
||||||
let vrings = vec![Arc::new(RwLock::new(Vring::new(max_queue_size as u16))); num_queues];
|
let vrings = vec![Arc::new(RwLock::new(Vring::new(max_queue_size as u16))); num_queues];
|
||||||
// Create the epoll file descriptor
|
// Create the epoll file descriptor
|
||||||
let epoll_fd = epoll::create(true).unwrap();
|
let epoll_fd = epoll::create(true).unwrap();
|
||||||
@ -462,13 +468,13 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_features(&mut self) -> VhostUserResult<u64> {
|
fn get_features(&mut self) -> VhostUserResult<u64> {
|
||||||
Ok(self.backend.features())
|
Ok(self.backend.read().unwrap().features())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_features(&mut self, features: u64) -> VhostUserResult<()> {
|
fn set_features(&mut self, features: u64) -> VhostUserResult<()> {
|
||||||
if !self.owned || self.features_acked {
|
if !self.owned || self.features_acked {
|
||||||
return Err(VhostUserError::InvalidOperation);
|
return Err(VhostUserError::InvalidOperation);
|
||||||
} else if (features & !self.backend.features()) != 0 {
|
} else if (features & !self.backend.read().unwrap().features()) != 0 {
|
||||||
return Err(VhostUserError::InvalidParam);
|
return Err(VhostUserError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +641,7 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
self.vrings[index as usize].write().unwrap().kick =
|
self.vrings[index as usize].write().unwrap().kick =
|
||||||
Some(unsafe { EventFd::from_raw_fd(fd.unwrap()) });;
|
Some(unsafe { EventFd::from_raw_fd(fd.unwrap()) });
|
||||||
|
|
||||||
// Quotation from vhost-user spec:
|
// Quotation from vhost-user spec:
|
||||||
// Client must start ring upon receiving a kick (that is, detecting
|
// Client must start ring upon receiving a kick (that is, detecting
|
||||||
@ -738,7 +744,7 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
|
|||||||
return Err(VhostUserError::InvalidParam);
|
return Err(VhostUserError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self.backend.get_config(offset, size))
|
Ok(self.backend.read().unwrap().get_config(offset, size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_config(
|
fn set_config(
|
||||||
@ -758,7 +764,7 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
|
|||||||
return Err(VhostUserError::InvalidParam);
|
return Err(VhostUserError::InvalidParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.backend.set_config(offset, buf);
|
self.backend.write().unwrap().set_config(offset, buf);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user