RDMA连接

本文详细介绍了RDMA连接的建立步骤,包括使用rdma_resolve_addr将目标IP地址转换为RDMA地址,以及通过rdma_resolve_route解析路由。在建立连接前,还需要对额外的资源进行初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RDMA连接的建立

rdma_resolve_addr用于将给定的目标 IP 地址映射到可用的 RDMA 地址

/* struct sockaddr_in *s_addr 代表ip地址 */
static struct rdma_event_channel *cm_event_channel = NULL;
static struct rdma_cm_id *cm_client_id = NULL;
/* 打开用于报告通信事件的事件通道。通过事件通道向用户报告异步事件 */
cm_event_channel = rdma_create_event_channel();

/* rdma_cm_ids 在概念上等同于 RDMA 通信的套接字。不同之处在于 RDMA 通信需
要在通信发生之前明确绑定到指定的 RDMA 设备,并且大多数操作本质上是异步的。*/
rdma_create_id(cm_event_channel, &cm_client_id, 
			NULL,
			RDMA_PS_TCP);
rdma_resolve_addr(cm_client_id, NULL, (struct sockaddr*) s_addr, 2000);

 rdma_resolve_route用于将rdma地址解析为路由

struct rdma_cm_event *cm_event = NULL;

/* 等待channel上发生事件: RDMA_CM_EVENT_ADDR_RESOLVED */
process_rdma_cm_event(cm_event_channel, 
			RDMA_CM_EVENT_ADDR_RESOLVED,
			&cm_event);

/* 接受事件(在接受事件之前应该通过process_rdma_cn_event返回的结果判断此事件是否确实发生了) */
rdma_ack_cm_event(cm_event);

 /* 将目标RDMA地址解析为路由 */
rdma_resolve_route(cm_client_id, 2000);

/* 等待事件: RDMA_CM_EVENT_ROUTE_RESOLVED */
process_rdma_cm_event(cm_event_channel, 
			RDMA_CM_EVENT_ROUTE_RESOLVED,
			&cm_event);
rdma_ack_cm_event(cm_event);

在建立连接之前还需要初始化其他资源

/* All resources are tied to a particular PD. 
	 * And accessing recourses across PD will result in a protection fault. */
pd = ibv_alloc_pd(cm_client_id->verbs);


/* Now we need a completion channel, were the I/O completion 
	 * notifications are sent. Remember, this is different from connection 
	 * management (CM) event notifications. 
	 * A completion channel is also tied to an RDMA device, hence we will 
	 * use cm_client_id->verbs. */
io_completion_channel = ibv_create_comp_channel(cm_client_id->verbs);

/* Now we create a completion queue (CQ) where actual I/O 
	 * completion metadata is placed. The metadata is packed into a structure 
	 * called struct ibv_wc (wc = work completion). ibv_wc has detailed 
	 * information about the work completion. An I/O request in RDMA world 
	 * is called "work" ;) 
	 */
client_cq = ibv_create_cq(cm_client_id->verbs /* which device*/, 
			CQ_CAPACITY /* maximum capacity*/, 
			NULL /* user context, not used here */,
			io_completion_channel /* which IO completion channel */, 
			0 /* signaling vector, not used here*/);

/* 为cq提供通知机制 */
ibv_req_notify_cq(client_cq, 0);

/* create a qp with initial args qp_init_attr*/
rdma_create_qp(cm_client_id /* which connection id */,
		       pd /* which protection domain*/,
		       &qp_init_attr /* Initial attributes */);
client_qp = cm_client_id.qp;

 

 

 

### RDMA 可靠连接的实现原理 RDMA(Remote Direct Memory Access)可靠连接的核心在于其能够在网络环境中提供低延迟、高吞吐量的数据传输服务,同时保持数据传输的可靠性。以下是关于 RDMA 可靠连接工作原理的关键点: #### 1. **基于 Reliable Connection (RC) 的 QP 类型** RDMA 提供多种队列对(Queue Pair, QP)类型用于不同的应用场景,其中 RC 是最常用的一种。它支持可靠的端到端消息传递机制,在发生错误时会自动重传丢失或损坏的消息[^2]。 - 在 RC 中,发送方和接收方之间维护了一个虚拟通道,该通道由硬件负责管理状态同步。 - 数据包按照顺序编号,并通过确认机制确保每条消息都被成功送达目标节点。 #### 2. **零拷贝与内核旁路技术** 为了减少传统 TCP/IP 协议栈中的上下文切换开销以及内存复制次数,RDMA 引入了 Zero-Copy 和 Kernel Bypass 技术[^4]: - **Zero-Copy**: 发送应用程序可以直接调用 RNIC Verbs API 将缓冲区地址提交给网卡驱动程序,而无需将数据先拷贝到操作系统内核空间再转发出去; - **Kernel Bypass**: 整个通信流程完全运行于用户态下完成,从而避免频繁地进入/退出核心模式带来的额外消耗。 #### 3. **利用 DMA 完成远程存取** DMA 功能使得 I/O 设备能够独立于 CPU 对主机 RAM 执行读写操作[^3]。当源端发起一次 Write 请求时,本地 NIC 芯片组依据指定参数构建相应帧结构并通过物理链路传送至目的机器上对应的适配器位置处;与此同时,后者则依照预定义规则解析收到的信息片段并将它们放置进特定区域内的存储单元之中——这一切均不依赖任何软件层面上的操作指令干预即可达成预期效果。 #### 4. **ACK 确认机制保障可靠性** 类似于 TCP 的三次握手过程,每次交换都需要等待对方返回 ACK 后才能继续下一步动作。如果某个阶段超出了设定时限仍未获得回应,则触发重新尝试直至最终建立成功的关联关系为止。 ```python import pyverbs.cm_enums as ce from pyverbs.qp import QPInitAttrEx, QPCap def create_rc_qp(pd, cq_send, cq_recv): qp_cap = QPCap(max_send_wr=100, max_recv_wr=100, max_send_sge=8, max_recv_sge=8) qp_init_attr_ex = QPInitAttrEx(cap=qp_cap, sq_sig_all=False, qp_type=ce.IBV_QPT_RC, send_cq=cq_send, recv_cq=cq_recv) # 创建QP实例... ``` 上述代码展示了如何使用 `pyverbs` 库创建一个 RC 类型的 Queue Pair,这是实现 RDMA 可靠连接的基础之一。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值