Skip to main content

MemoryRegion

Struct MemoryRegion 

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

A handle to a registered Memory Region.

A MemoryRegion represents a block of memory registered with the NIC for RDMA operations.

§What is Registration?

Registration pins a memory buffer (preventing OS swapping) and provides the NIC with virtual-to-physical address translation, enabling direct memory access (DMA) without CPU involvement.

§Ownership Model

MemoryRegion does not own the underlying buffer. This design allows:

  • Registering the same buffer in multiple Protection Domains.
  • Registering memory owned by other structures.
  • Flexible memory management strategies.

Safety is enforced at usage time when creating GatherElement or ScatterElement instances (see the memory module for details).

§Registration Methods

§Safe Registration

  • register_local_mr — Local write access only. Safe because all operations require creating SGEs with valid Rust references.

§Unsafe Registration

  • register_shared_mr — Adds remote read/write access. Unsafe because remote peers can access memory asynchronously, breaking aliasing guarantees.
  • register_mr_with_access — Full manual control. Unsafe when remote access flags are enabled.

Implementations§

Source§

impl MemoryRegion

Source

pub unsafe fn register_mr_with_access( pd: &ProtectionDomain, address: *mut u8, length: usize, access_flags: AccessFlags, ) -> IbvResult<MemoryRegion>

Registers a memory region with specific access permissions.

§Arguments
  • pd — The Protection Domain to register this memory region in.
  • address — Pointer to the start of the memory buffer to register.
  • length — The size of the buffer in bytes.
  • access_flags — The permissions to grant to the NIC for this memory region.
§Safety

This function is unsafe because enabling remote read or write access breaks local safety guarantees. If remote access is enabled:

  1. Aliasing: Remote peers can modify this memory at any time. You must manually ensure Rust’s aliasing rules are respected.
  2. Lifetime: You must manually ensure the memory remains allocated as long as remote peers are actively performing RDMA operations on it.
Source

pub fn register_local_mr( pd: &ProtectionDomain, address: *mut u8, length: usize, ) -> IbvResult<MemoryRegion>

Registers a local memory region (Local Write access).

This enables local write access only.

§Arguments
  • pd — The Protection Domain.
  • address — Pointer to the start of the memory buffer.
  • length — The size of the buffer in bytes.
§Why is this Safe?

Even though this does not take ownership of the memory, it is safe because:

  1. It does not allow Remote access (no aliasing risk).
  2. To use this MR locally (Send/Recv/Write-Source), you must create an SGE. The SGE creation requires a valid reference to the memory, proving it is still alive.
Source

pub unsafe fn register_shared_mr( pd: &ProtectionDomain, address: *mut u8, length: usize, ) -> IbvResult<MemoryRegion>

Registers a shared memory region with local write and remote read and write access.

§Arguments
  • pd — The Protection Domain.
  • address — Pointer to the start of the memory buffer.
  • length — The size of the buffer in bytes.
§Safety

This is unsafe because it allows remote peers to access the memory.

  • Aliasing — The memory effectively becomes shared mutable state. It is your responsibility to ensure aliasing rules are respected while remote peers perform RDMA operations on it.
  • Lifetime — You must manually ensure the memory remains allocated as long as remote peers are actively performing RDMA operations on it.
Source

pub unsafe fn register_dmabuf_mr_with_access( pd: &ProtectionDomain, fd: i32, offset: u64, length: usize, iova: u64, access_flags: AccessFlags, ) -> IbvResult<MemoryRegion>

Registers a DMA-BUF with the given access flags.

§Arguments
  • pd — The Protection Domain to register this memory region in.
  • fd — The file descriptor of the DMA-BUF to be registered.
  • offset — The start offset within the DMA-BUF file. The MR begins at this offset.
  • length — The size of the region to register (in bytes).
  • iova — The Input/Output Virtual Address. This is the virtual base address the NIC will use when accessing this MR via lkey/rkey. Important: iova must have the same page offset as offset.
  • access_flags — The permissions for this memory region.
§Safety

Same safety rules as register_mr_with_access. If access_flags includes remote capabilities, the user must manage aliasing and lifetimes manually.

Source

pub fn register_local_dmabuf_mr( pd: &ProtectionDomain, fd: i32, offset: u64, length: usize, iova: u64, ) -> IbvResult<MemoryRegion>

Registers a DMA-BUF for local access only.

§Arguments
  • pd — The Protection Domain.
  • fd — The file descriptor of the DMA-BUF.
  • offset — The start offset within the DMA-BUF file.
  • length — The size of the region to register (in bytes).
  • iova — The virtual base address. Must have the same page offset as offset.

Safe for the same reasons as register_local_mr: usages are gated by SGE creation.

Source

pub unsafe fn register_shared_dmabuf_mr( pd: &ProtectionDomain, fd: i32, offset: u64, length: usize, iova: u64, ) -> IbvResult<MemoryRegion>

