InfiniBand のエラーハンドリングのモデルを理解する

作成日:2014.04.17
修正日:2014.05.11

この文書は InfiniBand Verbs プログラムで必要になる InfiniBand のエラーハンドリングのモデルを解説する。

ただし InfiniBand Verbs でサポートしない Reliable Datagram(RD) サービスタイプは扱わず、Reliable Connection(RC)、Unreliable Connection(UC)、Unreliable Datagram(UD) の 3 つのサービスタイプのみを説明する。 eXtensible Reliable Connection(XRC) サービスタイプのエラーはまだ記載していない。 将来的に追記する。

以下は関連ページ。


更新履歴
(2014.04.17) 作成。
(2014.05.11) API にリンクを貼る


目次

1. はじめに

InfiniBand のエラーは 3 種類の方法で報告される。 そのうち 2 種類は概念編チュートリアル編で説明した 完了エラー(Completion Error)非同期エラー(Asynchronous Error) である。

完了エラーは Completion Queue(CQ) に Work Completion として報告されるエラーであり、全て Queue Pair(QP) と紐付けられている。 完了エラーは ibv_poll_cq で取得する。

非同期エラーは様々な原因によって生じ、ibv_get_async_event で取得することができる。 非同期エラーはまずユーザーコンテキストが作り出した QP、CQ、Shared Receive Queue(SRQ) に関連した Affiliated Error と、HCA や Port に関連した Unaffiliated Error に大別される。 Affiliated error はエラーを生成する原因となったオブジェクトの所有ユーザーコンテキストにだけ報告されるが、unaffiliated error はシステム内にある全てのユーザーコンテキストにブロードキャストされる(そのため libibverbs-utils パッケージに含まれる ibv_asyncwatch は unaffiliated error だけを監視できる)。

非同期エラーと言ったが一部に非同期イベント(Asynchronous Event) も含まれる。 名前だけの違いなので両者を区別する必要は特にない。 この文書では非同期エラーで代表させる。

最後は Immediate Error と呼ばれる。 日本語にし辛いが 即答エラー か? これは InfiniBand Verbs API の関数戻り値がエラーとなって復帰する場合である。 この文書ではあまり触れない。

Fig 1: InfiniBand のエラーの全体図

InfiniBand のエラーハンドリングを考える場合、以下の点を踏まえておく必要がある。

2. 完了エラー(Completion Error)

ibv_poll_cq() で返される完了は struct ibv_wc 構造体を持っている。 この中で statusenum ibv_wc_status 列挙子型を持ち、完了エラーの種類を報告する。

完了エラーが ibv_poll_cq() から取り出された場合、表中で明示的に「QP をエラーに落とさない」と書いてないものは、QP を Error ステートまたは Send Queue Error(SQE) ステートへ強制遷移させる。

Side の列は、requester side と responder side のどちらで発生するかを示している。 Services の列は、この完了エラーが発生する可能性のあるサービスタイプを示している。

完了エラーの種類
イベント名SideServicesQP Error備考
Success IBV_WC_SUCCESS Both All None  
Local Length Error IBV_WC_LOC_LEN_ERR Responder RC/UC Error Receive WRバッファ長の不足
All RC/UC Error or SQE メッセージ最大長の超過
Local QP Operation Error IBV_WC_LOC_QP_OP_ERR Both All Error or SQE  
Local Protection Error IBV_WC_LOC_PROT_ERR Both All Error or SQE  
Work Request Flushed Error IBV_WC_WR_FLUSH_ERR Both All None  
Memory Management Operation Error IBV_WC_MW_BIND_ERR        
Local Access Error IBV_WC_LOC_ACCESS_ERR Responder RC/UC Error  
Bad Response Error IBV_WC_BAD_RESP_ERR Requester RC Error  
Remote Invalid Request Error IBV_WC_REM_INV_REQ_ERR Requester RC Error  
Remote Access Error IBV_WC_REM_ACCESS_ERR Requester RC Error  
Remote Operation Error IBV_WC_REM_OP_ERR Requester RC Error  
Transport Retry Counter Exceed IBV_WC_RETRY_EXC_ERR Requester RC Error  
RNR Retry Counter Exceeded IBV_WC_RNR_RETRY_EXC_ERR Requester RC Error  
Aborted Error IBV_WC_REM_ABORT_ERR Responder UC None  
Fatal Error IBV_WC_FATAL_ERR Both All Error  
Response Timeout Error IBV_WC_RESP_TIMEOUT_ERR Unknown All Error  
General Error IBV_WC_GENERAL_ERR Unknown All Error?  
Local EE Context Operation Error IBV_WC_LOC_EEC_OP_ERR   RD    
Local RDD Violation Error IBV_WC_LOC_RDD_VIOL_ERR   RD
Remote Invalid RD Request IBV_WC_REM_INV_RD_REQ_ERR   RD
Invalid EE Context Number IBV_WC_INV_EECN_ERR   RD
Invalid EE Context State IBV_WC_INV_EEC_STATE_ERR   RD

