From 885950c2a4a65486524ac53e40f6b6515d7ebd3a Mon Sep 17 00:00:00 2001 From: Cautreoxit Date: Thu, 14 Nov 2024 21:10:55 +0800 Subject: [PATCH] Add VirtioBlockFeature to cache virtio-blk's features --- kernel/comps/virtio/src/device/block/device.rs | 7 +++++-- kernel/comps/virtio/src/device/block/mod.rs | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/kernel/comps/virtio/src/device/block/device.rs b/kernel/comps/virtio/src/device/block/device.rs index 885453357..4d842dccb 100644 --- a/kernel/comps/virtio/src/device/block/device.rs +++ b/kernel/comps/virtio/src/device/block/device.rs @@ -19,7 +19,7 @@ use ostd::{ Pod, }; -use super::{BlockFeatures, VirtioBlockConfig}; +use super::{BlockFeatures, VirtioBlockConfig, VirtioBlockFeature}; use crate::{ device::{ block::{ReqType, RespStatus}, @@ -92,6 +92,7 @@ impl aster_block::BlockDevice for BlockDevice { #[derive(Debug)] struct DeviceInner { config: SafePtr, + features: VirtioBlockFeature, queue: SpinLock, transport: SpinLock>, block_requests: DmaStream, @@ -122,6 +123,7 @@ impl DeviceInner { "Not supporting Multi-Queue Block IO Queueing Mechanism, only using the first queue" ); } + let features = VirtioBlockFeature::new(transport.as_ref()); let queue = VirtQueue::new(0, Self::QUEUE_SIZE, transport.as_mut()) .expect("create virtqueue failed"); let block_requests = { @@ -137,6 +139,7 @@ impl DeviceInner { let device = Arc::new(Self { config, + features, queue: SpinLock::new(queue), transport: SpinLock::new(transport), block_requests, @@ -410,7 +413,7 @@ impl DeviceInner { /// Flushes any cached data from the guest to the persistent storage on the host. /// This will be ignored if the device doesn't support the `VIRTIO_BLK_F_FLUSH` feature. fn flush(&self, bio_request: BioRequest) { - if self.transport.lock().read_device_features() & BlockFeatures::FLUSH.bits() == 0 { + if self.features.support_flush { bio_request.bios().for_each(|bio| { bio.complete(BioStatus::Complete); }); diff --git a/kernel/comps/virtio/src/device/block/mod.rs b/kernel/comps/virtio/src/device/block/mod.rs index 31fbef271..36b157af3 100644 --- a/kernel/comps/virtio/src/device/block/mod.rs +++ b/kernel/comps/virtio/src/device/block/mod.rs @@ -111,6 +111,12 @@ pub struct VirtioBlockTopology { opt_io_size: u32, } +#[derive(Debug, Copy, Clone)] +#[repr(C)] +pub struct VirtioBlockFeature { + support_flush: bool, +} + impl VirtioBlockConfig { pub(self) fn new(transport: &dyn VirtioTransport) -> SafePtr { let memory = transport.device_config_memory(); @@ -135,3 +141,10 @@ impl VirtioBlockConfig { .map(|val| val as usize) } } + +impl VirtioBlockFeature { + pub(self) fn new(transport: &dyn VirtioTransport) -> Self { + let support_flush = transport.read_device_features() & BlockFeatures::FLUSH.bits() == 1; + VirtioBlockFeature { support_flush } + } +}