use enumflags2::{bitflags, BitFlags};
use rdma_sys::ibv_access_flags;
#[bitflags]
#[repr(u64)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AccessFlag {
LocalWrite,
RemoteWrite,
RemoteRead,
RemoteAtomic,
MwBind,
ZeroBased,
OnDemand,
HugeTlb,
RelaxOrder,
}
#[inline]
#[must_use]
pub(crate) fn flags_into_ibv_access(flags: BitFlags<AccessFlag>) -> ibv_access_flags {
let mut ret = ibv_access_flags(0);
if flags.contains(AccessFlag::LocalWrite) {
ret |= ibv_access_flags::IBV_ACCESS_LOCAL_WRITE;
}
if flags.contains(AccessFlag::RemoteWrite) {
ret |= ibv_access_flags::IBV_ACCESS_REMOTE_WRITE;
}
if flags.contains(AccessFlag::RemoteRead) {
ret |= ibv_access_flags::IBV_ACCESS_REMOTE_READ;
}
if flags.contains(AccessFlag::RemoteAtomic) {
ret |= ibv_access_flags::IBV_ACCESS_REMOTE_ATOMIC;
}
if flags.contains(AccessFlag::MwBind) {
ret |= ibv_access_flags::IBV_ACCESS_MW_BIND;
}
if flags.contains(AccessFlag::ZeroBased) {
ret |= ibv_access_flags::IBV_ACCESS_ZERO_BASED;
}
if flags.contains(AccessFlag::OnDemand) {
ret |= ibv_access_flags::IBV_ACCESS_ON_DEMAND;
}
if flags.contains(AccessFlag::HugeTlb) {
ret |= ibv_access_flags::IBV_ACCESS_HUGETLB;
}
if flags.contains(AccessFlag::RelaxOrder) {
ret |= ibv_access_flags::IBV_ACCESS_RELAXED_ORDERING;
}
ret
}
#[inline]
#[must_use]
pub(crate) fn ibv_access_into_flags(access: ibv_access_flags) -> BitFlags<AccessFlag> {
let mut ret = BitFlags::<AccessFlag>::empty();
if (access & ibv_access_flags::IBV_ACCESS_LOCAL_WRITE).0 != 0 {
ret |= AccessFlag::LocalWrite;
}
if (access & ibv_access_flags::IBV_ACCESS_LOCAL_WRITE).0 != 0 {
ret |= AccessFlag::LocalWrite;
}
if (access & ibv_access_flags::IBV_ACCESS_REMOTE_READ).0 != 0 {
ret |= AccessFlag::RemoteRead;
}
if (access & ibv_access_flags::IBV_ACCESS_REMOTE_WRITE).0 != 0 {
ret |= AccessFlag::RemoteWrite;
}
if (access & ibv_access_flags::IBV_ACCESS_REMOTE_ATOMIC).0 != 0 {
ret |= AccessFlag::RemoteAtomic;
}
if (access & ibv_access_flags::IBV_ACCESS_MW_BIND).0 != 0 {
ret |= AccessFlag::MwBind;
}
if (access & ibv_access_flags::IBV_ACCESS_ZERO_BASED).0 != 0 {
ret |= AccessFlag::ZeroBased;
}
if (access & ibv_access_flags::IBV_ACCESS_ON_DEMAND).0 != 0 {
ret |= AccessFlag::OnDemand;
}
if (access & ibv_access_flags::IBV_ACCESS_HUGETLB).0 != 0 {
ret |= AccessFlag::HugeTlb;
}
if (access & ibv_access_flags::IBV_ACCESS_RELAXED_ORDERING).0 != 0 {
ret |= AccessFlag::RelaxOrder;
}
ret
}
#[cfg(test)]
mod access_test {
use super::*;
use crate::{memory_region::IbvAccess, RdmaBuilder};
use std::alloc::Layout;
#[tokio::test]
#[allow(clippy::unwrap_used)]
async fn flags_into_ibv_access_test() {
let rdma = RdmaBuilder::default().build().unwrap();
let layout = Layout::new::<[u8; 4096]>();
let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
let mr = rdma.alloc_local_mr_with_access(layout, access).unwrap();
assert_eq!(mr.ibv_access(), flags_into_ibv_access(access));
}
#[tokio::test]
#[allow(clippy::unwrap_used)]
async fn ibv_access_into_flags_test() {
let rdma = RdmaBuilder::default().build().unwrap();
let layout = Layout::new::<[u8; 4096]>();
let access = AccessFlag::LocalWrite | AccessFlag::RemoteRead;
let mr = rdma.alloc_local_mr_with_access(layout, access).unwrap();
assert_eq!(access, ibv_access_into_flags(mr.ibv_access()));
}
}