2.1 Success (IBV_WC_SUCCESS)

Work Request が成功したことを示す。 これはエラーではない。 そのため QP をエラーに落とさない。

2.2 Local Length Error (IBV_LOC_LEN_ERR)

Local Length Error は 2 種類の原因で発生する。

1 つ目は responder が SEND オペレーションを受信した時、Receive Queue に登録してあった Receive WR のバッファサイズが受信メッセージの長さよりも小さいことが原因の場合である。 QP が SRQ を使っている場合にも、SRQ の Receive WR のバッファサイズが小さいと発生する。

2 つ目は requester が送信するメッセージ長が InfiniBand の仕様上の上限 231 バイトを越えるか、また HCA の実機のメッセージ長の上限を超えたことが原因の場合である。 また requester と responder で別の HCA カードを挿している場合、requester 側のメッセージ長の上限よりも responder 側の上限が小さい場合が考えられる。 この場合に、responder が自身のメッセージ長上限を超越える SEND オペレーションを受信した時にエラーが発生する。 理論上は RDMA WRITE with Immediate オペレーションでも発生することがある。 ただし非同期エラー(Invalid Request Local Work Queue Error; IBV_EVENT_QP_REQ_ERR)になる可能性が高い。

メッセージの上限は ibv_query_port() によって取得できるポート属性の max_msg_sz で確認できる。 また ibv_devinfo に -v オプションを与えて実行することでも確認可能である。 ちなみに Mellanox ConnectX-3 ではこの値は 0x40000000 (=1G) バイトとなっている。

(どちらの場合でも) RC サービスにおいてこのエラーが responder 側に出た場合、NAK-Invalid Request を返すので、(NAK がパケットロスを起こさなければ) requester は Remote Invalid Request Error を発生させる。

2.3 Local QP Operation Error (IBV_WC_LOC_QP_OP_ERR)

QP にエラーが発生した場合に起きる。 Send WR や Receive WR のパラメータが不正だった場合(オペコードとか)に発生する。

RC サービスにおいてこのエラーが responder 側に出た場合、NAK-Remote Operation Error を返すので、(NAK がパケットロスを起こさなければ) requester は Remote Operation Error を発生させる。

2.4 Local Protection Error (IBV_WC_LOC_PROT_ERR)

Send WR や Receive WR 内の L_Key が Memory Region と合致しない場合に発生する。 Local Protection Error が出る正確な条件は 5.1 も参照のこと。

RC サービスにおいてこのエラーが responder 側に出た場合、NAK-Remote Operation Error を返すので、(NAK がパケットロスを起こさなければ) requester は Remote Operation Error を発生させる。

2.5 Work Request Flushed Error (IBV_WC_WR_FLUSH_ERR)

QP が Error ステートになった場合、SQ と RQ 内の WR は CQ に吐き出される。 この時、吐き出された WR にはこのエラー番号が設定される。 また QP が Error ステートになった後に、ibv_post_send()ibv_post_recv() で WR を登録した場合、直ちに CQ に完了エラーとして積まれるが、この時もこのエラー番号が設定される(ただし SRQ に紐付けられている QP が Error ステートになっても、SRQ の Receive WR はそのままなことに注意)。

また QP が SQE ステートになった場合、SQ 内の WR は CQ に吐き出される。 この時、吐き出された WR はこのエラー番号が設定される。 また QP が SQE ステートになった後に、ibv_post_send() で WR を登録した場合、直ちに CQ に完了エラーとして積まれるが、この時もこのエラー番号が設定される。

この完了エラーは QP をエラーにする原因そのものではなく、疑似エラーである。 そのため この完了エラーは QP をエラーに落とさない。

2.6 Local Access Error (IBV_WC_LOC_ACCESS_ERR)

RDMA WRITE with Immediate オペレーションを受けた時に R_Key が Memory Region と合致しない場合に発生する。 ただし完了エラーではなく非同期エラー(Local Access Violation Work Queue Error; IBV_EVENT_QP_ACCESS_ERR) として発生する場合もある。 Remote Protection Error が出る正確な条件は 5.1 も参照のこと。

RC サービスにおいてこのエラーが responder 側に出た場合、NAK-Remote Access Error を返すので、(NAK がパケットロスを起こさなければ) requester は Remote Access Error を発生させる。

2.7 Bad Response Error (IBV_WC_BAD_RESP_ERR)

