From e78e34b36aaf102d600550ef309f778f57b5c594 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 16 Apr 2020 17:13:08 +0200 Subject: [PATCH] vhost_user_blk: Make DiskFile sharable across threads The DiskFile will need to be shared across multiple threads when running multiple queues across these threads. That's why it needs to be put inside an Arc. The reason for the Mutex is because execute() expects a mutable object implementing Read + Write + Seek. Unfortunately, this create a contention point as the object needs to be locked from each thread, reducing the performance gain we will get with multiple threads. The need for an immutable object would solve this problem, and it will be addressed later through follow up patches. Signed-off-by: Sebastien Boeuf --- vhost_user_block/src/lib.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/vhost_user_block/src/lib.rs b/vhost_user_block/src/lib.rs index d507bf099..6be62ce3c 100644 --- a/vhost_user_block/src/lib.rs +++ b/vhost_user_block/src/lib.rs @@ -23,6 +23,7 @@ use std::io::Read; use std::io::{Seek, SeekFrom, Write}; use std::mem; use std::num::Wrapping; +use std::ops::DerefMut; use std::os::unix::fs::OpenOptionsExt; use std::path::PathBuf; use std::process; @@ -98,7 +99,7 @@ impl convert::From for io::Error { pub struct VhostUserBlkThread { mem: Option, - disk_image: Box, + disk_image: Arc>, disk_image_id: Vec, disk_nsectors: u64, config: virtio_blk_config, @@ -127,12 +128,14 @@ impl VhostUserBlkThread { let image_id = build_disk_image_id(&PathBuf::from(&image_path)); let image_type = qcow::detect_image_type(&mut raw_img).unwrap(); - let mut image = match image_type { - ImageType::Raw => Box::new(raw_img) as Box, - ImageType::Qcow2 => Box::new(QcowFile::from(raw_img).unwrap()) as Box, + let image = match image_type { + ImageType::Raw => Arc::new(Mutex::new(raw_img)) as Arc>, + ImageType::Qcow2 => { + Arc::new(Mutex::new(QcowFile::from(raw_img).unwrap())) as Arc> + } }; - let nsectors = (image.seek(SeekFrom::End(0)).unwrap() as u64) / SECTOR_SIZE; + let nsectors = (image.lock().unwrap().seek(SeekFrom::End(0)).unwrap() as u64) / SECTOR_SIZE; let mut config = virtio_blk_config::default(); config.capacity = nsectors; @@ -171,7 +174,7 @@ impl VhostUserBlkThread { Ok(request) => { debug!("element is a valid request"); let status = match request.execute( - &mut self.disk_image, + &mut self.disk_image.lock().unwrap().deref_mut(), self.disk_nsectors, mem, &self.disk_image_id,