From 4e2bdc65de96324c72a6c10a0b4907dcaac413c3 Mon Sep 17 00:00:00 2001 From: Zhang Junyang Date: Mon, 18 Aug 2025 08:13:51 +0000 Subject: [PATCH] Refactor implicit `Arc` APIs for DMA --- kernel/comps/block/src/bio.rs | 12 ++-- kernel/comps/network/src/buffer.rs | 8 +-- kernel/comps/network/src/dma_pool.rs | 6 +- .../comps/virtio/src/device/block/device.rs | 10 ++-- .../comps/virtio/src/device/console/device.rs | 8 +-- .../comps/virtio/src/device/input/device.rs | 5 +- .../comps/virtio/src/device/network/device.rs | 2 +- .../comps/virtio/src/device/socket/buffer.rs | 3 +- kernel/comps/virtio/src/dma_buf.rs | 49 +++++++++------- kernel/comps/virtio/src/queue.rs | 58 ++++++++++--------- .../comps/virtio/src/transport/mmio/device.rs | 6 +- kernel/comps/virtio/src/transport/mod.rs | 8 +-- .../comps/virtio/src/transport/pci/device.rs | 8 +-- .../comps/virtio/src/transport/pci/legacy.rs | 8 +-- kernel/libs/aster-util/src/mem_obj_slice.rs | 4 +- ostd/src/mm/dma/dma_coherent.rs | 30 ++++------ ostd/src/mm/dma/dma_stream.rs | 49 +++++++--------- 17 files changed, 137 insertions(+), 137 deletions(-) diff --git a/kernel/comps/block/src/bio.rs b/kernel/comps/block/src/bio.rs index 973b8e4d6..7a61119be 100644 --- a/kernel/comps/block/src/bio.rs +++ b/kernel/comps/block/src/bio.rs @@ -379,7 +379,7 @@ pub struct BioSegment { #[derive(Debug)] struct BioSegmentInner { /// Internal DMA slice. - dma_slice: Slice, + dma_slice: Slice>, /// Whether the segment is allocated from the pool. from_pool: bool, } @@ -435,7 +435,7 @@ impl BioSegment { .unwrap(); let dma_stream = DmaStream::map(segment.into(), direction.into(), false).unwrap(); BioSegmentInner { - dma_slice: Slice::new(dma_stream, offset..offset + len), + dma_slice: Slice::new(Arc::new(dma_stream), offset..offset + len), from_pool: false, } }); @@ -451,7 +451,7 @@ impl BioSegment { let dma_stream = DmaStream::map(segment, direction.into(), false).unwrap(); Self { inner: Arc::new(BioSegmentInner { - dma_slice: Slice::new(dma_stream, 0..len), + dma_slice: Slice::new(Arc::new(dma_stream), 0..len), from_pool: false, }), } @@ -478,7 +478,7 @@ impl BioSegment { } /// Returns the inner DMA slice. - pub fn inner_dma_slice(&self) -> &Slice { + pub fn inner_dma_slice(&self) -> &Slice> { &self.inner.dma_slice } @@ -531,7 +531,7 @@ impl BioSegmentInner { /// the `DmaStream`. // TODO: Use a more advanced allocation algorithm to replace the naive one to improve efficiency. struct BioSegmentPool { - pool: DmaStream, + pool: Arc, total_blocks: usize, direction: BioDirection, manager: SpinLock, @@ -567,7 +567,7 @@ impl BioSegmentPool { }); Self { - pool, + pool: Arc::new(pool), total_blocks, direction, manager, diff --git a/kernel/comps/network/src/buffer.rs b/kernel/comps/network/src/buffer.rs index 7f79ac913..d5c6a13e1 100644 --- a/kernel/comps/network/src/buffer.rs +++ b/kernel/comps/network/src/buffer.rs @@ -16,16 +16,16 @@ use spin::Once; use crate::dma_pool::{DmaPool, DmaSegment}; pub struct TxBuffer { - dma_stream: DmaStream, + dma_stream: Arc, nbytes: usize, - pool: &'static SpinLock, BottomHalfDisabled>, + pool: &'static SpinLock>, BottomHalfDisabled>, } impl TxBuffer { pub fn new( header: &H, packet: &[u8], - pool: &'static SpinLock, BottomHalfDisabled>, + pool: &'static SpinLock>, BottomHalfDisabled>, ) -> Self { let header = header.as_bytes(); let nbytes = header.len() + packet.len(); @@ -38,7 +38,7 @@ impl TxBuffer { let segment = FrameAllocOptions::new() .alloc_segment(TX_BUFFER_LEN / PAGE_SIZE) .unwrap(); - DmaStream::map(segment.into(), DmaDirection::ToDevice, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::ToDevice, false).unwrap()) }; let tx_buffer = { diff --git a/kernel/comps/network/src/dma_pool.rs b/kernel/comps/network/src/dma_pool.rs index 88ccdad6a..cd4580ba3 100644 --- a/kernel/comps/network/src/dma_pool.rs +++ b/kernel/comps/network/src/dma_pool.rs @@ -137,7 +137,7 @@ impl DmaPool { #[derive(Debug)] struct DmaPage { - storage: DmaStream, + storage: Arc, segment_size: usize, // `BitArray` is 64 bits, since each `DmaSegment` is bigger than 64 bytes, // there's no more than `PAGE_SIZE` / 64 = 64 `DmaSegment`s in a `DmaPage`. @@ -160,7 +160,7 @@ impl DmaPage { }; Ok(Self { - storage: dma_stream, + storage: Arc::new(dma_stream), segment_size, allocated_segments: SpinLock::new(BitArray::ZERO), pool, @@ -218,7 +218,7 @@ impl HasDaddr for DmaPage { /// Each `DmaSegment`'s daddr must be aligned with its size. #[derive(Debug)] pub struct DmaSegment { - dma_stream: DmaStream, + dma_stream: Arc, start_addr: Daddr, size: usize, page: Weak, diff --git a/kernel/comps/virtio/src/device/block/device.rs b/kernel/comps/virtio/src/device/block/device.rs index a53e1a07f..a880cda9d 100644 --- a/kernel/comps/virtio/src/device/block/device.rs +++ b/kernel/comps/virtio/src/device/block/device.rs @@ -109,8 +109,8 @@ struct DeviceInner { features: VirtioBlockFeature, queue: SpinLock, transport: SpinLock>, - block_requests: DmaStream, - block_responses: DmaStream, + block_requests: Arc, + block_responses: Arc, id_allocator: SpinLock, submitted_requests: SpinLock>, } @@ -143,12 +143,12 @@ impl DeviceInner { .expect("create virtqueue failed"); let block_requests = { let segment = FrameAllocOptions::new().alloc_segment(1).unwrap(); - DmaStream::map(segment.into(), DmaDirection::Bidirectional, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::Bidirectional, false).unwrap()) }; assert!(Self::QUEUE_SIZE as usize * REQ_SIZE <= block_requests.size()); let block_responses = { let segment = FrameAllocOptions::new().alloc_segment(1).unwrap(); - DmaStream::map(segment.into(), DmaDirection::Bidirectional, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::Bidirectional, false).unwrap()) }; assert!(Self::QUEUE_SIZE as usize * RESP_SIZE <= block_responses.size()); @@ -268,7 +268,7 @@ impl DeviceInner { .zeroed(false) .alloc_segment(1) .unwrap(); - DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap()) }; let device_id_slice = Slice::new(&device_id_stream, 0..MAX_ID_LENGTH); let outputs = vec![&device_id_slice, &resp_slice]; diff --git a/kernel/comps/virtio/src/device/console/device.rs b/kernel/comps/virtio/src/device/console/device.rs index e1f73a607..0d5c1e2b8 100644 --- a/kernel/comps/virtio/src/device/console/device.rs +++ b/kernel/comps/virtio/src/device/console/device.rs @@ -24,8 +24,8 @@ pub struct ConsoleDevice { transport: SpinLock>, receive_queue: SpinLock, transmit_queue: SpinLock, - send_buffer: DmaStream, - receive_buffer: DmaStream, + send_buffer: Arc, + receive_buffer: Arc, #[expect(clippy::box_collection)] callbacks: Rcu>>, } @@ -99,12 +99,12 @@ impl ConsoleDevice { let send_buffer = { let segment = FrameAllocOptions::new().alloc_segment(1).unwrap(); - DmaStream::map(segment.into(), DmaDirection::ToDevice, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::ToDevice, false).unwrap()) }; let receive_buffer = { let segment = FrameAllocOptions::new().alloc_segment(1).unwrap(); - DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap() + Arc::new(DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap()) }; let device = Arc::new(Self { diff --git a/kernel/comps/virtio/src/device/input/device.rs b/kernel/comps/virtio/src/device/input/device.rs index 580148466..cc676f0d7 100644 --- a/kernel/comps/virtio/src/device/input/device.rs +++ b/kernel/comps/virtio/src/device/input/device.rs @@ -253,7 +253,7 @@ impl InputDevice { /// each of which is large enough to contain a `VirtioInputEvent`. #[derive(Debug)] struct EventTable { - stream: DmaStream, + stream: Arc, num_events: usize, } @@ -270,7 +270,8 @@ impl EventTable { .iter() .all(|b| *b == 0)); - let stream = DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap(); + let stream = + Arc::new(DmaStream::map(segment.into(), DmaDirection::FromDevice, false).unwrap()); Self { stream, num_events } } diff --git a/kernel/comps/virtio/src/device/network/device.rs b/kernel/comps/virtio/src/device/network/device.rs index 93904d4dc..cb46a533e 100644 --- a/kernel/comps/virtio/src/device/network/device.rs +++ b/kernel/comps/virtio/src/device/network/device.rs @@ -360,7 +360,7 @@ impl Debug for NetworkDevice { } } -static TX_BUFFER_POOL: SpinLock, BottomHalfDisabled> = +static TX_BUFFER_POOL: SpinLock>, BottomHalfDisabled> = SpinLock::new(LinkedList::new()); const QUEUE_RECV: u16 = 0; diff --git a/kernel/comps/virtio/src/device/socket/buffer.rs b/kernel/comps/virtio/src/device/socket/buffer.rs index 863a4e13e..c6c7bacd4 100644 --- a/kernel/comps/virtio/src/device/socket/buffer.rs +++ b/kernel/comps/virtio/src/device/socket/buffer.rs @@ -12,7 +12,8 @@ use spin::Once; const RX_BUFFER_LEN: usize = 4096; pub static RX_BUFFER_POOL: Once> = Once::new(); -pub static TX_BUFFER_POOL: Once, BottomHalfDisabled>> = Once::new(); +pub static TX_BUFFER_POOL: Once>, BottomHalfDisabled>> = + Once::new(); pub fn init() { const POOL_INIT_SIZE: usize = 32; diff --git a/kernel/comps/virtio/src/dma_buf.rs b/kernel/comps/virtio/src/dma_buf.rs index e5ac00555..29ba1f707 100644 --- a/kernel/comps/virtio/src/dma_buf.rs +++ b/kernel/comps/virtio/src/dma_buf.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 +use alloc::sync::Arc; + use aster_network::{DmaSegment, RxBuffer, TxBuffer}; use aster_util::mem_obj_slice::Slice; use ostd::mm::{DmaCoherent, DmaStream, HasDaddr, HasSize}; @@ -13,29 +15,34 @@ pub trait DmaBuf: HasDaddr { fn len(&self) -> usize; } -impl DmaBuf for DmaStream { - fn len(&self) -> usize { - self.size() - } +macro_rules! impl_dma_buf_for { + ($($t:ty),*) => { + $( + impl DmaBuf for $t { + fn len(&self) -> usize { + self.size() + } + } + + impl DmaBuf for Slice<$t> { + fn len(&self) -> usize { + self.size() + } + } + )* + }; } -impl DmaBuf for Slice { - fn len(&self) -> usize { - self.size() - } -} - -impl DmaBuf for Slice<&DmaStream> { - fn len(&self) -> usize { - self.size() - } -} - -impl DmaBuf for DmaCoherent { - fn len(&self) -> usize { - self.size() - } -} +impl_dma_buf_for!( + DmaStream, + &DmaStream, + Arc, + &Arc, + DmaCoherent, + &DmaCoherent, + Arc, + &Arc +); impl DmaBuf for DmaSegment { fn len(&self) -> usize { diff --git a/kernel/comps/virtio/src/queue.rs b/kernel/comps/virtio/src/queue.rs index 1c564c493..f56dd7696 100644 --- a/kernel/comps/virtio/src/queue.rs +++ b/kernel/comps/virtio/src/queue.rs @@ -2,7 +2,7 @@ //! Virtqueue -use alloc::vec::Vec; +use alloc::{sync::Arc, vec::Vec}; use core::{ mem::{offset_of, size_of}, sync::atomic::{fence, Ordering}, @@ -37,11 +37,11 @@ pub enum QueueError { #[derive(Debug)] pub struct VirtQueue { /// Descriptor table - descs: Vec>, + descs: Vec>>, /// Available ring - avail: SafePtr, + avail: SafePtr>, /// Used ring - used: SafePtr, + used: SafePtr>, /// Notify configuration manager notify_config: ConfigManager, @@ -98,13 +98,13 @@ impl VirtQueue { continue_segment.split(seg1_frames * align_size) }; - let desc_frame_ptr: SafePtr = - SafePtr::new(DmaCoherent::map(seg1.into(), true).unwrap(), 0); - let mut avail_frame_ptr: SafePtr = + let desc_frame_ptr: SafePtr> = + SafePtr::new(Arc::new(DmaCoherent::map(seg1.into(), true).unwrap()), 0); + let mut avail_frame_ptr: SafePtr> = desc_frame_ptr.clone().cast(); avail_frame_ptr.byte_add(desc_size); - let used_frame_ptr: SafePtr = - SafePtr::new(DmaCoherent::map(seg2.into(), true).unwrap(), 0); + let used_frame_ptr: SafePtr> = + SafePtr::new(Arc::new(DmaCoherent::map(seg2.into(), true).unwrap()), 0); (desc_frame_ptr, avail_frame_ptr, used_frame_ptr) } else { if size > 256 { @@ -112,27 +112,33 @@ impl VirtQueue { } ( SafePtr::new( - DmaCoherent::map( - FrameAllocOptions::new().alloc_segment(1).unwrap().into(), - true, - ) - .unwrap(), + Arc::new( + DmaCoherent::map( + FrameAllocOptions::new().alloc_segment(1).unwrap().into(), + true, + ) + .unwrap(), + ), 0, ), SafePtr::new( - DmaCoherent::map( - FrameAllocOptions::new().alloc_segment(1).unwrap().into(), - true, - ) - .unwrap(), + Arc::new( + DmaCoherent::map( + FrameAllocOptions::new().alloc_segment(1).unwrap().into(), + true, + ) + .unwrap(), + ), 0, ), SafePtr::new( - DmaCoherent::map( - FrameAllocOptions::new().alloc_segment(1).unwrap().into(), - true, - ) - .unwrap(), + Arc::new( + DmaCoherent::map( + FrameAllocOptions::new().alloc_segment(1).unwrap().into(), + true, + ) + .unwrap(), + ), 0, ), ) @@ -234,7 +240,7 @@ impl VirtQueue { let avail_slot = self.avail_idx & (self.queue_size - 1); { - let ring_ptr: SafePtr<[u16; 64], &DmaCoherent> = + let ring_ptr: SafePtr<[u16; 64], &Arc> = field_ptr!(&self.avail, AvailRing, ring); let mut ring_slot_ptr = ring_ptr.cast::(); ring_slot_ptr.add(avail_slot as usize); @@ -419,7 +425,7 @@ pub struct Descriptor { next: u16, } -type DescriptorPtr<'a> = SafePtr>; +type DescriptorPtr<'a> = SafePtr, TRightSet>; fn set_dma_buf(desc_ptr: &DescriptorPtr, buf: &T) { // TODO: skip the empty dma buffer or just return error? diff --git a/kernel/comps/virtio/src/transport/mmio/device.rs b/kernel/comps/virtio/src/transport/mmio/device.rs index 057bb7d81..c97696f82 100644 --- a/kernel/comps/virtio/src/transport/mmio/device.rs +++ b/kernel/comps/virtio/src/transport/mmio/device.rs @@ -98,9 +98,9 @@ impl VirtioTransport for VirtioMmioTransport { &mut self, idx: u16, queue_size: u16, - descriptor_ptr: &SafePtr, - driver_ptr: &SafePtr, - device_ptr: &SafePtr, + descriptor_ptr: &SafePtr>, + driver_ptr: &SafePtr>, + device_ptr: &SafePtr>, ) -> Result<(), VirtioTransportError> { field_ptr!(&self.layout, VirtioMmioLayout, queue_sel) .write_once(&(idx as u32)) diff --git a/kernel/comps/virtio/src/transport/mod.rs b/kernel/comps/virtio/src/transport/mod.rs index 0e4e388c1..b77606efe 100644 --- a/kernel/comps/virtio/src/transport/mod.rs +++ b/kernel/comps/virtio/src/transport/mod.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -use alloc::boxed::Box; +use alloc::{boxed::Box, sync::Arc}; use core::fmt::Debug; use aster_util::safe_ptr::SafePtr; @@ -73,9 +73,9 @@ pub trait VirtioTransport: Sync + Send + Debug { &mut self, idx: u16, queue_size: u16, - descriptor_ptr: &SafePtr, - avail_ring_ptr: &SafePtr, - used_ring_ptr: &SafePtr, + descriptor_ptr: &SafePtr>, + avail_ring_ptr: &SafePtr>, + used_ring_ptr: &SafePtr>, ) -> Result<(), VirtioTransportError>; /// The max queue size of one virtqueue. diff --git a/kernel/comps/virtio/src/transport/pci/device.rs b/kernel/comps/virtio/src/transport/pci/device.rs index a4b60bcae..522e23c35 100644 --- a/kernel/comps/virtio/src/transport/pci/device.rs +++ b/kernel/comps/virtio/src/transport/pci/device.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -use alloc::boxed::Box; +use alloc::{boxed::Box, sync::Arc}; use core::fmt::Debug; use aster_util::{field_ptr, safe_ptr::SafePtr}; @@ -77,9 +77,9 @@ impl VirtioTransport for VirtioPciModernTransport { &mut self, idx: u16, queue_size: u16, - descriptor_ptr: &SafePtr, - avail_ring_ptr: &SafePtr, - used_ring_ptr: &SafePtr, + descriptor_ptr: &SafePtr>, + avail_ring_ptr: &SafePtr>, + used_ring_ptr: &SafePtr>, ) -> Result<(), VirtioTransportError> { if idx >= self.num_queues() { return Err(VirtioTransportError::InvalidArgs); diff --git a/kernel/comps/virtio/src/transport/pci/legacy.rs b/kernel/comps/virtio/src/transport/pci/legacy.rs index fa8a8647b..27901afaf 100644 --- a/kernel/comps/virtio/src/transport/pci/legacy.rs +++ b/kernel/comps/virtio/src/transport/pci/legacy.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -use alloc::boxed::Box; +use alloc::{boxed::Box, sync::Arc}; use core::fmt::Debug; use aster_util::safe_ptr::SafePtr; @@ -163,9 +163,9 @@ impl VirtioTransport for VirtioPciLegacyTransport { &mut self, idx: u16, _queue_size: u16, - descriptor_ptr: &SafePtr, - _avail_ring_ptr: &SafePtr, - _used_ring_ptr: &SafePtr, + descriptor_ptr: &SafePtr>, + _avail_ring_ptr: &SafePtr>, + _used_ring_ptr: &SafePtr>, ) -> Result<(), VirtioTransportError> { // When using the legacy interface, there was no mechanism to negotiate // the queue size! The transitional driver MUST retrieve the `Queue Size` diff --git a/kernel/libs/aster-util/src/mem_obj_slice.rs b/kernel/libs/aster-util/src/mem_obj_slice.rs index 37908cbb2..48c67427f 100644 --- a/kernel/libs/aster-util/src/mem_obj_slice.rs +++ b/kernel/libs/aster-util/src/mem_obj_slice.rs @@ -10,6 +10,7 @@ //! [`IoMem`]: ostd::io::IoMem //! [`DmaStream`]: ostd::mm::dma::DmaStream +use alloc::sync::Arc; use core::{borrow::Borrow, fmt::Debug, ops::Range}; use ostd::mm::{ @@ -115,7 +116,8 @@ impl> HasVmRea } // A handy implementation for streaming DMA slice. -impl> Slice { +// TODO: Implement the `sync()` method also for `Slice`/`Slice<&DmaStream>`. +impl>> Slice { /// Synchronizes the slice of streaming DMA mapping with the device. /// /// The method will call [`DmaStream::sync`] with the offset range of this slice. diff --git a/ostd/src/mm/dma/dma_coherent.rs b/ostd/src/mm/dma/dma_coherent.rs index 389ed5518..060a5b215 100644 --- a/ostd/src/mm/dma/dma_coherent.rs +++ b/ostd/src/mm/dma/dma_coherent.rs @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -use alloc::sync::Arc; use core::ops::Deref; use cfg_if::cfg_if; @@ -29,13 +28,8 @@ cfg_if! { /// /// The mapping will be destroyed automatically when /// the object is dropped. -#[derive(Debug, Clone)] -pub struct DmaCoherent { - inner: Arc, -} - #[derive(Debug)] -struct DmaCoherentInner { +pub struct DmaCoherent { segment: USegment, start_daddr: Daddr, is_cache_coherent: bool, @@ -101,11 +95,9 @@ impl DmaCoherent { }; Ok(Self { - inner: Arc::new(DmaCoherentInner { - segment, - start_daddr, - is_cache_coherent, - }), + segment, + start_daddr, + is_cache_coherent, }) } } @@ -113,11 +105,11 @@ impl DmaCoherent { impl Deref for DmaCoherent { type Target = USegment; fn deref(&self) -> &Self::Target { - &self.inner.segment + &self.segment } } -impl Drop for DmaCoherentInner { +impl Drop for DmaCoherent { fn drop(&mut self) { let paddr = self.segment.paddr(); let frame_count = self.segment.size() / PAGE_SIZE; @@ -165,19 +157,19 @@ impl Drop for DmaCoherentInner { impl HasPaddr for DmaCoherent { fn paddr(&self) -> Paddr { - self.inner.segment.paddr() + self.segment.paddr() } } impl HasSize for DmaCoherent { fn size(&self) -> usize { - self.inner.segment.size() + self.segment.size() } } impl HasDaddr for DmaCoherent { fn daddr(&self) -> Daddr { - self.inner.start_daddr + self.start_daddr } } @@ -185,10 +177,10 @@ impl HasVmReaderWriter for DmaCoherent { type Types = VmReaderWriterIdentity; fn reader(&self) -> VmReader<'_, Infallible> { - self.inner.segment.reader() + self.segment.reader() } fn writer(&self) -> VmWriter<'_, Infallible> { - self.inner.segment.writer() + self.segment.writer() } } diff --git a/ostd/src/mm/dma/dma_stream.rs b/ostd/src/mm/dma/dma_stream.rs index df9489d19..4d43c9fd1 100644 --- a/ostd/src/mm/dma/dma_stream.rs +++ b/ostd/src/mm/dma/dma_stream.rs @@ -5,7 +5,6 @@ allow(unfulfilled_lint_expectations) )] -use alloc::sync::Arc; use core::ops::Range; use super::{check_and_insert_dma_mapping, remove_dma_mapping, DmaError}; @@ -19,18 +18,12 @@ use crate::{ }, }; -/// A streaming DMA mapping. Users must synchronize data -/// before reading or after writing to ensure consistency. +/// A streaming DMA mapping. /// -/// The mapping is automatically destroyed when this object -/// is dropped. -#[derive(Debug, Clone)] -pub struct DmaStream { - inner: Arc, -} - +/// Users must synchronize data before reading or after writing to ensure +/// consistency. #[derive(Debug)] -struct DmaStreamInner { +pub struct DmaStream { segment: USegment, start_daddr: Daddr, /// TODO: remove this field when on x86. @@ -97,12 +90,10 @@ impl DmaStream { }; Ok(Self { - inner: Arc::new(DmaStreamInner { - segment, - start_daddr, - is_cache_coherent, - direction, - }), + segment, + start_daddr, + is_cache_coherent, + direction, }) } @@ -113,12 +104,12 @@ impl DmaStream { /// there is a chance that the device is updating /// the memory. Do this at your own risk. pub fn segment(&self) -> &USegment { - &self.inner.segment + &self.segment } /// Returns the DMA direction. pub fn direction(&self) -> DmaDirection { - self.inner.direction + self.direction } /// Synchronizes the streaming DMA mapping with the device. @@ -142,10 +133,10 @@ impl DmaStream { if _byte_range.end > self.size() { return Err(Error::InvalidArgs); } - if self.inner.is_cache_coherent { + if self.is_cache_coherent { return Ok(()); } - let _start_va = crate::mm::paddr_to_vaddr(self.inner.segment.paddr()) as *const u8; + let _start_va = crate::mm::paddr_to_vaddr(self.segment.paddr()) as *const u8; // TODO: Query the CPU for the cache line size via CPUID, we use 64 bytes as the cache line size here. for _i in _byte_range.step_by(64) { // TODO: Call the cache line flush command in the corresponding architecture. @@ -159,11 +150,11 @@ impl DmaStream { impl HasDaddr for DmaStream { fn daddr(&self) -> Daddr { - self.inner.start_daddr + self.start_daddr } } -impl Drop for DmaStreamInner { +impl Drop for DmaStream { fn drop(&mut self) { let paddr = self.segment.paddr(); let frame_count = self.segment.size() / PAGE_SIZE; @@ -201,28 +192,28 @@ impl HasVmReaderWriter for DmaStream { type Types = VmReaderWriterResult; fn reader(&self) -> Result, Error> { - if self.inner.direction == DmaDirection::ToDevice { + if self.direction == DmaDirection::ToDevice { return Err(Error::AccessDenied); } - Ok(self.inner.segment.reader()) + Ok(self.segment.reader()) } fn writer(&self) -> Result, Error> { - if self.inner.direction == DmaDirection::FromDevice { + if self.direction == DmaDirection::FromDevice { return Err(Error::AccessDenied); } - Ok(self.inner.segment.writer()) + Ok(self.segment.writer()) } } impl HasPaddr for DmaStream { fn paddr(&self) -> Paddr { - self.inner.segment.paddr() + self.segment.paddr() } } impl HasSize for DmaStream { fn size(&self) -> usize { - self.inner.segment.size() + self.segment.size() } }