割り込み関連のバグ - virtio

現象

receive 時に割り込みを見ているのに used->idx が進んでおらず待たされるときがある。

現象を解決する1つの方法

send で割り込み見るようにする。

仮説

send で割り込みを OFF にしているつもりだが割り込みが来ているのでは?
仮説が正しいとすると、receive で割り込みを待っていても実は send の割り込みが来ているだけなので used->idx が進んでいないことが説明できる。

検証方法

send のみ実行して割り込みの有無をチェックする。

結果

  • send せずとも1度割り込みが来る(notify?)
  • send 1回につき割り込み 1回来る

追加検証

  • send のどこで割り込みが来ているか
    • outp16(baseAddress_ + VIRTIO_PCI_QUEUE_NOTIFY, VRING_TYPE_WRITE); のあと。
  • 1回目の割り込みは何か?
    • outp32(baseAddress_ + VIRTIO_PCI_QUEUE_PFN, syscall_get_physical_address((uintptr_t)vring->desc, NULL) >> 12);

発見

VRING_USED_F_NO_NOTIFY の flags の指定場所を間違えていた。

次の一手

  • VRING_USED_F_NO_NOTIFYを正しく設定する
  • send で割り込みが来ないことを確認する
  • VIRTIO_PCI_QUEUE_PFN で割り込みが来るのは想定通りか?確認する
  • VRING_AVAIL_F_NO_INTERRUPT が活用できるか検討する