Responder から返される応答メッセージ(ACK or NAK)を requester が解析した時に、不正なオペコードが含まれていた場合に発生する。

トランスポート層の障害によってのみ発生し、上位のプログラムのバグでは発生しえない。

2.8 Remote Invalid Request Error (IBV_WC_REM_INV_REQ_ERR)

Responder 側にエラーが発生し、NAK-Invalid Request が返ってきた結果を報告するエラーである。 具体的には以下が原因で発生する。

  1. Responder が受信したリクエストパケット内のオペコードが不正。
  2. Responder が受信したリクエストパケット内のペイロードの長さが不正。
  3. Responder が max_msg_sz を越える長さのメッセージを受信した。
  4. Responder が受信した SEND オペレーションのデータが Receive WR のバッファサイズを越えた。
  5. RDMA READ や ATOMIC オペレーションのリクエストを QP に設定された同時処理数の属性(max_dest_rd_atomic)以上に受け取った。 詳細は「InfiniBand の再送制御を理解する」を参照のこと。
  6. ATOMIC オペレーションが不正境界。

1. と 2. はトランスポート層の障害によってのみ発生し、上位のプログラムのバグでは発生しえない。

2.9 Remote Access Error (IBV_WC_REM_ACCESS_ERR)

Responder 側にエラーが発生し、NAK-Remote Access Error が返ってきた結果を報告するエラーである。 具体的には以下が原因で発生する。

2.10 Remote Operation Error (IBV_WC_REM_OP_ERR)

Responder 側にエラーが発生し、NAK-Remote Operation Error が返ってきた結果を報告するエラーである。 以下の状況で発生する。

2.11 Transport Retry Counter Exceed (IBV_WC_RETRY_EXC_ERR)

Local ACK Timeout による再送が上限を越えた場合に発生する。 詳細は「InfiniBand の再送制御を理解する」を参照のこと。

2.12 RNR Retry Counter Exceeded (IBV_WC_RNR_RETRY_EXC_ERR)

RNR NAK Retry による再送が上限を越えた場合に発生する。 詳細は「InfiniBand の再送制御を理解する」を参照のこと。

2.13 Aborted Error (IBV_WC_REM_ABORT_ERR)

UC サービスはパケットロスが起きた時でも再送をしないが、QP を Error ステートに落とすこともしない。 RQ から取り出した Receive WR はリセットして、次のメッセージの受信用に再利用する。 しかし SRQ から取り出した Receive WR は、HCA の実装によっては SRQ に戻せない場合がある。 そのような実装では、処理を中断した Receive WR を「アボート」する。 この完了エラーは QP をエラーに落とさない。 ユーザープログラムは ibv_poll_cq() でアボート完了エラーを受け取った場合には、プログラムを停止させずに処理を続ける必要がある。

このエラーが responder 側に発生しても、requester は感知しない。

2.14 Fatal Error (IBV_WC_FATAL_ERR)

QP に対して致命的な異常が発生したことを通知する。 発生条件は具体的に規定されていない。

2.15 Response Timeout Error (IBV_WC_RESP_TIMEOUT_ERR)

InfiniBand の仕様ではなく、InfiniBand Verbs が内部的に定義しているエラーである。 現在はカーネルによって IB ドライバがアンロードされ、応答を待っている WQE を CQ に移す際にこのエラーが出現することがある。

現在はユーザーランドプログラムが見ることはない。

2.16 General Error (IBV_WC_GENERAL_ERR)

分類できないエラーはこのエラー番号で報告される。 例えば RMPP MAD の送信で後続パケットが送れない場合に発生する。

このエラーが responder に発生した場合の、requester の挙動は不明。

3. 非同期エラー(Asynchronous Error)

ibv_get_async_event() で返される非同期エラーは struct ibv_async_event 構造体を持っている。 この中で event_typeenum ibv_event_type 列挙子型を持ち、非同期エラーの種類を報告している。

struct ibv_async_event {
        union {
                struct ibv_cq  *cq;
                struct ibv_qp  *qp;
                struct ibv_srq *srq;
                int             port_num;
        } element;
        enum ibv_event_type     event_type;
};

enum ibv_event_type 列挙子型で区別される非同期エラーの種類は以下の表のようになる。

