* [PATCH v6 1/2] rust: error: Add EOVERFLOW
@ 2024-12-05 11:32 Abdiel Janulgue
2024-12-05 11:32 ` [PATCH v6 2/2] rust: add dma coherent allocator abstraction Abdiel Janulgue
0 siblings, 1 reply; 6+ messages in thread
From: Abdiel Janulgue @ 2024-12-05 11:32 UTC (permalink / raw)
To: daniel.almeida
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, Robin Murphy,
airlied, open list:DMA MAPPING HELPERS, Abdiel Janulgue
Trivial addition for missing EOVERFLOW error. This is used by a
subsequent patch that might require returning EOVERFLOW as a result
of `checked_mul`.
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@gmail.com>
---
rust/kernel/error.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
index 52c502432447..cd57fac7f1f9 100644
--- a/rust/kernel/error.rs
+++ b/rust/kernel/error.rs
@@ -63,6 +63,7 @@ macro_rules! declare_err {
declare_err!(EPIPE, "Broken pipe.");
declare_err!(EDOM, "Math argument out of domain of func.");
declare_err!(ERANGE, "Math result not representable.");
+ declare_err!(EOVERFLOW, "Value too large for defined data type.");
declare_err!(ERESTARTSYS, "Restart the system call.");
declare_err!(ERESTARTNOINTR, "System call was interrupted by a signal and will be restarted.");
declare_err!(ERESTARTNOHAND, "Restart if no handler.");
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v6 2/2] rust: add dma coherent allocator abstraction.
2024-12-05 11:32 [PATCH v6 1/2] rust: error: Add EOVERFLOW Abdiel Janulgue
@ 2024-12-05 11:32 ` Abdiel Janulgue
2024-12-05 13:07 ` Robin Murphy
0 siblings, 1 reply; 6+ messages in thread
From: Abdiel Janulgue @ 2024-12-05 11:32 UTC (permalink / raw)
To: daniel.almeida
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, Robin Murphy,
airlied, open list:DMA MAPPING HELPERS, Abdiel Janulgue
Add a simple dma coherent allocator rust abstraction. Based on
Andreas Hindborg's dma abstractions from the rnvme driver, which
was also based on earlier work by Wedson Almeida Filho.
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Tested-by: Daniel Almeida <daniel.almeida@collabora.com>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@gmail.com>
---
rust/bindings/bindings_helper.h | 1 +
rust/kernel/dma.rs | 136 ++++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
3 files changed, 138 insertions(+)
create mode 100644 rust/kernel/dma.rs
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 5c4dfe22f41a..49bf713b9bb6 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -11,6 +11,7 @@
#include <linux/blk_types.h>
#include <linux/blkdev.h>
#include <linux/cred.h>
+#include <linux/dma-mapping.h>
#include <linux/errname.h>
#include <linux/ethtool.h>
#include <linux/file.h>
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
new file mode 100644
index 000000000000..dd725c571ff7
--- /dev/null
+++ b/rust/kernel/dma.rs
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Direct memory access (DMA).
+//!
+//! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-mapping.h)
+
+use crate::{
+ bindings,
+ build_assert,
+ device::Device,
+ error::code::*,
+ error::Result,
+ types::ARef,
+ transmute::{AsBytes, FromBytes},
+};
+
+/// An abstraction of the `dma_alloc_coherent` API.
+///
+/// This is an abstraction around the `dma_alloc_coherent` API which is used to allocate and map
+/// large consistent DMA regions.
+///
+/// A [`CoherentAllocation`] instance contains a pointer to the allocated region (in the
+/// processor's virtual address space) and the device address which can be given to the device
+/// as the DMA address base of the region. The region is released once [`CoherentAllocation`]
+/// is dropped.
+///
+/// # Invariants
+///
+/// For the lifetime of an instance of [`CoherentAllocation`], the cpu address is a valid pointer
+/// to an allocated region of consistent memory and we hold a reference to the device.
+pub struct CoherentAllocation<T: AsBytes + FromBytes> {
+ dev: ARef<Device>,
+ dma_handle: bindings::dma_addr_t,
+ count: usize,
+ cpu_addr: *mut T,
+}
+
+impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
+ /// Allocates a region of `size_of::<T> * count` of consistent memory.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::device::Device;
+ /// use kernel::dma::CoherentAllocation;
+ ///
+ /// # fn test(dev: &Device) -> Result {
+ /// let c: CoherentAllocation<u64> = CoherentAllocation::alloc_coherent(dev, 4, GFP_KERNEL)?;
+ /// # Ok::<(), Error>(()) }
+ /// ```
+ pub fn alloc_coherent(
+ dev: &Device,
+ count: usize,
+ flags: kernel::alloc::Flags,
+ ) -> Result<CoherentAllocation<T>> {
+ build_assert!(core::mem::size_of::<T>() > 0,
+ "It doesn't make sense for the allocated type to be a ZST");
+
+ let size = count.checked_mul(core::mem::size_of::<T>()).ok_or(EOVERFLOW)?;
+ let mut dma_handle = 0;
+ // SAFETY: device pointer is guaranteed as valid by invariant on `Device`.
+ // We ensure that we catch the failure on this function and throw an ENOMEM
+ let ret = unsafe {
+ bindings::dma_alloc_attrs(
+ dev.as_raw(),
+ size,
+ &mut dma_handle, flags.as_raw(),
+ 0,
+ )
+ };
+ if ret.is_null() {
+ return Err(ENOMEM)
+ }
+ // INVARIANT: We just successfully allocated a coherent region which is accessible for
+ // `count` elements, hence the cpu address is valid. We also hold a refcounted reference
+ // to the device.
+ Ok(Self {
+ dev: dev.into(),
+ dma_handle,
+ count,
+ cpu_addr: ret as *mut T,
+ })
+ }
+
+ /// Returns the base address to the allocated region and the dma handle. The caller takes
+ /// ownership of the returned resources.
+ pub fn into_parts(self) -> (usize, bindings::dma_addr_t) {
+ let ret = (self.cpu_addr as _, self.dma_handle);
+ core::mem::forget(self);
+ ret
+ }
+
+ /// Returns the base address to the allocated region in the CPU's virtual address space.
+ pub fn start_ptr(&self) -> *const T {
+ self.cpu_addr as _
+ }
+
+ /// Returns the base address to the allocated region in the CPU's virtual address space as
+ /// a mutable pointer.
+ pub fn start_ptr_mut(&mut self) -> *mut T {
+ self.cpu_addr
+ }
+
+ /// Returns a DMA handle which may given to the device as the DMA address base of
+ /// the region.
+ pub fn dma_handle(&self) -> bindings::dma_addr_t {
+ self.dma_handle
+ }
+
+ /// Returns the CPU-addressable region as a slice.
+ pub fn cpu_buf(&self) -> &[T]
+ {
+ // SAFETY: The pointer is valid due to type invariant on `CoherentAllocation` and
+ // is valid for reads for `self.count * size_of::<T>` bytes.
+ unsafe { core::slice::from_raw_parts(self.cpu_addr, self.count) }
+ }
+
+ /// Performs the same functionality as `cpu_buf`, except that a mutable slice is returned.
+ pub fn cpu_buf_mut(&mut self) -> &mut [T]
+ {
+ // SAFETY: The pointer is valid due to type invariant on `CoherentAllocation` and
+ // is valid for reads for `self.count * size_of::<T>` bytes.
+ unsafe { core::slice::from_raw_parts_mut(self.cpu_addr, self.count) }
+ }
+}
+
+impl<T: AsBytes + FromBytes> Drop for CoherentAllocation<T> {
+ fn drop(&mut self) {
+ let size = self.count * core::mem::size_of::<T>();
+ // SAFETY: the device, cpu address, and the dma handle is valid due to the
+ // type invariants on `CoherentAllocation`.
+ unsafe { bindings::dma_free_attrs(self.dev.as_raw(), size,
+ self.cpu_addr as _,
+ self.dma_handle, 0) }
+ }
+}
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index e1065a7551a3..6e90ebf5a130 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -35,6 +35,7 @@
mod build_assert;
pub mod cred;
pub mod device;
+pub mod dma;
pub mod error;
#[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
pub mod firmware;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v6 2/2] rust: add dma coherent allocator abstraction.
2024-12-05 11:32 ` [PATCH v6 2/2] rust: add dma coherent allocator abstraction Abdiel Janulgue
@ 2024-12-05 13:07 ` Robin Murphy
2024-12-05 14:25 ` Abdiel Janulgue
0 siblings, 1 reply; 6+ messages in thread
From: Robin Murphy @ 2024-12-05 13:07 UTC (permalink / raw)
To: Abdiel Janulgue, daniel.almeida
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, airlied,
open list:DMA MAPPING HELPERS
On 05/12/2024 11:32 am, Abdiel Janulgue wrote:
> Add a simple dma coherent allocator rust abstraction. Based on
> Andreas Hindborg's dma abstractions from the rnvme driver, which
> was also based on earlier work by Wedson Almeida Filho.
>
> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
> Tested-by: Daniel Almeida <daniel.almeida@collabora.com>
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@gmail.com>
> ---
> rust/bindings/bindings_helper.h | 1 +
> rust/kernel/dma.rs | 136 ++++++++++++++++++++++++++++++++
> rust/kernel/lib.rs | 1 +
> 3 files changed, 138 insertions(+)
> create mode 100644 rust/kernel/dma.rs
>
> diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
> index 5c4dfe22f41a..49bf713b9bb6 100644
> --- a/rust/bindings/bindings_helper.h
> +++ b/rust/bindings/bindings_helper.h
> @@ -11,6 +11,7 @@
> #include <linux/blk_types.h>
> #include <linux/blkdev.h>
> #include <linux/cred.h>
> +#include <linux/dma-mapping.h>
> #include <linux/errname.h>
> #include <linux/ethtool.h>
> #include <linux/file.h>
> diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
> new file mode 100644
> index 000000000000..dd725c571ff7
> --- /dev/null
> +++ b/rust/kernel/dma.rs
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Direct memory access (DMA).
> +//!
> +//! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-mapping.h)
> +
> +use crate::{
> + bindings,
> + build_assert,
> + device::Device,
> + error::code::*,
> + error::Result,
> + types::ARef,
> + transmute::{AsBytes, FromBytes},
> +};
> +
> +/// An abstraction of the `dma_alloc_coherent` API.
> +///
> +/// This is an abstraction around the `dma_alloc_coherent` API which is used to allocate and map
> +/// large consistent DMA regions.
> +///
> +/// A [`CoherentAllocation`] instance contains a pointer to the allocated region (in the
> +/// processor's virtual address space) and the device address which can be given to the device
> +/// as the DMA address base of the region. The region is released once [`CoherentAllocation`]
> +/// is dropped.
> +///
> +/// # Invariants
> +///
> +/// For the lifetime of an instance of [`CoherentAllocation`], the cpu address is a valid pointer
> +/// to an allocated region of consistent memory and we hold a reference to the device.
> +pub struct CoherentAllocation<T: AsBytes + FromBytes> {
> + dev: ARef<Device>,
> + dma_handle: bindings::dma_addr_t,
> + count: usize,
> + cpu_addr: *mut T,
> +}
> +
> +impl<T: AsBytes + FromBytes> CoherentAllocation<T> {
> + /// Allocates a region of `size_of::<T> * count` of consistent memory.
> + ///
> + /// # Examples
> + ///
> + /// ```
> + /// use kernel::device::Device;
> + /// use kernel::dma::CoherentAllocation;
> + ///
> + /// # fn test(dev: &Device) -> Result {
> + /// let c: CoherentAllocation<u64> = CoherentAllocation::alloc_coherent(dev, 4, GFP_KERNEL)?;
> + /// # Ok::<(), Error>(()) }
> + /// ```
> + pub fn alloc_coherent(
> + dev: &Device,
> + count: usize,
> + flags: kernel::alloc::Flags,
Might it be worth adding at least a placeholder type and argument for
"attrs" as well, so there's less churn involved in coming back and
adding it later? Or is the intention to have a separate
dma_alloc_attrs() constructor for such users?
(I assume adding an mmap method as and when needed won't affect any
existing users, so is fine not to worry about right now)
Thanks,
Robin.
> + ) -> Result<CoherentAllocation<T>> {
> + build_assert!(core::mem::size_of::<T>() > 0,
> + "It doesn't make sense for the allocated type to be a ZST");
> +
> + let size = count.checked_mul(core::mem::size_of::<T>()).ok_or(EOVERFLOW)?;
> + let mut dma_handle = 0;
> + // SAFETY: device pointer is guaranteed as valid by invariant on `Device`.
> + // We ensure that we catch the failure on this function and throw an ENOMEM
> + let ret = unsafe {
> + bindings::dma_alloc_attrs(
> + dev.as_raw(),
> + size,
> + &mut dma_handle, flags.as_raw(),
> + 0,
> + )
> + };
> + if ret.is_null() {
> + return Err(ENOMEM)
> + }
> + // INVARIANT: We just successfully allocated a coherent region which is accessible for
> + // `count` elements, hence the cpu address is valid. We also hold a refcounted reference
> + // to the device.
> + Ok(Self {
> + dev: dev.into(),
> + dma_handle,
> + count,
> + cpu_addr: ret as *mut T,
> + })
> + }
> +
> + /// Returns the base address to the allocated region and the dma handle. The caller takes
> + /// ownership of the returned resources.
> + pub fn into_parts(self) -> (usize, bindings::dma_addr_t) {
> + let ret = (self.cpu_addr as _, self.dma_handle);
> + core::mem::forget(self);
> + ret
> + }
> +
> + /// Returns the base address to the allocated region in the CPU's virtual address space.
> + pub fn start_ptr(&self) -> *const T {
> + self.cpu_addr as _
> + }
> +
> + /// Returns the base address to the allocated region in the CPU's virtual address space as
> + /// a mutable pointer.
> + pub fn start_ptr_mut(&mut self) -> *mut T {
> + self.cpu_addr
> + }
> +
> + /// Returns a DMA handle which may given to the device as the DMA address base of
> + /// the region.
> + pub fn dma_handle(&self) -> bindings::dma_addr_t {
> + self.dma_handle
> + }
> +
> + /// Returns the CPU-addressable region as a slice.
> + pub fn cpu_buf(&self) -> &[T]
> + {
> + // SAFETY: The pointer is valid due to type invariant on `CoherentAllocation` and
> + // is valid for reads for `self.count * size_of::<T>` bytes.
> + unsafe { core::slice::from_raw_parts(self.cpu_addr, self.count) }
> + }
> +
> + /// Performs the same functionality as `cpu_buf`, except that a mutable slice is returned.
> + pub fn cpu_buf_mut(&mut self) -> &mut [T]
> + {
> + // SAFETY: The pointer is valid due to type invariant on `CoherentAllocation` and
> + // is valid for reads for `self.count * size_of::<T>` bytes.
> + unsafe { core::slice::from_raw_parts_mut(self.cpu_addr, self.count) }
> + }
> +}
> +
> +impl<T: AsBytes + FromBytes> Drop for CoherentAllocation<T> {
> + fn drop(&mut self) {
> + let size = self.count * core::mem::size_of::<T>();
> + // SAFETY: the device, cpu address, and the dma handle is valid due to the
> + // type invariants on `CoherentAllocation`.
> + unsafe { bindings::dma_free_attrs(self.dev.as_raw(), size,
> + self.cpu_addr as _,
> + self.dma_handle, 0) }
> + }
> +}
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index e1065a7551a3..6e90ebf5a130 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -35,6 +35,7 @@
> mod build_assert;
> pub mod cred;
> pub mod device;
> +pub mod dma;
> pub mod error;
> #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
> pub mod firmware;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v6 2/2] rust: add dma coherent allocator abstraction.
2024-12-05 13:07 ` Robin Murphy
@ 2024-12-05 14:25 ` Abdiel Janulgue
2024-12-05 16:41 ` Daniel Almeida
0 siblings, 1 reply; 6+ messages in thread
From: Abdiel Janulgue @ 2024-12-05 14:25 UTC (permalink / raw)
To: Robin Murphy, daniel.almeida
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, airlied,
open list:DMA MAPPING HELPERS
On 05/12/2024 15:07, Robin Murphy wrote:
>> + pub fn alloc_coherent(
>> + dev: &Device,
>> + count: usize,
>> + flags: kernel::alloc::Flags,
>
> Might it be worth adding at least a placeholder type and argument for
> "attrs" as well, so there's less churn involved in coming back and
> adding it later? Or is the intention to have a separate
> dma_alloc_attrs() constructor for such users?
>
It certainly is possible to include attrs in the constructor using Option:
```
pub fn alloc_coherent(
dev: &Device,
count: usize,
flags: kernel::alloc::Flags,
attrs: Option<u64>,
) -> Result<CoherentAllocation<T>> {
<cut>
let ret = unsafe {
bindings::dma_alloc_attrs(
dev.as_raw(),
size,
&mut dma_handle, flags.as_raw(),
attrs.unwrap_or(0),
)
};
<cut>
}
```
So the signature of the constructor could be:
let c = CoherentAllocation::alloc_coherent(dev, 4, GFP_KERNEL, None)?;
Andreas, Miguel, Daniel, any thoughts?
Regards,
Abdiel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v6 2/2] rust: add dma coherent allocator abstraction.
2024-12-05 14:25 ` Abdiel Janulgue
@ 2024-12-05 16:41 ` Daniel Almeida
2024-12-05 16:47 ` Robin Murphy
0 siblings, 1 reply; 6+ messages in thread
From: Daniel Almeida @ 2024-12-05 16:41 UTC (permalink / raw)
To: Abdiel Janulgue
Cc: Robin Murphy, Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, airlied,
open list:DMA MAPPING HELPERS
Hi Abdiel,
> On 5 Dec 2024, at 11:25, Abdiel Janulgue <abdiel.janulgue@gmail.com> wrote:
>
> On 05/12/2024 15:07, Robin Murphy wrote:
>>> + pub fn alloc_coherent(
>>> + dev: &Device,
>>> + count: usize,
>>> + flags: kernel::alloc::Flags,
>> Might it be worth adding at least a placeholder type and argument for "attrs" as well, so there's less churn involved in coming back and adding it later? Or is the intention to have a separate dma_alloc_attrs() constructor for such users?
>
> It certainly is possible to include attrs in the constructor using Option:
> ```
> pub fn alloc_coherent(
> dev: &Device,
> count: usize,
> flags: kernel::alloc::Flags,
> attrs: Option<u64>,
> ) -> Result<CoherentAllocation<T>> {
>
> <cut>
> let ret = unsafe {
> bindings::dma_alloc_attrs(
> dev.as_raw(),
> size,
> &mut dma_handle, flags.as_raw(),
> attrs.unwrap_or(0),
> )
> };
> <cut>
> }
>
> ```
> So the signature of the constructor could be:
>
> let c = CoherentAllocation::alloc_coherent(dev, 4, GFP_KERNEL, None)?;
>
> Andreas, Miguel, Daniel, any thoughts?
>
> Regards,
> Abdiel
>
Instead of a raw u64, you should take inspiration from the work in the Alloc crate and elsewhere to define
a proper `flags` type, which you can name `attr` in this case.
— Daniel
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v6 2/2] rust: add dma coherent allocator abstraction.
2024-12-05 16:41 ` Daniel Almeida
@ 2024-12-05 16:47 ` Robin Murphy
0 siblings, 0 replies; 6+ messages in thread
From: Robin Murphy @ 2024-12-05 16:47 UTC (permalink / raw)
To: Daniel Almeida, Abdiel Janulgue
Cc: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Valentin Obst, open list:RUST,
open list, Christoph Hellwig, Marek Szyprowski, airlied,
open list:DMA MAPPING HELPERS
On 05/12/2024 4:41 pm, Daniel Almeida wrote:
> Hi Abdiel,
>
>> On 5 Dec 2024, at 11:25, Abdiel Janulgue <abdiel.janulgue@gmail.com> wrote:
>>
>> On 05/12/2024 15:07, Robin Murphy wrote:
>>>> + pub fn alloc_coherent(
>>>> + dev: &Device,
>>>> + count: usize,
>>>> + flags: kernel::alloc::Flags,
>>> Might it be worth adding at least a placeholder type and argument for "attrs" as well, so there's less churn involved in coming back and adding it later? Or is the intention to have a separate dma_alloc_attrs() constructor for such users?
>>
>> It certainly is possible to include attrs in the constructor using Option:
>> ```
>> pub fn alloc_coherent(
>> dev: &Device,
>> count: usize,
>> flags: kernel::alloc::Flags,
>> attrs: Option<u64>,
>> ) -> Result<CoherentAllocation<T>> {
>>
>> <cut>
>> let ret = unsafe {
>> bindings::dma_alloc_attrs(
>> dev.as_raw(),
>> size,
>> &mut dma_handle, flags.as_raw(),
>> attrs.unwrap_or(0),
Note that you'd also want to store the attrs in the CoherentAllocation
itself, since they must be passed to the free and (eventually) mmap
calls too.
>> )
>> };
>> <cut>
>> }
>>
>> ```
>> So the signature of the constructor could be:
>>
>> let c = CoherentAllocation::alloc_coherent(dev, 4, GFP_KERNEL, None)?;
>>
>> Andreas, Miguel, Daniel, any thoughts?
>>
>> Regards,
>> Abdiel
>>
>
> Instead of a raw u64, you should take inspiration from the work in the Alloc crate and elsewhere to define
> a proper `flags` type, which you can name `attr` in this case.
Indeed, some type-checking would be rather neat, especially given that
there are actually different sets of DMA attributes which apply to the
coherent vs. streaming APIs (and no, that isn't very well documented...)
Thanks,
Robin.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-12-05 16:47 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-05 11:32 [PATCH v6 1/2] rust: error: Add EOVERFLOW Abdiel Janulgue
2024-12-05 11:32 ` [PATCH v6 2/2] rust: add dma coherent allocator abstraction Abdiel Janulgue
2024-12-05 13:07 ` Robin Murphy
2024-12-05 14:25 ` Abdiel Janulgue
2024-12-05 16:41 ` Daniel Almeida
2024-12-05 16:47 ` Robin Murphy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox