From d37da228ab3e8176163a84e7f90f28df7f963610 Mon Sep 17 00:00:00 2001 From: Shaowei Song Date: Wed, 20 Nov 2024 13:43:57 +0000 Subject: [PATCH] Improve flexibility of `DmaStreamSlice` --- .../comps/virtio/src/device/block/device.rs | 8 +- kernel/comps/virtio/src/dma_buf.rs | 2 +- ostd/src/mm/dma/dma_stream.rs | 89 +++++++++++++++---- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/kernel/comps/virtio/src/device/block/device.rs b/kernel/comps/virtio/src/device/block/device.rs index bffe95535..0731fc1c0 100644 --- a/kernel/comps/virtio/src/device/block/device.rs +++ b/kernel/comps/virtio/src/device/block/device.rs @@ -322,12 +322,12 @@ impl DeviceInner { resp_slice }; - let dma_slices: Vec = dma_streams + let dma_slices: Vec> = dma_streams .iter() .map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len)) .collect(); let outputs = { - let mut outputs: Vec<&DmaStreamSlice> = Vec::with_capacity(dma_streams.len() + 1); + let mut outputs: Vec<&DmaStreamSlice<_>> = Vec::with_capacity(dma_streams.len() + 1); outputs.extend(dma_slices.iter()); outputs.push(&resp_slice); outputs @@ -384,12 +384,12 @@ impl DeviceInner { resp_slice }; - let dma_slices: Vec = dma_streams + let dma_slices: Vec> = dma_streams .iter() .map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len)) .collect(); let inputs = { - let mut inputs: Vec<&DmaStreamSlice> = Vec::with_capacity(dma_streams.len() + 1); + let mut inputs: Vec<&DmaStreamSlice<_>> = Vec::with_capacity(dma_streams.len() + 1); inputs.push(&req_slice); inputs.extend(dma_slices.iter()); inputs diff --git a/kernel/comps/virtio/src/dma_buf.rs b/kernel/comps/virtio/src/dma_buf.rs index e0dc5586a..8a52413d5 100644 --- a/kernel/comps/virtio/src/dma_buf.rs +++ b/kernel/comps/virtio/src/dma_buf.rs @@ -19,7 +19,7 @@ impl DmaBuf for DmaStream { } } -impl DmaBuf for DmaStreamSlice<'_> { +impl> DmaBuf for DmaStreamSlice { fn len(&self) -> usize { self.nbytes() } diff --git a/ostd/src/mm/dma/dma_stream.rs b/ostd/src/mm/dma/dma_stream.rs index c439ce310..464d64ce8 100644 --- a/ostd/src/mm/dma/dma_stream.rs +++ b/ostd/src/mm/dma/dma_stream.rs @@ -48,7 +48,7 @@ struct DmaStreamInner { pub enum DmaDirection { /// Data flows to the device ToDevice, - /// Data flows form the device + /// Data flows from the device FromDevice, /// Data flows both from and to the device Bidirectional, @@ -117,16 +117,21 @@ impl DmaStream { &self.inner.vm_segment } - /// Returns the number of frames + /// Returns the number of frames. pub fn nframes(&self) -> usize { self.inner.vm_segment.nbytes() / PAGE_SIZE } - /// Returns the number of bytes + /// Returns the number of bytes. pub fn nbytes(&self) -> usize { self.inner.vm_segment.nbytes() } + /// Returns the DMA direction. + pub fn direction(&self) -> DmaDirection { + self.inner.direction + } + /// Synchronizes the streaming DMA mapping with the device. /// /// This method should be called under one of the two conditions: @@ -242,15 +247,21 @@ impl HasPaddr for DmaStream { } } +impl AsRef for DmaStream { + fn as_ref(&self) -> &DmaStream { + self + } +} + /// A slice of streaming DMA mapping. #[derive(Debug)] -pub struct DmaStreamSlice<'a> { - stream: &'a DmaStream, +pub struct DmaStreamSlice { + stream: Dma, offset: usize, len: usize, } -impl<'a> DmaStreamSlice<'a> { +impl> DmaStreamSlice { /// Constructs a `DmaStreamSlice` from the [`DmaStream`]. /// /// # Panics @@ -259,9 +270,9 @@ impl<'a> DmaStreamSlice<'a> { /// this method will panic. /// If the `offset + len` is greater than the length of the stream, /// this method will panic. - pub fn new(stream: &'a DmaStream, offset: usize, len: usize) -> Self { - assert!(offset < stream.nbytes()); - assert!(offset + len <= stream.nbytes()); + pub fn new(stream: Dma, offset: usize, len: usize) -> Self { + assert!(offset < stream.as_ref().nbytes()); + assert!(offset + len <= stream.as_ref().nbytes()); Self { stream, @@ -270,6 +281,16 @@ impl<'a> DmaStreamSlice<'a> { } } + /// Returns the underlying `DmaStream`. + pub fn stream(&self) -> &DmaStream { + self.stream.as_ref() + } + + /// Returns the offset of the slice. + pub fn offset(&self) -> usize { + self.offset + } + /// Returns the number of bytes. pub fn nbytes(&self) -> usize { self.len @@ -277,35 +298,69 @@ impl<'a> DmaStreamSlice<'a> { /// Synchronizes the slice of streaming DMA mapping with the device. pub fn sync(&self) -> Result<(), Error> { - self.stream.sync(self.offset..self.offset + self.len) + self.stream + .as_ref() + .sync(self.offset..self.offset + self.len) + } + + /// Returns a reader to read data from it. + pub fn reader(&self) -> Result, Error> { + let stream_reader = self + .stream + .as_ref() + .reader()? + .skip(self.offset) + .limit(self.len); + Ok(stream_reader) + } + + /// Returns a writer to write data into it. + pub fn writer(&self) -> Result, Error> { + let stream_writer = self + .stream + .as_ref() + .writer()? + .skip(self.offset) + .limit(self.len); + Ok(stream_writer) } } -impl VmIo for DmaStreamSlice<'_> { +impl + Send + Sync> VmIo for DmaStreamSlice { fn read(&self, offset: usize, writer: &mut VmWriter) -> Result<(), Error> { if writer.avail() + offset > self.len { return Err(Error::InvalidArgs); } - self.stream.read(self.offset + offset, writer) + self.stream.as_ref().read(self.offset + offset, writer) } fn write(&self, offset: usize, reader: &mut VmReader) -> Result<(), Error> { if reader.remain() + offset > self.len { return Err(Error::InvalidArgs); } - self.stream.write(self.offset + offset, reader) + self.stream.as_ref().write(self.offset + offset, reader) } } -impl HasDaddr for DmaStreamSlice<'_> { +impl> HasDaddr for DmaStreamSlice { fn daddr(&self) -> Daddr { - self.stream.daddr() + self.offset + self.stream.as_ref().daddr() + self.offset } } -impl HasPaddr for DmaStreamSlice<'_> { +impl> HasPaddr for DmaStreamSlice { fn paddr(&self) -> Paddr { - self.stream.paddr() + self.offset + self.stream.as_ref().paddr() + self.offset + } +} + +impl Clone for DmaStreamSlice { + fn clone(&self) -> Self { + Self { + stream: self.stream.clone(), + offset: self.offset, + len: self.len, + } } }