非同期エラーの種類
発生箇所 イベント名 Services Affiliated /
Unaffiliated
Event /
Error
QP Local Work Queue Catastrophic Error IBV_EVENT_QP_FATAL All Affiliated Error
Invalid Request Local Work Queue Error IBV_EVENT_QP_REQ_ERR RC Affiliated Error
Local Access Violation Work Queue Error IBV_EVENT_QP_ACCESS_ERR RC Affiliated Error
Communication Established Event IBV_EVENT_COMM_EST RC/UC/RD
(UD/Raw)*
Affiliated Event
Send Queue Drained Event IBV_EVENT_SQ_DRAINED All** Affiliated Event
Path Migrated Event IBV_EVENT_PATH_MIG All *** Affiliated Event
Path Migration Request Error IBV_EVENT_PATH_MIG_ERR All *** Affiliated Error
Last WQE Reached Event IBV_EVENT_QP_LAST_WQE_REACHED RC/UD/UC Affiliated Event
CQ CQ Error IBV_EVENT_CQ_ERR All Affiliated Error
SRQ SRQ Catastrophic Error IBV_EVENT_SRQ_ERR All Affiliated Error
SRQ Limit Reached Event IBV_EVENT_SRQ_LIMIT_REACHED RC/UD/UC Affiliated Event
Port Port Active IBV_EVENT_PORT_ACTIVE   Unaffiliated Event
Port Error IBV_EVENT_PORT_ERR   Unaffiliated Error
LID Change IBV_EVENT_LID_CHANGE   Unaffiliated Event
P_Key Change IBV_EVENT_PKEY_CHANGE   Unaffiliated Event
SM Change IBV_EVENT_SM_CHANGE   Unaffiliated Event
Client Reregistration IBV_EVENT_CLIENT_REREGISTER   Unaffiliated Event
GID Table Change IBV_EVENT_GID_CHANGE   Unaffiliated Event
CA Local Catastrophic Error IBV_EVENT_DEVICE_FATAL   Unaffiliated Error
* UD/RAW はオプションだが、この非同期イベントを発生させることは strongly discouraged とある。
** Unreliable は再送を行わないので、意味があるのは RC だけである。
*** Connection (RC、UC) だけで意味がある。

3.1 Catastrophic Error

Local Work Queue Catastrophic Error(IBV_EVENT_QP_FATAL)、CQ Error(IBV_EVENT_CQ_ERR)、SRQ Catastrophic Error(IBV_EVENT_SRQ_ERR) の 3 種類は、オブジェクトに破壊的なエラーが発生したことを通知する。 この破壊的エラーが発生したオブジェクトは、再利用できず直ちに ibv_destroy_qp()ibv_destroy_cq()ibv_destroy_srq() で回収する必要がある。

また Local Catastrophic Error(IBV_EVENT_DEVICE_FATAL) は HCA に致命的な異常が発生したことを通知する。 この異常が発生したユーザーコンテキストは利用を中断する必要がある。

3.1.1 Local Work Queue Catastrophic Error (IBV_EVENT_QP_FATAL)

QP に致命的なエラーが発生したことを通知する。 QP 自身に致命的なエラーが生じた場合以外に、ibv_create_qp() で作成時に関連付けられた CQ に CQ Error や、SRQ に SRQ Catastrophic Error が発生した場合にもこのエラーが起きる。

このエラーが発生すると QP は一応 Error ステートになる。 ただし他の原因で Error ステートに遷移した場合と異なり、CQ から CQE が取り出せるという保証はない。 そのため QP がこのエラーになった場合、ibv_destroy_qp() で回収すべきであろう。

3.1.2 CQ Error (IBV_EVENT_CQ_ERR)

CQ に致命的なエラーが発生したことを通知する。 ユーザープログラムが CQ へ追加される CQE が最大数をオーバーフローした場合に発生する。 これ以外にも CQ に異常が発生した場合には、このエラーが発生するとされる。

CQ がこのエラーになった以降は、CQ に新しい CQE を積んだり ibv_poll_cq() で取り出すことはできなくなる。 つまり ibv_destroy_cq() 以外の操作ができなくなる。

CQ がこのエラーになった場合、この CQ を ibv_create_qp()qp_init_attr->send_cqqp_init_attr->recv_cq に指定している QP は全て連鎖的に Local Work Queue Catastrophic Error となる。

3.1.3 SRQ Catastrophic Error (IBV_EVENT_SRQ_ERR)

SRQ に致命的なエラーが発生したことを通知する。 このエラーが起こる具体的な事象は定義されていない。

SRQ がこのエラーになった以降は、SRQ に ibv_post_srq_recv() で新しい Receive WR を登録することや、SRQ から Receive WR を取り出すことができなくなる。 つまり ibv_destroy_srq() 以外の操作ができなくなる。

SRQ がこのエラーになった場合、この SRQ を ibv_create_qp()qp_init_attr->srq に指定している QP は全て連鎖的に Local Work Queue Catastrophic Error となる。

3.1.4 Local Catastrophic Error (IBV_EVENT_DEVICE_FATAL)

