Virtio-netでXDPを動かすにはqemuのオプション変更が必要

Linuxカーネル4.10からvirtio_netがXDPをサポートするようになった。だが、動作させるには少しオプション変更が必要となる。

Qemuの起動オプションに下記を渡すことでここに記載のあるオフロード機能が無効になり、XDPが動作するようになる:

gso=off,guest_tso4=off,guest_tso6=off,guest_ecn=off,guest_ufo=off

virshであれば、該当NICinterfaceセクションの下に下記設定を入れてあげれば良さそう:

$ virsh edit XDP-VM
<domain type='kvm'>
...
  <devices>
    ...
    <interface type='network'>
      ...
      <model type='virtio'/>
      <driver name='vhost' queues='4'>
        <host gso='off' tso4='off' tso6='off' ecn='off' ufo='off'/>
        <guest tso4='off' tso6='off' ecn='off' ufo='off'/>
      </driver>
      ...
    </interface>
    ...
  </devices>
</domain>

Pitfall

上記設定をせずにXDPを使おうとすると、NICにプログラムをアタッチする段階でEOPNOTSUPP (Operation not supported) が返ってきて失敗する。また、ゲスト側のログに下のメッセージが出る:

$ dmesg
...
[  528.046901] virtio_net virtio4 ens9: can't set XDP while host is implementing LRO, disable LRO first

このメッセージと該当部分のコードを素直に読むと、ethtoollroないしtso/ufo/ecnを無効にしてやれば良さそうに見える。だが実際には前述した通りqemuのオプション側でこれらの機能を無効にする必要があるので注意が必要*1

Reference

*1:詳しくは追えていないがそういうものらしい https://www.spinics.net/lists/netdev/msg409656.html