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
impl MemoryRegion
Sourcepub unsafe fn register_mr_with_access(
pd: &ProtectionDomain,
address: *mut u8,
length: usize,
access_flags: AccessFlags,
) -> IbvResult<MemoryRegion>
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:
- Aliasing: Remote peers can modify this memory at any time. You must manually ensure Rust’s aliasing rules are respected.
- Lifetime: You must manually ensure the memory remains allocated as long as remote peers are actively performing RDMA operations on it.
Sourcepub fn register_local_mr(
pd: &ProtectionDomain,
address: *mut u8,
length: usize,
) -> IbvResult<MemoryRegion>
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:
- It does not allow Remote access (no aliasing risk).
- 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.
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.
Sourcepub unsafe fn register_dmabuf_mr_with_access(
pd: &ProtectionDomain,
fd: i32,
offset: u64,
length: usize,
iova: u64,
access_flags: AccessFlags,
) -> IbvResult<MemoryRegion>
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:iovamust have the same page offset asoffset.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.
Sourcepub fn register_local_dmabuf_mr(
pd: &ProtectionDomain,
fd: i32,
offset: u64,
length: usize,
iova: u64,
) -> IbvResult<MemoryRegion>
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 asoffset.
Safe for the same reasons as register_local_mr: usages are gated by SGE creation.
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 asoffset.
§Safety
Unsafe due to remote access risks. See register_shared_mr.
Source§impl MemoryRegion
impl MemoryRegion
Sourcepub fn rkey(&self) -> u32
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.
Sourcepub fn address(&self) -> usize
pub fn address(&self) -> usize
Returns the starting virtual address of the registered memory buffer.
Sourcepub fn lkey(&self) -> u32
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.
Sourcepub fn remote(&self) -> RemoteMemoryRegion
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
impl MemoryRegion
Sourcepub fn gather_element<'a>(&'a self, data: &'a [u8]) -> GatherElement<'a>
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.
Sourcepub fn gather_element_checked<'a>(
&'a self,
data: &'a [u8],
) -> Result<GatherElement<'a>, ScatterGatherElementError>
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:
- The slice is fully contained within this
MemoryRegion. - 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).
Sourcepub fn gather_element_unchecked<'a>(
&'a self,
data: &'a [u8],
) -> GatherElement<'a>
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.
Sourcepub fn scatter_element<'a>(&'a self, data: &'a mut [u8]) -> ScatterElement<'a>
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.
Sourcepub fn scatter_element_checked<'a>(
&'a self,
data: &'a mut [u8],
) -> Result<ScatterElement<'a>, ScatterGatherElementError>
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:
- The slice is fully contained within this
MemoryRegion. - 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.
Sourcepub fn scatter_element_unchecked<'a>(
&'a self,
data: &'a mut [u8],
) -> ScatterElement<'a>
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.
Sourcepub fn encloses(&self, address: *const u8, length: usize) -> bool
pub fn encloses(&self, address: *const u8, length: usize) -> bool
Checks if the given address range is fully contained within this MR.
Sourcepub fn encloses_slice(&self, slice: &[u8]) -> bool
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
impl Debug for MemoryRegion
Source§impl Drop for MemoryRegion
impl Drop for MemoryRegion
impl Send for MemoryRegion
SAFETY: libibverbs components are thread safe.
impl Sync for MemoryRegion
SAFETY: libibverbs components are thread safe.