HCA に何らかの致命的な異常が発生したことを意味する。 これが通知された場合、ユーザーコンテキストに属する全てのオブジェクトは以降正常に使えるという保証がなくなる。 すみやかにユーザーコンテキストに所属する全てのオブジェクトを破壊し、ユーザーコンテキストも ibv_close_device() で閉じるのが望ましい。 ただし、それも成功しない可能性がある。

3.2 Normal Error

3.2.1 Invalid Request Local Work Queue Error (IBV_EVENT_QP_REQ_ERR)

Responder がトランスポート層に異常を発見した場合に発生する。 具体的には以下が原因で発生する。

  1. Responder が受信したリクエストパケット内のオペコードが不正。
  2. Responder が受信したリクエストパケット内のペイロードの長さが不正。
  3. Responder が max_msg_sz を越える長さのメッセージを受信した。

3.2.2 Local Access Violation Work Queue Error (IBV_EVENT_QP_ACCESS_ERR)

Responder が RDMA WRITE with Immediate オペレーション以外の RDMA 操作を受信し、異常となった場合に発生する。 具体的には以下が原因で発生する。

  1. ATOMIC オペレーションが不正境界。
  2. RDMA READ や ATOMIC オペレーションのリクエストを QP に設定された同時処理数の属性(max_dest_rd_atomic)以上に受け取った。 詳細は「InfiniBand の再送制御を理解する」を参照のこと。
  3. RDMA WRITE without Immediate、RDMA READ、ATOMIC オペレーションで R_Key が Memory Region と合致しない。
  4. RDMA WRITE with Immediate オペレーションで R_Key が Memory Region と合致しない(場合によって)

3.3 プログラムによって利用できるイベント

3.3.1 Communication Established Event (IBV_EVENT_COMM_EST)

この非同期イベントは、「InfiniBand の QP ステートの遷移を理解する」で述べたように QP を RTR ステートに遷移後に最初のパケットを受信したことを通知する。 受信するパケットは SEND/RDMA WRITE/RDMA READ/ATOMIC 操作要求のいずれでもよい。 RTR ステートのまま複数のパケットを受信しても 2 度目以降は発生しない。 ただしステートを遷移させ、再び RTR ステートに変えた場合はまた発生する。

3.3.2 Send Queue Drained Event (IBV_EVENT_SQ_DRAINED)

この非同期イベントは、「InfiniBand の QP ステートの遷移を理解する」で述べたように QP が SQD ステートに遷移後に送信中の全ての Send WR に ACK が返ってきたことを通知する。 プログラムがこのイベントを拾うことで、QP の送信メッセージが停止したことを確認できる。 ibv_modfiy_qp() で SQD ステートから SQD ステートへ遷移することで、RTR や RTS で設定した属性の一部を受信を停止せずに変更することが可能である。

3.3.3 Last WQE Reached Event (IBV_EVENT_QP_LAST_WQE_REACHED)

この非同期イベントは、「InfiniBand の QP ステートの遷移を理解する」で述べたように SRQ に紐付けられた QP が Error ステートに落ちた後に、処理中の WQE の CQ への追加が完了したことを通知する。 発生条件は以下の 2 つである。

ただし上記の条件を満たしても、QP が Local Catastrophic Error によって Error ステートに落ちた場合には、この非同期イベントは発生しないかもしれない。

3.3.4 SRQ Limit Reached Event (IBV_EVENT_SRQ_LIMIT_REACHED)

この非同期イベントは、チュートリアルで述べたように SRQ の WQE の残量が SRQ Limit を下回ったことを通知する。

ただし 1 度 IBV_EVENT_SRQ_LIMIT_REACHED 非同期イベントが発生すると、SRQ Limit は無効化されるので、もう 1 度使うには ibv_modify_srq() で再設定する必要がある。

ibv_modify_srq()srq_attr_maskIBV_SRQ_MAX_WR を設定するには、HCA が IBV_DEVICE_SRQ_RESIZE をサポートしている必要がある。 しかし IBV_SRQ_LIMITIBV_DEVICE_SRQ_RESIZE サポートは不要である。

3.4 Path Migration に関係するもの

3.4.1 Path Migrated Event (IBV_EVENT_PATH_MIG)

通信パスがalternate pathに切り替わったことを通知する。

3.4.2 Path Migration Request Error (IBV_EVENT_PATH_MIG_ERR)

通信パスをalternate pathに切り替えようとしてエラーが発生したことを通知する。

3.5 ポートのリンク状態に関係するもの

Port Active Event(IBV_EVENT_PORT_ACTIVE) と Port Error(IBV_EVENT_PORT_ERR) は HCA のポートのリンク状態に変化があった時に発生する。

