Skip to main content

DmaHandle

Struct DmaHandle 

Source
pub struct DmaHandle { /* private fields */ }
Expand description

Handle for DMA memory allocation.

Manages DMA memory buffers that may require special alignment or DMA address mask constraints. When the original virtual address doesn’t meet alignment or mask requirements, an additional aligned buffer is allocated and stored in alloc_virt.

Implementations§

Source§

impl DmaHandle

Source

pub unsafe fn new( cpu_addr: NonNull<u8>, dma_addr: DmaAddr, layout: Layout, ) -> Self

alloc_coherent 操作创建 DmaHandle

此构造函数专门用于 DMA 一致性内存分配场景,其中:

  • 内存是专门为 DMA 分配的(零初始化)
  • CPU 和设备看到同一个虚拟地址
  • 不需要额外的对齐缓冲区
§特性保证
  • 内存已被零初始化
§Safety

调用者必须确保:

  • origin_virt 指向有效内存,生命周期与 handle 相同
  • dma_addr 是与 origin_virt 对应的设备可访问地址
  • layout 正确描述内存的大小和对齐
  • 内存必须保持有效直到被正确释放
Source

pub fn size(&self) -> usize

Returns the size of the DMA buffer in bytes.

Source

pub fn align(&self) -> usize

Returns the alignment requirement of the DMA buffer in bytes.

Source

pub fn as_ptr(&self) -> NonNull<u8>

Returns the virtual address to access data.

Source

pub fn dma_addr(&self) -> DmaAddr

Returns the DMA address visible to devices.

Source

pub fn layout(&self) -> Layout

Returns the memory layout used for this DMA allocation.

Methods from Deref<Target = Layout>§

1.28.0 · Source

pub fn size(&self) -> usize

The minimum size in bytes for a memory block of this layout.

1.28.0 · Source

pub fn align(&self) -> usize

The minimum byte alignment for a memory block of this layout.

The returned alignment is guaranteed to be a power of two.

Source

pub fn alignment(&self) -> Alignment

🔬This is a nightly-only experimental API. (ptr_alignment_type)

The minimum byte alignment for a memory block of this layout.

The returned alignment is guaranteed to be a power of two.

1.95.0 · Source

pub fn dangling_ptr(&self) -> NonNull<u8>

Creates a NonNull that is dangling, but well-aligned for this Layout.

Note that the address of the returned pointer may potentially be that of a valid pointer, which means this must not be used as a “not yet initialized” sentinel value. Types that lazily allocate must track initialization by some other means.

1.44.0 · Source

pub fn align_to(&self, align: usize) -> Result<Layout, LayoutError>

Creates a layout describing the record that can hold a value of the same layout as self, but that also is aligned to alignment align (measured in bytes).

If self already meets the prescribed alignment, then returns self.

Note that this method does not add any padding to the overall size, regardless of whether the returned layout has a different alignment. In other words, if K has size 16, K.align_to(32) will still have size 16.

Returns an error if the combination of self.size() and the given align violates the conditions listed in Layout::from_size_align.

Source

pub fn adjust_alignment_to( &self, alignment: Alignment, ) -> Result<Layout, LayoutError>

🔬This is a nightly-only experimental API. (ptr_alignment_type)

Creates a layout describing the record that can hold a value of the same layout as self, but that also is aligned to alignment alignment.

If self already meets the prescribed alignment, then returns self.

Note that this method does not add any padding to the overall size, regardless of whether the returned layout has a different alignment. In other words, if K has size 16, K.align_to(32) will still have size 16.

Returns an error if the combination of self.size() and the given alignment violates the conditions listed in Layout::from_size_alignment.

Source

pub fn padding_needed_for(&self, alignment: Alignment) -> usize

🔬This is a nightly-only experimental API. (ptr_alignment_type)

Returns the amount of padding we must insert after self to ensure that the following address will satisfy alignment.

e.g., if self.size() is 9, then self.padding_needed_for(alignment4) (where alignment4.as_usize() == 4) returns 3, because that is the minimum number of bytes of padding required to get a 4-aligned address (assuming that the corresponding memory block starts at a 4-aligned address).

Note that the utility of the returned value requires alignment to be less than or equal to the alignment of the starting address for the whole allocated block of memory. One way to satisfy this constraint is to ensure alignment.as_usize() <= self.align().

