move dv functionality to use dlopen (#248)

abstract out the usage of direct verbs functionality to use tables with
the function pointers. This will allow in a second step the library to
be simultaniously be compiled for multiple NIC vendors/DV libraries and
interfaces. For now, the conversion has been done for IB MLX5 and BCOM
DV, the Pensando AINIC is to follow soon.
Šī revīzija ir iekļauta:
Edgar Gabriel
2025-09-11 16:13:31 -05:00
revīziju iesūtīja GitHub
vecāks 5dc7d4539e
revīzija 99b753f103
3 mainīti faili ar 181 papildinājumiem un 20 dzēšanām
+55 -10
Parādīt failu
@@ -71,6 +71,29 @@ GDABackend::GDABackend(TcpBootstrap *bootstrap): Backend(bootstrap) {
void GDABackend::init() {
type = BackendType::GDA_BACKEND;
int ret;
#if defined(GDA_BNXT)
ret = bnxt_dv_dl_init();
if (ret != ROCSHMEM_SUCCESS) {
// Disable BNXT GDA support.
DPRINTF("Initializing rocSHMEM BNXT GDA support failed\n");
// We abort for now, but might remove that once we support
// multiple NIC types in the same build
abort();
}
#endif
#if defined(GDA_MLX5)
ret = mlx5_dv_dl_init();
if (ret != ROCSHMEM_SUCCESS) {
// Disable MLX5 GDA support.
DPRINTF("Initializing rocSHMEM MLX5 GDA support failed\n");
// We abort for now, but might remove that once we support
// multiple NIC types in the same build
abort();
}
#endif
read_env();
//TODO setup_host_interface();
@@ -113,6 +136,15 @@ GDABackend::~GDABackend() {
cleanup_gpu_qps();
cleanup_heap_memory_rkey();
cleanup_ibv();
#if defined(GDA_BNXT)
if (bnxtdv_handle_ != nullptr)
dlclose(bnxtdv_handle_);
#endif
#if defined(GDA_MLX5)
if (mlx5dv_handle_ != nullptr)
dlclose(mlx5dv_handle_);
#endif
}
void GDABackend::read_env() {
@@ -545,6 +577,19 @@ void GDABackend::rte_barrier() {
}
}
#if defined(GDA_MLX5)
int GDABackend::mlx5_dv_dl_init () {
mlx5dv_handle_ = dlopen("libmlx5.so", RTLD_NOW);
if (!mlx5dv_handle_) {
printf("Could not open libmlx5.so. Returning\n");
return ROCSHMEM_ERROR;
}
DLSYM_HELPER(mlx5dv_ftable_, mlx5dv_, mlx5dv_handle_, init_obj);
return ROCSHMEM_SUCCESS;
}
#endif
void GDABackend::setup_ibv() {
open_ib_device();
@@ -566,22 +611,22 @@ void GDABackend::cleanup_ibv() {
CHECK_HIP(hipHostUnregister(db_region_attr.dbr));
for (int i = 0; i < qps.size(); i++) {
err = bnxt_re_dv_destroy_qp(qps[i]);
err = bnxtdv_ftable_.destroy_qp(qps[i]);
CHECK_ZERO(err, "bnxt_re_dv_destroy_qp");
err = bnxt_re_dv_umem_dereg(bnxt_qps[i].attr.rq_umem_handle);
err = bnxtdv_ftable_.umem_dereg(bnxt_qps[i].attr.rq_umem_handle);
CHECK_ZERO(err, "bnxt_re_dv_umem_dereg (RQ)");
err = bnxt_re_dv_umem_dereg(bnxt_qps[i].attr.sq_umem_handle);
err = bnxtdv_ftable_.umem_dereg(bnxt_qps[i].attr.sq_umem_handle);
CHECK_ZERO(err, "bnxt_re_dv_umem_dereg (SQ)");
CHECK_HIP(hipFree(bnxt_qps[i].sq_buf));
CHECK_HIP(hipFree(bnxt_qps[i].rq_buf));
err = bnxt_re_dv_destroy_cq(cqs[i]);
err = bnxtdv_ftable_.destroy_cq(cqs[i]);
CHECK_ZERO(err, "bnxt_re_dv_destroy_cq");
err = bnxt_re_dv_umem_dereg(bnxt_cqs[i].umem_handle);
err = bnxtdv_ftable_.umem_dereg(bnxt_cqs[i].umem_handle);
CHECK_ZERO(err, "bnxt_re_dv_umem_dereg");
CHECK_HIP(hipFree(bnxt_cqs[i].buf));
@@ -753,7 +798,7 @@ void GDABackend::modify_qps_reset_to_init() {
for (int i =0; i < qps.size() ; i++) {
#ifdef GDA_BNXT
err = bnxt_re_dv_modify_qp(qps[i], &attr, attr_mask, 0, 0);
err = bnxtdv_ftable_.modify_qp(qps[i], &attr, attr_mask, 0, 0);
#else
err = ibv_modify_qp(qps[i], &attr, attr_mask);
#endif
@@ -799,7 +844,7 @@ void GDABackend::modify_qps_init_to_rtr() {
}
#ifdef GDA_BNXT
err = bnxt_re_dv_modify_qp(qps[i], &attr, attr_mask, 0, 0);
err = bnxtdv_ftable_.modify_qp(qps[i], &attr, attr_mask, 0, 0);
#else
err = ibv_modify_qp(qps[i], &attr, attr_mask);
#endif
@@ -830,7 +875,7 @@ void GDABackend::modify_qps_rtr_to_rts() {
attr.sq_psn = dest_info[i].psn;
#ifdef GDA_BNXT
err = bnxt_re_dv_modify_qp(qps[i], &attr, attr_mask, 0, 0);
err = bnxtdv_ftable_.modify_qp(qps[i], &attr, attr_mask, 0, 0);
#else
err = ibv_modify_qp(qps[i], &attr, attr_mask);
#endif
@@ -984,7 +1029,7 @@ void GDABackend::initialize_gpu_qp(QueuePair* gpu_qp, int conn_num) {
mlx5dv_obj mlx_obj;
mlx_obj.cq.in = cqs[conn_num];
mlx_obj.cq.out = &cq_out;
mlx5dv_init_obj(&mlx_obj, MLX5DV_OBJ_CQ);
mlx5dv_ftable_.init_obj(&mlx_obj, MLX5DV_OBJ_CQ);
dump_mlx5dv_cq(&cq_out, conn_num);
/*
@@ -1007,7 +1052,7 @@ void GDABackend::initialize_gpu_qp(QueuePair* gpu_qp, int conn_num) {
mlx5dv_qp qp_out;
mlx_obj.qp.in = qps[conn_num];
mlx_obj.qp.out = &qp_out;
mlx5dv_init_obj(&mlx_obj, MLX5DV_OBJ_QP);
mlx5dv_ftable_.init_obj(&mlx_obj, MLX5DV_OBJ_QP);
dump_mlx5dv_qp(&qp_out, conn_num);
/*
+90
Parādīt failu
@@ -25,6 +25,8 @@
#ifndef LIBRARY_SRC_GDA_BACKEND_HPP_
#define LIBRARY_SRC_GDA_BACKEND_HPP_
#include <dlfcn.h>
#include "backend_bc.hpp"
#include "containers/free_list_impl.hpp"
#include "hdp_proxy.hpp" //TODO useless?
@@ -35,6 +37,58 @@
#include "bootstrap/bootstrap.hpp"
#include "debug_gda.hpp"
#ifdef GDA_BNXT
#include <infiniband/bnxt_re_dv.h>
struct bnxtdv_funcs_t {
int (*init_obj)(struct bnxt_re_dv_obj *obj, uint64_t obj_type);
struct ibv_qp* (*create_qp)(struct ibv_pd *pd,
struct bnxt_re_dv_qp_init_attr *qp_attr);
int (*destroy_qp)(struct ibv_qp *ibvqp);
int (*modify_qp)(struct ibv_qp *ibv_qp, struct ibv_qp_attr *attr,
int attr_mask, uint32_t type, uint32_t value);
int (*qp_mem_alloc)(struct ibv_pd *ibvpd,
struct ibv_qp_init_attr *attr,
struct bnxt_re_dv_qp_mem_info *dv_qp_mem);
struct ibv_cq* (*create_cq)(struct ibv_context *ibvctx,
struct bnxt_re_dv_cq_init_attr *cq_attr);
int (*destroy_cq)(struct ibv_cq *ibv_cq);
void* (*cq_mem_alloc)(struct ibv_context *ibvctx, int num_cqe,
struct bnxt_re_dv_cq_attr *cq_attr);
void* (*umem_reg)(struct ibv_context *ibvctx,
struct bnxt_re_dv_umem_reg_attr *in);
int (*umem_dereg)(void *umem_handle);
int (*get_default_db_region)(struct ibv_context *ibvctx,
struct bnxt_re_dv_db_region_attr *out);
};
#endif /* GDA_BNXT */
#ifdef GDA_MLX5
#include <infiniband/mlx5dv.h>
struct mlx5dv_funcs_t {
int (*init_obj)(struct mlx5dv_obj *obj, uint64_t obj_type);
};
#endif /* GDA_MLX5 */
/* Helper Macros for handling dynamic libraries */
#define PPCAT_NX(prefix, func_name) prefix##func_name
#define PPCAT(prefix, func_name) PPCAT_NX(prefix, func_name)
#define STRINGIFY_NX(name) #name
#define STRINGIFY(name) STRINGIFY_NX(name)
#define DLSYM_HELPER(func_struct, prefix, handle, func_name) \
do { \
*(void **) (&func_struct.func_name) = dlsym(handle, STRINGIFY(PPCAT(prefix, func_name))); \
if (!func_struct.func_name) { \
DPRINTF("Failed to find function %s \n", STRINGIFY(PPCAT(prefix, func_name))); \
dlclose(handle); \
handle = nullptr; \
return ROCSHMEM_ERROR; \
} \
} while (0)
namespace rocshmem {
class GDAContext;
@@ -437,6 +491,42 @@ class GDABackend : public Backend {
* @brief rte barrier for initialization
*/
void rte_barrier();
#ifdef GDA_BNXT
/**
* @brief structures holding the function pointers to the direct verbs functionality
* of each network driver.
*/
bnxtdv_funcs_t bnxtdv_ftable_;
/**
* @brief handle used for the dlopen of the BCOM library
*/
void *bnxtdv_handle_{nullptr};
/**
* @brief initialize function table for BCOM direct verbs support
*/
int bnxt_dv_dl_init();
#endif
#ifdef GDA_MLX5
/**
* @brief structures holding the function pointers to the direct verbs functionality
* of each network driver.
*/
mlx5dv_funcs_t mlx5dv_ftable_;
/**
* @brief handle used for the dlopen of the MLX5 library
*/
void *mlx5dv_handle_{nullptr};
/**
* @brief initialize function table for MLNX direct verbs support
*/
int mlx5_dv_dl_init();
#endif
};
} // namespace rocshmem
+36 -10
Parādīt failu
@@ -42,7 +42,7 @@ void GDABackend::initialize_gpu_qp(QueuePair* gpu_qp, int conn_num) {
dv_obj.cq.in = cqs[conn_num];
dv_obj.cq.out = &dv_cq;
err = bnxt_re_dv_init_obj(&dv_obj, BNXT_RE_DV_OBJ_CQ);
err = bnxtdv_ftable_.init_obj(&dv_obj, BNXT_RE_DV_OBJ_CQ);
CHECK_ZERO(err, "bnxt_re_dv_init_obj(CQ)");
memset(&gpu_qp->cq, 0, sizeof(bnxt_device_cq));
@@ -56,7 +56,7 @@ void GDABackend::initialize_gpu_qp(QueuePair* gpu_qp, int conn_num) {
dv_obj.qp.in = ib_qp;
dv_obj.qp.out = &dv_qp;
err = bnxt_re_dv_init_obj(&dv_obj, BNXT_RE_DV_OBJ_QP);
err = bnxtdv_ftable_.init_obj(&dv_obj, BNXT_RE_DV_OBJ_QP);
CHECK_ZERO(err, "bnxt_re_dv_init_obj(QP)");
memset(&gpu_qp->sq, 0, sizeof(bnxt_device_sq));
@@ -76,7 +76,7 @@ void GDABackend::initialize_gpu_qp(QueuePair* gpu_qp, int conn_num) {
gpu_qp->sq.mtu = ibv_mtu_to_int(portinfo.active_mtu);
/* Export DB */
err = bnxt_re_dv_get_default_db_region(context, &db_region_attr);
err = bnxtdv_ftable_.get_default_db_region(context, &db_region_attr);
CHECK_ZERO(err, "bnxt_re_dv_init_obj(QP)");
CHECK_HIP(hipHostRegister(db_region_attr.dbr, getpagesize(), hipHostRegisterDefault));
@@ -98,7 +98,7 @@ void GDABackend::create_cqs(int cqe) {
for (int i = 0; i < qps.size(); i++) {
/* Allocate CQ mem */
memset(&cq_attr, 0, sizeof(struct bnxt_re_dv_cq_attr));
bnxt_cqs[i].handle = bnxt_re_dv_cq_mem_alloc(context, cqe, &cq_attr);
bnxt_cqs[i].handle = bnxtdv_ftable_.cq_mem_alloc(context, cqe, &cq_attr);
CHECK_NNULL(bnxt_cqs[i].handle, "bnxt_re_dv_cq_mem_alloc");
/* Allocate CQ UMEM */
@@ -112,7 +112,7 @@ void GDABackend::create_cqs(int cqe) {
umem_attr.size = bnxt_cqs[i].length;
umem_attr.access_flags = IBV_ACCESS_LOCAL_WRITE;
bnxt_cqs[i].umem_handle = bnxt_re_dv_umem_reg(context, &umem_attr);
bnxt_cqs[i].umem_handle = bnxtdv_ftable_.umem_reg(context, &umem_attr);
CHECK_NNULL(bnxt_cqs[i].umem_handle, "bnxt_re_dv_umem_reg(cq_buf)");
/* Create CQ */
@@ -121,7 +121,7 @@ void GDABackend::create_cqs(int cqe) {
cq_init_attr.umem_handle = bnxt_cqs[i].umem_handle;
cq_init_attr.ncqe = cq_attr.ncqe;
cqs[i] = bnxt_re_dv_create_cq(context, &cq_init_attr);
cqs[i] = bnxtdv_ftable_.create_cq(context, &cq_init_attr);
CHECK_NNULL(cqs[i], "bnxt_re_dv_create_cq");
}
}
@@ -152,7 +152,7 @@ void GDABackend::create_qps(int sq_length) {
/* Alloc qp_mem_info */
memset(&bnxt_qps[i].mem_info, 0, sizeof(struct bnxt_re_dv_qp_mem_info));
err = bnxt_re_dv_qp_mem_alloc(pd_orig, &ib_qp_attr, &bnxt_qps[i].mem_info);
err = bnxtdv_ftable_.qp_mem_alloc(pd_orig, &ib_qp_attr, &bnxt_qps[i].mem_info);
CHECK_ZERO(err, "bnxt_re_dv_qp_mem_alloc");
/* Alloc SQ */
@@ -177,7 +177,7 @@ void GDABackend::create_qps(int sq_length) {
umem_attr.size = bnxt_qps[i].mem_info.sq_len;
umem_attr.access_flags = IBV_ACCESS_LOCAL_WRITE;
sq_umem_handle = bnxt_re_dv_umem_reg(context, &umem_attr);
sq_umem_handle = bnxtdv_ftable_.umem_reg(context, &umem_attr);
CHECK_NNULL(sq_umem_handle, "bnxt_re_dv_umem_reg(sq)");
memset(&umem_attr, 0, sizeof(struct bnxt_re_dv_umem_reg_attr));
@@ -185,7 +185,7 @@ void GDABackend::create_qps(int sq_length) {
umem_attr.size = bnxt_qps[i].mem_info.rq_len;
umem_attr.access_flags = IBV_ACCESS_LOCAL_WRITE;
rq_umem_handle = bnxt_re_dv_umem_reg(context, &umem_attr);
rq_umem_handle = bnxtdv_ftable_.umem_reg(context, &umem_attr);
CHECK_NNULL(rq_umem_handle, "bnxt_re_dv_umem_reg(rq)");
/* IB DV QP Init Attr */
@@ -214,10 +214,36 @@ void GDABackend::create_qps(int sq_length) {
bnxt_qps[i].attr.comp_mask = bnxt_qps[i].mem_info.comp_mask;
/* Alloc QP */
qps[i] = bnxt_re_dv_create_qp(pd_orig, &bnxt_qps[i].attr);
qps[i] = bnxtdv_ftable_.create_qp(pd_orig, &bnxt_qps[i].attr);
CHECK_NNULL(qps[i], "bnxt_re_dv_create_qp");
}
}
int GDABackend::bnxt_dv_dl_init() {
bnxtdv_handle_ = dlopen("libbnxt_re.so", RTLD_NOW);
if (!bnxtdv_handle_) {
// Try hard-coded PATH
bnxtdv_handle_ = dlopen("/usr/local/lib/libbnxt_re.so", RTLD_NOW);
if (!bnxtdv_handle_) {
DPRINTF("Could not open libbnxt_re.so. Returning\n");
return ROCSHMEM_ERROR;
}
}
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, init_obj);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, create_qp);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, destroy_qp);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, modify_qp);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, qp_mem_alloc);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, create_cq);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, destroy_cq);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, cq_mem_alloc);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, umem_reg);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, umem_dereg);
DLSYM_HELPER(bnxtdv_ftable_, bnxt_re_dv_, bnxtdv_handle_, get_default_db_region);
return ROCSHMEM_SUCCESS;
}
} // namespace rocshmem