IBV_GET_ASYNC_EVENT(3), IBV_ACK_ASYNC_EVENT(3)

作成日:2014.05.10
修正日:2014.05.31

NAME

ibv_get_async_event, ibv_ack_async_event - 非同期イベント(asynchronous events)を取得・承認(acknowledge)する。

SYNOPSIS

#include <infiniband/verbs.h>

int ibv_get_async_event(struct ibv_context *context,
                        struct ibv_async_event *event);

void ibv_ack_async_event(struct ibv_async_event *event);

DESCRIPTION

ibv_get_async_event()context で指定される RDMA デバイスから非同期イベントが到着するまで待機する。 ibv_get_async_event() の呼び出しに成功した場合、1 イベントだけ取得し event の領域へコピーする。 失敗した場合は、イベントの取得なしで ibv_get_async_event() の呼び出しから復帰する。

contextibv_open_device(3) でオープンした RDMA デバイスを指定する。

ibv_ack_async_event() は非同期イベント event を承認する。

非同期イベントの詳細は 「InfiniBand のエラーハンドリングのモデルを理解する」を参照のこと。

RETURN VALUE

ibv_get_async_event() は成功すれば 0 を返す。 失敗すれば -1 を返す。

ibv_ack_async_event() には戻り値はない。

ERRORS

ibv_get_async_event() は仕様に明記されていないが、-1 で返ってきた場合 errno にエラー原因が登録されている。

EINTRシグナルによる割り込みが入った。
EAGAIN(context->async_fd をノンブロッキングモードに設定している場合)
取り出し可能な非同期イベントがない。

errno の利用は仕様外なので、自己責任になる。

NOTES

ibv_get_async_event() で取り出した非同期イベントは、ibv_ack_async_event() を使って承認する必要がある。 ibv_get_async_event() で取り出した非同期イベントに紐付けられたオブジェクト(CQ、SRQ、QP) を破壊する操作(ibv_destroy_cq()ibv_destroy_srq()ibv_destroy_qp())を実行すると、ibv_ack_async_event() が呼ばれるまで待機することになる。 これは InfiniBand Verbs 内での競合を避けるためのガード機構である。

逆に event が指す非同期イベントのデータに触ってよいのは、ibv_get_async_evnet() で取得した後、ibv_ack_async_event() を呼び出す前までである。 ibv_ack_async_event() が呼ばれた後は、非同期イベントのデータの先にある CQ/QP/SRQ は破壊されメモリ領域が回収されている可能性がある。

ibv_get_async_event() は待機関数である。 もしマルチスレッドがこの関数を同時に呼び出した状態で、1 つだけ非同期イベントが発生すると、どちらか 1 つのスレッドだけが非同期イベントを受信する。 ただしどちらのスレッドが受け取るかは予測できない。

EXAMPLES

context->async_fd をノンブロッキングモードに設定するには以下のコードのように fcntl() を設定する。

#include <stdlib.h> /* for exit */
#include <unistd.h>
#include <fcntl.h>
#include <infiniband/verbs.h>

static void async_change_blocking_mode(struct ibv_context *context)
{
    int ret, flags;

    flags = fcntl(context->async_fd, F_GETFL);
    if (flags < 0) {
        perror("fcntl(context->async_fd, F_GETFL)");
        exit(EXIT_FAILURE);
    }

    ret = fcntl(context->async_fd, F_SETFL, flags | O_NONBLOCK);
    if (ret < 0) {
        perror("fcntl(context->async_fd, F_SETFL, flags | O_NONBLOCK)");
        exit(EXIT_FAILURE);
    }
}

ノンブロッキングモードに設定以降は ibv_get_async_event() もブロックせず、取り出し可能な非同期イベントがない場合は -1 で復帰し、errnoEAGAIN が設定されるようになる。

非同期イベントの到着は context->async_fd が ready-to-input になるタイミングを select()epoll() で待ち合わせることができる。 context->async_fd が "ready" になった後は、ibv_get_async_event() を呼び出すと最低 1 つは完了イベントを取り出すことができる。

SEE ALSO

InfiniBand Verbs API Referenceibv_open_device(3)

AUTHORS

コメント

コメントを書き込む

TOP    掲示板    戻る
Written by NAKAMURA Minoru, Email: nminoru atmark nminoru dot jp, Twitter:@nminoru_jp