この 2 つ非同期エラーは HCA がこれらを報告する機能を実装している場合のみ発生する。 機能が実装されている場合、ibv_query_port() の中の port_cap_flagsIBV_DEVICE_PORT_ACTIVE_EVENT の属性がセットされていることで報告される。

3.5.1 Port Active Event (IBV_EVENT_PORT_ACTIVE)

ポートのリンク状態が通信不能から通信可能なステータスに遷移したことを通知する。 これはポートのリンク状態は物理的な結線がつながっただけではなく、Subnet Manager から LID の割り当てまでが完了した状態である。

このイベントの到着後は ibv_query_port()state が、IBV_PORT_ACTIVEIBV_PORT_ACTIVE_DEFER になる。

3.5.2 Port Error(IBV_EVENT_PORT_ERR)

ポートのリンク状態が通信可能から通信不能なステータスに遷移したことを通知する。

この非同期エラーが発生しても QP のステートはそのままである。

このイベントの到着後は ibv_query_port()state が、IBV_PORT_ACTIVEIBV_PORT_ACTIVE_DEFER 以外になる。

3.7 Subnet Manager に関係するもの

LID Change(IBV_EVENT_LID_CHANGE)、P_Key Change(IBV_EVENT_PKEY_CHANGE)、SM Change(IBV_EVENT_SM_CHANGE)、Client Reregistration(IBV_EVENT_CLIENT_REREGISTER)、GID Table Change(IBV_EVENT_GID_CHANGE) は Subnet Manager がポートへの設定の変更した際に発生する。

3.6.1 LID Change (IBV_EVENT_LID_CHANGE)

この非同期イベントは Subnet Manager がポートの LID を変更した時に発生する。 HCA のポートの LID は初期状態では 0 だが、Subnet Manager がサブネットを構成して LID を割り当てたタイミングでもこの非同期イベントは発生する。

この非同期イベント発生後は、Base port LID が変更されているので、ibv_query_port()lid を確認すべきである。 またポートに属する各種情報は取得し直す必要がある。

Subnet Manager が停止した場合でも、いったんポートに割り当てられた LID は維持される。

3.6.2 P_Key Change (IBV_EVENT_PKEY_CHANGE)

この非同期イベントは Subnet Manager が Partition Key Table を変更した時に発生する。

この非同期イベント発生後は、Partition Key Table が変更されているので、ibv_query_pkey を確認すべきである。

3.6.3 SM Change (IBV_EVENT_SM_CHANGE)

この非同期イベントは Subnet Manager がマイグレーションした時に発生する。

この非同期イベント発生後は、ポートの SM LID が変更されているので、ibv_query_port()sm_lid を確認すべきである。

3.6.4 Client Reregistration (IBV_EVENT_CLIENT_REREGISTER)

この非同期イベントは Subnet Manager が再起動などによりポートの情報を再登録した場合に発生する。

この非同期イベント発生後は、ポートに属する各種情報は取得し直す必要がある。

この非同期イベントは HCA が Client Reregistration をサポートしている場合のみ発生する。 Client Reregistration がサポートされている場合、ibv_query_port() の中の port_cap_flags1U << 25 の属性がセットされていることで報告される。

Mellanox ConnectX-3 ではこの機能はサポートされている。

3.6.5 GID Table Change (IBV_EVENT_GID_CHANGE)

この非同期イベントは Subnet Manager がポートの GID Table を変更した時に発生する。

この非同期イベント発生後は、GID Table が変更されているので、ibv_query_gid() を確認すべきである。

4. パターンごとの発生するエラー

4.1 Send Work Request または Receive Work Request の登録エラー

ibv_post_send() を使って Send Queue(SQ) に Send Work Request が登録可能かどうかは、QP のステートに依存する。

ibv_post_recv() を使って Receive Queue(RQ) に Send Work Request が登録可能かどうかは、QP のステートに依存する。

この操作で QP のステートが変わることはない。

QP が Reset、Init、RTR ステートの時に ibv_post_send() を呼び出した場合と、Reset ステートの時に ibv_post_recv() を呼び出した場合には、仕様上 Immediate Error となる。 しかし実機では Immediate Error とならない場合がある。 その場合、登録に成功したように振舞う場合と、Local QP Operation Error (IBV_WC_LOC_QP_OP_ERR) となる場合がある。

4.2 Requester が Send Work Request 処理時にエラー

Send WQE の内容に誤りがあった場合にはエラーとなる。

エラー発生時には RC サービスの場合は Error ステートに落ちる。 UC/UD サービスの場合は SQE ステートに落ちる。

4.3 Responder が受信不能

Responder はリクエストとなるパケットに含まれるパラメータが条件を満たさない場合、QP には渡さずにパケットを破棄する。

