99 lines
2.7 KiB
Rust
99 lines
2.7 KiB
Rust
//! RDMA device discovery
|
|
|
|
use super::types::{RdmaDeviceInfo, RdmaNodeType};
|
|
use crate::error::Result;
|
|
|
|
#[cfg(feature = "rdma")]
|
|
use super::ffi::{
|
|
IbvDeviceAttr, ibv_close_device, ibv_free_device_list, ibv_get_device_list,
|
|
ibv_get_device_name, ibv_open_device, ibv_query_device,
|
|
};
|
|
|
|
#[cfg(feature = "rdma")]
|
|
use std::ffi::CStr;
|
|
|
|
/// Discover available RDMA devices
|
|
pub fn discover_rdma_devices() -> Result<Vec<RdmaDeviceInfo>> {
|
|
let mut devices = Vec::new();
|
|
|
|
#[cfg(feature = "rdma")]
|
|
unsafe {
|
|
let mut num_devices: i32 = 0;
|
|
let device_list = ibv_get_device_list(&mut num_devices);
|
|
|
|
if device_list.is_null() || num_devices == 0 {
|
|
return Ok(devices);
|
|
}
|
|
|
|
for i in 0..num_devices as isize {
|
|
let device = *device_list.offset(i);
|
|
if device.is_null() {
|
|
continue;
|
|
}
|
|
|
|
let name_ptr = ibv_get_device_name(device);
|
|
let name = if name_ptr.is_null() {
|
|
"unknown".to_string()
|
|
} else {
|
|
CStr::from_ptr(name_ptr).to_string_lossy().into_owned()
|
|
};
|
|
|
|
// Open device to query properties
|
|
let context = ibv_open_device(device);
|
|
if context.is_null() {
|
|
continue;
|
|
}
|
|
|
|
let mut attr = IbvDeviceAttr::default();
|
|
if ibv_query_device(context, &mut attr) == 0 {
|
|
devices.push(RdmaDeviceInfo {
|
|
name,
|
|
guid: attr.node_guid,
|
|
num_ports: attr.phys_port_cnt,
|
|
node_type: RdmaNodeType::ChannelAdapter,
|
|
max_msg_size: attr.max_mr_size.min(1 << 30),
|
|
max_qp: attr.max_qp as u32,
|
|
max_cq: attr.max_cq as u32,
|
|
max_mr: attr.max_mr as u32,
|
|
});
|
|
}
|
|
|
|
let _ = ibv_close_device(context);
|
|
}
|
|
|
|
ibv_free_device_list(device_list);
|
|
}
|
|
|
|
#[cfg(not(feature = "rdma"))]
|
|
{
|
|
// Return stub device info when RDMA is not available
|
|
devices.push(RdmaDeviceInfo {
|
|
name: "stub_device".to_string(),
|
|
guid: 0,
|
|
num_ports: 1,
|
|
node_type: RdmaNodeType::ChannelAdapter,
|
|
max_msg_size: 1 << 30,
|
|
max_qp: 65536,
|
|
max_cq: 65536,
|
|
max_mr: 65536,
|
|
});
|
|
}
|
|
|
|
Ok(devices)
|
|
}
|
|
|
|
/// Check if RDMA is available on this system
|
|
pub fn is_rdma_available() -> bool {
|
|
#[cfg(feature = "rdma")]
|
|
{
|
|
discover_rdma_devices()
|
|
.map(|devices| !devices.is_empty())
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
#[cfg(not(feature = "rdma"))]
|
|
{
|
|
false
|
|
}
|
|
}
|