当前位置: 首页 > 工具软件 > cq > 使用案例 >

【verbs】ibv_get_cq_event|ibv_ack_cq_events()

淳于祺
2023-12-01

目录

ibv_get_cq_event

概要

描述

返回值

提示

ibv_ack_cq_events

描述

参数

返回值

例子

常见问题


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()一次性确认多个完成事件分摊成本

参数

NameDirectionDescription
cqin从ibv_create_cq()返回的CQ
neventsin

要确认的完成事件数。(Number of Completion events to acknowledge)

返回值

无 (此功能始终成功)。

例子

read完成事件并确认它:

struct ibv_context *context;
struct ibv_cq *cq;
void *ev_ctx = NULL; /* can be initialized with other values for the CQ context */
 
/* Create a CQ, which is associated with a Completion Event Channel */
cq = ibv_create_cq(ctx, 1, ev_ctx, channel, 0);
if (!cq) {
        fprintf(stderr, "Failed to create CQ\n");
        return -1;
}
 
/* Request notification before any completion can be created (to prevent races) */
ret = ibv_req_notify_cq(cq, 0);
if (ret) {
        fprintf(stderr, "Couldn't request CQ notification\n");
        return -1;
}
 
.
. /* Perform an operation that will eventually end with Work Completion */
.
 
/* The following code will be called each time you need to read a Work Completion */
struct ibv_cq *ev_cq;
void *ev_ctx;
int ret;
int ne;
 
/* Wait for the Completion event */
ret = ibv_get_cq_event(channel, &amp;ev_cq, &amp;ev_ctx);
if (ret) {
        fprintf(stderr, "Failed to get CQ event\n");
        return -1;
}
 
/* Request notification upon the next completion event */
ret = ibv_req_notify_cq(ev_cq, 0);
if (ret) {
        fprintf(stderr, "Couldn't request CQ notification\n");
        return -1;
}
 
/* Empty the CQ: poll all of the completions from the CQ (if any exist) */
do {
        ne = ibv_poll_cq(cq, 1, &amp;wc);
        if (ne &lt; 0) {
                fprintf(stderr, "Failed to poll completions from the CQ: ret = %d\n",
                        ne);
                return -1;
        }
        /* there may be an extra event with no completion in the CQ */
        if (ne) {
            if (wc.status != IBV_WC_SUCCESS) {
                fprintf(stderr, "Completion with status 0x%x was found\n",
wc.status);
                return -1;
            }
        }
} while (ne);
 
/* Ack the event */
ibv_ack_cq_events(ev_cq, 1);

常见问题

为什么无论如何需要调用ibv_ack_cq_events()?

使用此verb 函数是为了防止内部竞争。

如果我不确认所有完成事件会怎样?


如果一个人不确认他使用ibv_get_cq_event()读取的所有完成事件,则销毁获得事件的CQ将永远被阻塞。此行为是为了防止出现 对 已被破坏的资源 进行确认(的情况)。

如果我读取一个完成事件,但在确认事件之前我的进程被有意地终止(例如,通过调用exit())或无意地终止(例如,段错误),将会发生什么情况?

即使有任何未确认的完成事件,当进程终止时,无论原因如何,所有资源都将被清除。

我应该一个接一个地确认完成事件,还是一次确认几个完成事件?

确认完成事件需要使用互斥对象,因此强烈建议一次确认多个完成事件(尤其是在数据路径中)。

 类似资料:

相关阅读

相关文章

相关问答