パケットの破棄で responder の QP はステートが変わることはない。

4.4 Responder QP でリクエスト受信時にエラー

Responder がリクエストパケットを受信した場合、オペレーション種類ごとに異なるエラーが発生する。

4.4.1 SEND

SEND オペレーションは RC/UC/UD サービスで利用できる。 SEND オペレーションのメッセージを受信した場合、responder のパターンによって以下のような完了エラーが発生する。 また responder の QP は Error ステートに落ちる。

RC サービスの場合は、これらのエラーが生じた場合は NAK が返されて、requester にも完了エラーが発生し、QP は Error ステートに落ちる。

エラー Responder に生じるエラー Requester に生じるエラー
L_Key が Memory Region と合致しない Local Protection Error(IBV_WC_LOC_PROT_ERR) 完了エラー Remote Operation Error(IBV_WC_REM_OP_ERR) 完了エラー
Receive WR バッファ長の不足 Local Length Error(IBV_LOC_LEN_ERR) 完了エラー(*1) Remote Invalid Request Error(IBV_WC_REM_INV_REQ_ERR) 完了エラー
メッセージ最大長を超過 Local Length Error(IBV_LOC_LEN_ERR) 完了エラー(*2) Remote Invalid Request Error(IBV_WC_REM_INV_REQ_ERR) 完了エラー
それ以外 Local QP Operation Error(IBV_WC_LOC_QP_OP_ERR) 完了エラー Remote Operation Error(IBV_WC_REM_OP_ERR) 完了エラー

4.4.2 RDMA WRITE

RDMA WRITE オペレーションは RC/UD サービスで利用できる。 RDMA WRITE オペレーションのメッセージを受信した場合、responder のパターンによって以下のような完了エラー・非同期エラーが発生する。 また responder の QP は Error ステートに落ちる。

RC サービスの場合は、これらのエラーが生じた場合は NAK が返されて、requester にも完了エラーが発生し、QP は Error ステートに落ちる。

エラー Responder に生じるエラー Requester に生じるエラー
R_Key が Memory Region と合致しない Local Access Error(IBV_WC_LOC_ACCESS_ERR) 完了エラー
Local Access Violation Work Queue Error(IBV_EVENT_QP_ACCESS_ERR) 非同期エラー
Remote Access Error(IBV_WC_REM_ACCESS_ERR) 完了エラー
メッセージ最大長を超過 Local Length Error(IBV_LOC_LEN_ERR) 完了エラー
Invalid Request Local Work Queue Error(IBV_EVENT_QP_REQ_ERR) 非同期エラー
Remote Invalid Request Error(IBV_WC_REM_INV_REQ_ERR) 完了エラー
それ以外 Local QP Operation Error(IBV_WC_LOC_QP_OP_ERR) 完了エラー
Invalid Request Local Work Queue Error(IBV_EVENT_QP_REQ_ERR) 非同期エラー
Remote Operation Error(IBV_WC_REM_OP_ERR) 完了エラー

RDMA WRITE without Immediate オペレーションの場合、responder は非同期エラーのみが発生する。 しかし RDMA WRITE with Immediate オペレーションの場合、responder に生じるのは完了エラーと非同期エラーの場合の2通りが考えられる。 詳細は 5.2 を参照のこと。

4.4.3 RDMA READ、ATOMIC Operations

RDMA READ、ATOMIC Operations は RC サービスで利用できる。 RDMA READ、ATOMIC Operations のメッセージを受信した場合、responder のパターンによって以下のような非同期エラーが発生する。 また responder の QP は Error ステートに落ちる。

RC サービスの場合は、これらのエラーが生じた場合は NAK が返されて、requester にも完了エラーが発生し、QP は Error ステートに落ちる。

エラー Responder に生じるエラー Requester に生じるエラー
R_Key が Memory Region と合致しない Local Access Violation Work Queue Error (IBV_EVENT_QP_ACCESS_ERR) 非同期エラー Remote Access Error (IBV_WC_REM_ACCESS_ERR) 完了エラー
メッセージ最大長を超過 Invalid Request Local Work Queue Error (IBV_EVENT_QP_REQ_ERR) 非同期エラー Remote Invalid Request Error (IBV_WC_REM_INV_REQ_ERR) 完了エラー
同時受信数が max_dest_rd_atomic を超過 Local Access Violation Work Queue Error (IBV_EVENT_QP_ACCESS_ERR) 非同期エラー Remote Invalid Request Error (IBV_WC_REM_INV_REQ_ERR) 完了エラー
ATOMIC オペレーションの境界に沿わない Local Access Violation Work Queue Error (IBV_EVENT_QP_ACCESS_ERR) 非同期エラー Remote Invalid Request Error (IBV_WC_REM_INV_REQ_ERR) 完了エラー
それ以外 Invalid Request Local Work Queue Error (IBV_EVENT_QP_REQ_ERR) 非同期エラー Remote Operation Error (IBV_WC_REM_OP_ERR) 完了エラー

