Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

16.2.2. SR-IOV の使用

本セクションでは、PCI パススルーを使用して、SR-IOV 対応マルチポートネットワークカードの仮想機能を、ネットワークデバイスとして仮想マシンに割り当てる方法を説明します。
SR-IOV 仮想機能 (VF) は、virsh edit コマンドまたは virsh attach-device コマンドで <hostdev> にデバイスエントリーを追加することで、仮想マシンに割り当てることができます。ただし、これは通常のネットワークデバイスとは異なり、SR-IOV VF ネットワークデバイスには永続的な一意の MAC アドレスがなく、ホストを再起動するたびに新しい MAC アドレスが割り当てられるため、問題になることがあります。このため、システムの再起動後にゲストに同じ VF が割り当てられた場合でも、ホストの再起動時に、ゲストのネットワークアダプターが新しい MAC アドレスを持つと判断します。その結果、ゲストは毎回新しいハードウェアが接続されていると考え、通常はゲストのネットワーク設定を再設定する必要があります。
libvirt には、<interface type='hostdev'> インターフェイスデバイスが含まれます。このインターフェイスデバイスを使用すると、libvirt は、最初に、示されたネットワーク固有のハードウェアおよびスイッチの初期化 (MAC アドレス、VLAN タグ、802.1Qbh 仮想ポートパラメーターの設定など) を実行し、次にゲストに PCI デバイスを割り当てます。
<interface type='hostdev'> インターフェイスを使用するには、以下が必要です。
  • SR-IOV 対応のネットワークカード、
  • Intel VT-d 拡張機能または AMD IOMMU 拡張機能のいずれかに対応するホストハードウェア
  • 割り当てる VF の PCI アドレス。
重要
仮想マシンへの SR-IOV デバイスの割り当てには、ホストハードウェアが Intel VT-d または AMD IOMMU 仕様に対応している必要があります。
Intel または AMD システムに SR-IOV ネットワークデバイスを接続する場合は、以下の手順を行います。

