・ロックの優先順位

  dev(lock) → qp → dev(schedule) → srq → pd → cq → dev(wq)

  mad.c の中で ib_post_send の外側で spin_lock_irqsave している。
  セマフォではなく spin_lock を使う必要がある。

	spin_lock_irqsave(&qp_info->send_queue.lock, flags);
	if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
		ret = ib_post_send(mad_agent->qp, &mad_send_wr->send_wr,
				   &bad_send_wr);
		list = &qp_info->send_queue.list;
	} else {
		ret = 0;
		list = &qp_info->overflow_list;
	}

	if (!ret) {
		qp_info->send_queue.count++;
		list_add_tail(&mad_send_wr->mad_list.list, list);
	}
	spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);

・HCA & switch エミュレーション

   pib の HCA エミュレーションは IB の定義するパケットを UDP パケットとして送受信する。
   # CRC がない。Credit-based flow control のためのフィールドや MSN が

   pib のエミュレーションしている HCA 毎に 1 つのスレッドと 1 つの UDP ソケットを作成する。


  ・SMP (Direct routing)
  ・Unicast               LID が分かれれば直接送信する。
  ・Multicast             easy switch に投げてフォワーディングする。

  実機の IB は HCA が接続された物理的なリンクを辿って送信を行うが、pib では通常のユニ
  キャスト通信は easy switch をバイパスして、直接通信相手のポートのソケットへ送信する。

  ただしマルチキャストと Direct routing の SMP MAD は、スイッチ経由で行う。
  
・MR

  MR の L_Key と R_Key は PD に設けられた mr_table[] のインデックス値とする。
  ただし配列のインデックスとして使うのは下位ビットで、上位ビットは PD ごと
  に設定する乱数値とする。

・GID

  IB は 64-bit のユニークアドレス (EUI-64) が必要。

  マルチホストモードでは、複数のホスト間で衝突しない値をつける必要がある。

  このためにホスト内で見つかった最初のイーサーネット機器の MAC アドレス (EUI-48) を借用し、
  これを上位につめた 64 ビットを合成する。

  0x0000 Not use
  0x0100 Easy Switch
  0x0200 SystemImageGUID 
  0xyyzz NodeGUID or PortGUID
         -- yy は 3 から始まる HCA 番号
         -- zz は 0 なら NodeGUID で、1 以上は PortGUID

・送信処理は Send Queue は submitted(未送信)、sending(送信中)、waiting(ACK待ち) の 3 つのキューで処理する。

  - ibv_post_send は submitted queue につなげる。

    - QP が RESET または INIT 以外なら可能。

  - バックグラウンド処理が submitted queue から Send WR を取り出して、sending queue につなげる。
    これは QP が RTS の場合だけ実行する。

    - 先行する RMDA READ、Atomic 操作がある場合、SEND_FENCE がついている sending queue にはつなげない。
    - 同時実行中の RMDA READ、Atomic 操作 が上限を越えると  sending queue にはつなげない。

  - Sending queue の先頭からパケットを送信する。
    これは QP が RTS または SQD の場合だけ実行する。

  - 1回分の送信が完了すれば sending キューのエントリは waiting キューに送る。

  - QP が Send Drain(SQD) 属性になった場合は、submitted キューにあるのものは sending queue に移さない。

  - 送信が失敗(NAK受信、再送)になると wainting キューにある全エントリは sending キューに戻した上で、
    全ての未 ACK パケット分をクリアする。

  - ACK は sending キューと waiting キューにある場合の二通りが考えられる。

・輻輳制御

  輻輳制御はまったく未実装である。