1.44.0 · Source

pub fn pad_to_align(&self) -> Layout

Creates a layout by rounding the size of this layout up to a multiple of the layout’s alignment.

This is equivalent to adding the result of padding_needed_for to the layout’s current size.

1.95.0 · Source

pub fn repeat(&self, n: usize) -> Result<(Layout, usize), LayoutError>

Creates a layout describing the record for n instances of self, with a suitable amount of padding between each to ensure that each instance is given its requested size and alignment. On success, returns (k, offs) where k is the layout of the array and offs is the distance between the start of each element in the array.

Does not include padding after the trailing element.

(That distance between elements is sometimes known as “stride”.)

On arithmetic overflow, returns LayoutError.

§Examples
use std::alloc::Layout;

// All rust types have a size that's a multiple of their alignment.
let normal = Layout::from_size_align(12, 4).unwrap();
let repeated = normal.repeat(3).unwrap();
assert_eq!(repeated, (Layout::from_size_align(36, 4).unwrap(), 12));

// But you can manually make layouts which don't meet that rule.
let padding_needed = Layout::from_size_align(6, 4).unwrap();
let repeated = padding_needed.repeat(3).unwrap();
assert_eq!(repeated, (Layout::from_size_align(22, 4).unwrap(), 8));

// Repeating an element zero times has zero size, but keeps the alignment (like `[T; 0]`)
let repeated = normal.repeat(0).unwrap();
assert_eq!(repeated, (Layout::from_size_align(0, 4).unwrap(), 12));
let repeated = padding_needed.repeat(0).unwrap();
assert_eq!(repeated, (Layout::from_size_align(0, 4).unwrap(), 8));
1.44.0 · Source

pub fn extend(&self, next: Layout) -> Result<(Layout, usize), LayoutError>

Creates a layout describing the record for self followed by next, including any necessary padding to ensure that next will be properly aligned, but no trailing padding.

In order to match C representation layout repr(C), you should call pad_to_align after extending the layout with all fields. (There is no way to match the default Rust representation layout repr(Rust), as it is unspecified.)

Note that the alignment of the resulting layout will be the maximum of those of self and next, in order to ensure alignment of both parts.

Returns Ok((k, offset)), where k is layout of the concatenated record and offset is the relative location, in bytes, of the start of the next embedded within the concatenated record (assuming that the record itself starts at offset 0).

On arithmetic overflow, returns LayoutError.

§Examples

To calculate the layout of a #[repr(C)] structure and the offsets of the fields from its fields’ layouts:

pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutError> {
    let mut offsets = Vec::new();
    let mut layout = Layout::from_size_align(0, 1)?;
    for &field in fields {
        let (new_layout, offset) = layout.extend(field)?;
        layout = new_layout;
        offsets.push(offset);
    }
    // Remember to finalize with `pad_to_align`!
    Ok((layout.pad_to_align(), offsets))
}
1.95.0 · Source

pub fn repeat_packed(&self, n: usize) -> Result<Layout, LayoutError>

Creates a layout describing the record for n instances of self, with no padding between each instance.

Note that, unlike repeat, repeat_packed does not guarantee that the repeated instances of self will be properly aligned, even if a given instance of self is properly aligned. In other words, if the layout returned by repeat_packed is used to allocate an array, it is not guaranteed that all elements in the array will be properly aligned.

On arithmetic overflow, returns LayoutError.

1.95.0 · Source

pub fn extend_packed(&self, next: Layout) -> Result<Layout, LayoutError>

Creates a layout describing the record for self followed by next with no additional padding between the two. Since no padding is inserted, the alignment of next is irrelevant, and is not incorporated at all into the resulting layout.

On arithmetic overflow, returns LayoutError.

Trait Implementations§

Source§

impl Clone for DmaHandle

Source§

fn clone(&self) -> DmaHandle

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DmaHandle

Source§

fn fmt(&self, __derive_more_f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for DmaHandle

Source§

type Target = Layout

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Hash for DmaHandle

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for DmaHandle

Source§

fn eq(&self, other: &DmaHandle) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for DmaHandle

Source§

impl Eq for DmaHandle

Source§

impl StructuralPartialEq for DmaHandle

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.