手順16.8 Intel または AMD システムでの SR-IOV ネットワークデバイスの接続

  1. BIOS およびカーネルで、Intel VT-d または AMD IOMMU の仕様を有効にします。

    Intel システムでは、BIOS で Intel VT-d が有効になっていない場合は有効にします。BIOS およびカーネルで Intel VT-d を有効にする場合は、手順16.1「PCI デバイス割り当てのための Intel システムの準備」 を参照してください。
    Intel VT-d が既に有効で機能している場合は、この手順をスキップしてください。
    AMD システムでは、BIOS で AMD IOMMU 仕様が有効になっていない場合は有効にします。BIOS で IOMMU を有効にする方法は、手順16.2「PCI デバイス割り当て用の AMD システムの準備」 を参照してください。
  2. サポートの確認

    SR-IOV 機能のある PCI デバイスが検出されたかどうかを確認します。この例では、SR-IOV に対応する Intel 82576 ネットワークインターフェイスカードを一覧表示します。lspci コマンドを使用して、デバイスが検出されたかどうかを確認します。
    # lspci
    03:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    03:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    この出力は、その他のデバイスをすべて削除するように変更されていることに注意してください。
  3. 仮想機能のアクティブ化

    以下のコマンドを実行します。
    # echo ${num_vfs} > /sys/class/net/enp14s0f0/device/sriov_numvfs
  4. 仮想機能を永続化します。

    再起動後も仮想機能を永続化するには、選択したエディターを使用して、以下のような udev ルールを作成します。ここでは、ネットワークインターフェイスカードでサポートされている制限まで、予定している数の VF (この例では 2) を指定します。以下の例では、enp14s0f0 を PF ネットワークデバイス名に置き換え、ENV{ID_NET_DRIVER} の値を、使用中のドライバーに合わせて調整します。
    # vim /etc/udev/rules.d/enp14s0f0.rules
    ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="ixgbe",
    ATTR{device/sriov_numvfs}="2"
    
    これにより、システムの起動時に機能が有効になります。
  5. 新しい仮想機能の検査

    lspci コマンドを使用して、Intel 82576 ネットワークデバイスに追加した仮想機能の一覧を表示します。(もしくは、grep を使用して Virtual Function を検索し、仮想機能に対応するデバイスを検索します。)
    # lspci | grep 82576
    0b:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    0b:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
    0b:10.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.6 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:10.7 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.0 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.1 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.2 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.3 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.4 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    0b:11.5 Ethernet controller: Intel Corporation 82576 Virtual Function (rev 01)
    PCI デバイスの識別子は、lspci コマンドの -n パラメーターで確認できます。物理機能は、0b:00.0 および 0b:00.1 に対応します。説明には、すべての仮想機能のVirtual Functionが記載されています。
  6. デバイスが virsh で存在することを確認します。

    libvirt サービスは、仮想マシンにデバイスを追加する前にデバイスを認識する必要があります。libvirt は、lspci 出力と同様の表記を使用します。lspci出力内の句読点文字 (: および .) はすべて、アンダースコア (_) に変更されます。
    virsh nodedev-list コマンドと grep コマンドを使用して、利用可能なホストデバイスの一覧から Intel 82576 ネットワークデバイスをフィルターにかけます。0b は、この例題の Intel 82576 ネットワークデバイス用のフィルターです。これはシステムにより異なるため、デバイスが追加される可能性があります。
    # virsh nodedev-list | grep 0b
    pci_0000_0b_00_0
    pci_0000_0b_00_1
    pci_0000_0b_10_0
    pci_0000_0b_10_1
    pci_0000_0b_10_2
    pci_0000_0b_10_3
    pci_0000_0b_10_4
    pci_0000_0b_10_5
    pci_0000_0b_10_6
    pci_0000_0b_11_7
    pci_0000_0b_11_1
    pci_0000_0b_11_2
    pci_0000_0b_11_3
    pci_0000_0b_11_4
    pci_0000_0b_11_5
    仮想機能と物理機能の PCI アドレスがリストに含まれている必要があります。
  7. virsh でデバイスの詳細を取得する

    pci_0000_0b_00_0 は、物理機能のいずれかで、pci_0000_0b_10_0 は、その物理機能に対応する最初の仮想機能です。virsh nodedev-dumpxml を実行すると、両方のデバイスの情報が表示されます。
    # virsh nodedev-dumpxml pci_0000_03_00_0
    <device>
      <name>pci_0000_03_00_0</name>
      <path>/sys/devices/pci0000:00/0000:00:01.0/0000:03:00.0</path>
      <parent>pci_0000_00_01_0</parent>
      <driver>
        <name>igb</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>3</bus>
        <slot>0</slot>
        <function>0</function>
        <product id='0x10c9'>82576 Gigabit Network Connection</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <capability type='virt_functions'>
          <address domain='0x0000' bus='0x03' slot='0x10' function='0x0'/>
          <address domain='0x0000' bus='0x03' slot='0x10' function='0x2'/>
          <address domain='0x0000' bus='0x03' slot='0x10' function='0x4'/>
          <address domain='0x0000' bus='0x03' slot='0x10' function='0x6'/>
          <address domain='0x0000' bus='0x03' slot='0x11' function='0x0'/>
          <address domain='0x0000' bus='0x03' slot='0x11' function='0x2'/>
          <address domain='0x0000' bus='0x03' slot='0x11' function='0x4'/>
        </capability>
        <iommuGroup number='14'>
          <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
          <address domain='0x0000' bus='0x03' slot='0x00' function='0x1'/>
        </iommuGroup>
      </capability>
    </device>
    # virsh nodedev-dumpxml pci_0000_03_11_5
    <device>
      <name>pci_0000_03_11_5</name>
      <path>/sys/devices/pci0000:00/0000:00:01.0/0000:03:11.5</path>
      <parent>pci_0000_00_01_0</parent>
      <driver>
        <name>igbvf</name>
      </driver>
      <capability type='pci'>
        <domain>0</domain>
        <bus>3</bus>
        <slot>17</slot>
        <function>5</function>
        <product id='0x10ca'>82576 Virtual Function</product>
        <vendor id='0x8086'>Intel Corporation</vendor>
        <capability type='phys_function'>
          <address domain='0x0000' bus='0x03' slot='0x00' function='0x1'/>
        </capability>
        <iommuGroup number='35'>
          <address domain='0x0000' bus='0x03' slot='0x11' function='0x5'/>
        </iommuGroup>
      </capability>
    </device>
    この例では、手順 8 で作成した仮想マシンに、仮想機能 pci_0000_03_10_2 を追加します。仮想機能の busslot、および function パラメーターは、デバイスを追加するために必要です。
    このパラメーターは、/tmp/new-interface.xml などの一時 XML ファイルにコピーします。
       <interface type='hostdev' managed='yes'>
         <source>
           <address type='pci' domain='0x0000' bus='0x03' slot='0x10' function='0x2'/>
         </source>
       </interface>
    注記
    仮想マシンが起動すると、物理アダプターが提供するタイプのネットワークデバイスと、設定された MAC アドレスが表示されます。この MAC アドレスは、ホストおよびゲストの再起動後も変更されません。
    以下の <interface> の例は、オプションの <mac address><virtualport>、および <vlan> 要素のシンタックスを示しています。実際には、例にあるように、両方の要素を同時に使用するのではなく、<vlan> 要素または <virtualport> 要素のいずれかを使用します。
    ...
     <devices>
       ...
       <interface type='hostdev' managed='yes'>
         <source>
           <address type='pci' domain='0' bus='11' slot='16' function='0'/>
         </source>
         <mac address='52:54:00:6d:90:02'>
         <vlan>
            <tag id='42'/>
         </vlan>
         <virtualport type='802.1Qbh'>
           <parameters profileid='finance'/>
         </virtualport>
       </interface>
       ...
     </devices>
    MAC アドレスを指定しないと、MAC アドレスが自動的に生成されます。<virtualport> 要素は、802.11Qbh ハードウェアスイッチに接続する場合にのみ使用されます。<vlan> 要素は、VLAN タグ付けされた 42 に、ゲストのデバイスを透過的に配置します。
  8. 仮想マシンへの仮想機能の追加

    上の手順で作成した一時ファイルを使用し、次のコマンドを実行して仮想マシンに仮想機能を追加します。これにより、新しいデバイスがすぐに接続され、以降のゲストの再起動のために保存されます。
    virsh attach-device MyGuest /tmp/new-interface.xml --live --config
    
    virsh attach-device--live を指定すると、新しいデバイスが実行中のゲストに接続されます。--config オプションを使用すると、今後ゲストを再起動しても新しいデバイスを使用できるようになります。
    注記
    --live オプションは、ゲストが実行中の場合にのみ受け入れられます。--live オプションが実行されていないゲストで使用されると、virsh はエラーを返します。
仮想マシンが新しいネットワークインターフェイスカードを検出します。この新しいカードは、SR-IOV デバイスの仮想機能です。