5. その他のトピックス

5.1 Local/Remote Protection Error の考え方

Local protection error は Send WR や Receive WR に設定した scatter/gather エントリが事前に ibv_reg_mr() で登録した memory region と合致しない場合に発生する。 Scatter/gather エントリの 1 組は struct ibv_sge 構造体で渡すことになる。

struct ibv_sge {
        uint64_t                addr;
        uint32_t                length;
        uint32_t                lkey;
};

実際に local protection error は以下のパターンで生じる。

  1. S/G エントリが memory region として登録されていない。
  2. S/G エントリが memory region として登録した範囲からはみ出している。
  3. L_Key が memory region と一致しない。
  4. オペレーションの要求する memory region で登録したアクセス権限と一致しない。

Remote protection error は、requester で登録した RDMA オペレーションがパケットに埋め込まれて responder に送信され、responder で登録した memory region と合致しない場合に発生する。 比較されるのは struct ibv_send_wr 構造体の rkey で示される R_Key、remote_addr のアドレス、バイト長である。 バイト長は明示的に指定するのではなく、Send WR で指定する scatter/gather エントリの length を足したものがバイト長になる。

struct ibv_send_wr {
        union {
                struct {
                        uint64_t        remote_addr;
                        uint32_t        rkey;
                } rdma;
        } wr;
};

Remote protection error も 1.〜4. のパターンで生じる。

1. 〜 4. が全部 local/remote protection error として丸められるのは、やや大雑把な感じがするがこれは protection domain、memory region の内部実装から来ていると思われる。 Memory region は概念的には Fig 2 のようにメモリ空間をカバーする範囲を登録しておき、アドレスから memory region を決定するのだが、実際に memory region を木構造で管理したりすると探索に時間がかかる。

Fig 2: Memory Region の探索(概念図)

そこで実際の memory region の探索はアドレスからではなく、L_Key や R_Key を用いて行う。 Memory region と QP は protection domain 内に作成されることは概念編で説明したが、protection domain 内には memory region を登録する表がある。 ibv_reg_mr() はこの表の空きエントリに挿入するのだが、その際に表のインデックス番号を L_Key や R_Key の一部に埋め込んでおく。 検索は L_Key や R_Key から表のインデックス番号をデコードして特定する。

Fig 3: Memory Region の探索(実際)

上記のような実装をとるため 1. は表にエントリがあるかどうかのチェック、2. 〜 4. はエントリ内のパラメータを使った比較となり、一律なエラーとして扱われている。

5.2 RDMA WRITE with Immediate の特殊事情

大概のエラーは完了エラーで返すか非同期エラーで返すかが決まっている中で、RDMA WRITE with Immediate だけは状況に応じて完了エラーが出たり非同期エラーが出たりする。 これには以下のような事情がある。

RC/UC は 1 つの Send WR が 1 つのメッセージとして送信されるが、1 メッセージの最大長は 231 であり、MTU を越えるサイズの場合は複数のパケットに分割して送信される。 しかし responder から見ると、自身に送られてきたメッセージが RDMA WRITE オペレーションなのか、RDMA WRITE with Immediate オペレーションなのかを判定するには最後のパケットの到着を待たなくてはならない。

RDMA WRITE with/without Immediate オペレーションのオペコード
オペレーション メッセージ長 最初のパケット 真ん中のパケット 最後のパケット
RDMA WRITE MTU 以下RDMA WRITE Only
RDMA WRITE with ImmediateMTU 以下RDMA WRITE Only with Immediate
RDMA WRITE MTU 超過RDMA WRITE FirstRDMA WRITE MiddleRDMA WRITE Last
RDMA WRITE with ImmediateMTU 超過RDMA WRITE FirstRDMA WRITE MiddleRDMA WRITE Last with Immediate

一方、最初のパケットを受け取った段階でエラーだと分かることが多い。 例えば R_Keyは最初のパケットに含まれているので Remote Access Error かどうかは分かる。 この場合、RDMA WRITE オペレーションか RDMA WRITE with Immediate オペレーションなのかを判別するためだけに、最後のパケットまで待つのは効率が悪い。 HCA は実装によって、判定ができない状況では RDMA WRITE (without Immediate) オペレーションだとみなして非同期エラーを投げることになる。

これが RDMA WRITE with Immediate オペレーションが完了エラーになったり非同期エラーになったりする理由である。

コメント

コメントを書き込む

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