Registers a DMA-BUF for shared access.

§Arguments
  • pd — The Protection Domain.
  • fd — The file descriptor of the DMA-BUF.
  • offset — The start offset within the DMA-BUF file.
  • length — The size of the region to register (in bytes).
  • iova — The virtual base address. Must have the same page offset as offset.
§Safety

Unsafe due to remote access risks. See register_shared_mr.

Source§

impl MemoryRegion

Source

pub fn rkey(&self) -> u32

Returns the Remote Key (rkey) for this MR.

This key is used by remote peers to access this memory region via RDMA operations.

Source

pub fn address(&self) -> usize

Returns the starting virtual address of the registered memory buffer.

Source

pub fn length(&self) -> usize

Returns the length of the registered memory region in bytes.

Source

pub fn lkey(&self) -> u32

Returns the Local Key (lkey) for this MR.

This key is used locally in Work Requests (within Scatter/Gather Elements) to prove to the NIC that the application has the right to access this memory.

Source

pub fn remote(&self) -> RemoteMemoryRegion

Returns a remote endpoint of this MR for remote peers to use in one-sided operations.

This struct contains the triplet (Address, Length, RKey) needed by a remote node to perform RDMA Read or Write operations on this memory.

§Warning

If the peer attempts an operation (e.g., RDMA Write) that was not enabled during registration, their operation will fail with a Remote Access Error.

Source§

impl MemoryRegion

Source

pub fn gather_element<'a>(&'a self, data: &'a [u8]) -> GatherElement<'a>

Creates a Gather Element (for Sending/Writing) using the “raw” constructor.

§Debug checks

In debug builds, this validates MR containment and the u32 length limit and may panic if they are violated (because it uses debug_assert!). In release builds, these checks are not executed by default.

Source

pub fn gather_element_checked<'a>( &'a self, data: &'a [u8], ) -> Result<GatherElement<'a>, ScatterGatherElementError>

Creates a Gather Element (for Sending/Writing) from a shared slice.

§Checks

This method validates that:

  1. The slice is fully contained within this MemoryRegion.
  2. The slice’s length fits in a u32 (hardware limit for a single SGE).

If these checks fail, it returns an error immediately.

§Safety Guarantee

This takes a &'a [u8], ensuring the memory is initialized and cannot be mutated while the operation is pending (Rust borrowing rules).

Source

pub fn gather_element_unchecked<'a>( &'a self, data: &'a [u8], ) -> GatherElement<'a>

Creates a Gather Element without immediate bounds checking.

§Behavior

This bypasses the software checks for:

  • Memory region containment.
  • Length limits (u32).
§Safety

This method is safe to call. If the slice is not within the memory region, or if the length is invalid, the library will create the SGE anyway.

However, the hardware will catch this mismatch when the Work Request is executed. The operation will fail with a Local Protection Error, but it will not cause Undefined Behavior.

Source

pub fn scatter_element<'a>(&'a self, data: &'a mut [u8]) -> ScatterElement<'a>

Creates a Scatter Element (for Receiving/Reading) using the “raw” constructor.

§Debug checks

In debug builds, this validates MR containment and the u32 length limit and may panic if they are violated (because it uses debug_assert!). In release builds, these checks are not executed by default.

Source

pub fn scatter_element_checked<'a>( &'a self, data: &'a mut [u8], ) -> Result<ScatterElement<'a>, ScatterGatherElementError>

Creates a Scatter Element (for Receiving/Reading) from a mutable slice.

§Checks

This method validates that:

  1. The slice is fully contained within this MemoryRegion.
  2. The slice’s length fits in a u32.
§Safety Guarantee

This takes a &'a mut [u8], ensuring you have exclusive access to the buffer and no other part of your program is reading it while the NIC writes to it.

Source

pub fn scatter_element_unchecked<'a>( &'a self, data: &'a mut [u8], ) -> ScatterElement<'a>

Creates a Scatter Element without immediate bounds checking.

§Behavior

This bypasses the software checks for:

  • Memory region containment.
  • Length limits (u32).
§Safety

This method is safe to call. If the slice is not within the memory region, or if the length is invalid, the library will create the SGE anyway.

However, the hardware will catch this mismatch when the Work Request is executed. The operation will fail with a Local Protection Error, but it will not cause Undefined Behavior.

Source

pub fn encloses(&self, address: *const u8, length: usize) -> bool

Checks if the given address range is fully contained within this MR.

Source

pub fn encloses_slice(&self, slice: &[u8]) -> bool

Checks if the given slice is fully contained within this MR.

Trait Implementations§

Source§

impl Debug for MemoryRegion

Source§

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

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

impl Drop for MemoryRegion

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for MemoryRegion

SAFETY: libibverbs components are thread safe.

Source§

impl Sync for MemoryRegion

SAFETY: libibverbs components are thread safe.

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> 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<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.