目录
ibv_get_cq_event
ibv_get_cq_event,ibv_ack_cq_events-获取和确认完成队列(CQ)事件
(注意调用ibv_get_cq_event之前需要调用ibv_req_notify_cq才能得到event,见:【vbers】ibv_req_notify_cq()_bandaoyu的note-CSDN博客)
概要
#include <infiniband / verbs.h>
int ibv_get_cq_event(struct ibv_comp_channel * channel, struct ibv_cq ** cq,void ** cq_context);
void ibv_ack_cq_events(struct ibv_cq * cq,unsigned int nevents);
描述
ibv_get_cq_event()等待事件通道channel中的下一个完成事件。用获取事件的CQ填充参数cq,并用CQ的上下文填充cq_context。
ibv_ack_cq_events()确认 cq上的nevents事件CQ。
返回值
ibv_get_cq_event()成功返回0,错误返回-1。
ibv_ack_cq_events()不返回任何值。
提示
ibv_get_cq_events()返回的所有完成事件必须使用ibv_ack_cq_events()进行确认。
为了避免竞争,销毁CQ将等待所有完成事件得到确认;这保证了在成功与成功之间一对一的对应关系。
在数据路径中调用ibv_ack_cq_events()可能相对昂贵,因为它必须使用互斥量。因此,最好是通过对需要确认的事件数量进行计数并在对ibv_ack_cq_events()的一次调用中同时确认几个完成事件来分摊此成本。
ibv_ack_cq_events
原文original:ibv_ack_cq_events() - RDMAmojo RDMAmojo
描述
ibv_ack_cq_events()确认完成事件(acknowledge Completion events.)。
为了防止竞争,使用ibv_get_cq_event()读取的所有完成事件 必须使用ibv_ack_cq_events()确认。
在数据路径中调用ibv_ack_cq_events()可能相对昂贵,因为它使用互斥对象。因此,最好通过对需要确认的事件进行计数,然后再调用ibv_ack_cq_events()一次性确认多个完成事件来分摊成本。
参数
Name | Direction | Description |
---|---|---|
cq | in | 从ibv_create_cq()返回的CQ |
nevents | in | 要确认的完成事件数。(Number of Completion events to acknowledge) |
返回值
无 (此功能始终成功)。
例子
read完成事件并确认它:
|
常见问题
为什么无论如何需要调用ibv_ack_cq_events()?
使用此verb 函数是为了防止内部竞争。
如果我不确认所有完成事件会怎样?
如果一个人不确认他使用ibv_get_cq_event()读取的所有完成事件,则销毁获得事件的CQ将永远被阻塞。此行为是为了防止出现 对 已被破坏的资源 进行确认(的情况)。
如果我读取一个完成事件,但在确认事件之前我的进程被有意地终止(例如,通过调用exit())或无意地终止(例如,段错误),将会发生什么情况?
即使有任何未确认的完成事件,当进程终止时,无论原因如何,所有资源都将被清除。
我应该一个接一个地确认完成事件,还是一次确认几个完成事件?
确认完成事件需要使用互斥对象,因此强烈建议一次确认多个完成事件(尤其是在数据路径中)。