16.7. GPU デバイスの割り当て

GPU をゲストに割り当てるには、以下の方法の 1 つを使用します。
  • GPU PCI デバイスの割り当て: この方法を使用すると、ホストから GPU デバイスを削除し、1 つのゲストに割り当てることができます。
  • NVIDIA vGPU の割り当て: この方法では、物理 GPU から複数の 媒介デバイス (mediated device) を作成することができ、これらのデバイスを仮想 GPU として複数のゲストに割り当てすることができます。これは一部の NVIDIA GPU でのみサポートされ、1 つの媒介 デバイスを 1 つのゲストのみに割り当てできます。

16.7.1. GPU PCI デバイスの割り当て

Red Hat Enterprise Linux 7 では、VGA 以外のグラフィックデバイスとして以下に記載されている PCI ベースの GPU デバイスの割り当てをサポートします。
  • NVIDIA Quadro K シリーズ、M シリーズ、および P シリーズ (モデル 2000 シリーズ以降)
  • NVIDIA GRID K シリーズ
  • NVIDIA Tesla K シリーズおよび M シリーズ
現在、標準のエミュレートされた VGA インターフェースのほかに、2 つまでの GPU を仮想マシンに割り当てることができます。エミュレートされた VGA は起動前およびインストールに使用され、NVIDIA グラフィックスドライバーがロードされると、NVIDIA GPU に引き継がれます。
GPU をゲスト仮想マシンに割り当てるには、IOMMU (I/O メモリー管理ユニット) をホストマシン上で有効にし、lspci コマンドを使用して GPU デバイスを特定する必要があります。さらに、デバイスの割り当てをホストから解除してゲストに割り当て、ゲストで Xorg を設定する必要もあります。以下の手順を参照してください。

手順16.13 ホストマシンカーネルの IOMMU サポートを有効にします。

  1. カーネルコマンドラインを編集します。

    Intel VT-d システムの場合、intel_iommu=on および iommu=pt パラメーターをカーネルコマンドラインに追加して IOMMU をアクティブにします。AMD-Vi システムの場合、必要なオプションは amd_iommu=pt になります。このオプションを有効にするには、以下のように GRUB_CMDLINX_LINUX 行を編集するか、これを /etc/sysconfig/grub 設定ファイルに追加します。
    GRUB_CMDLINE_LINUX="rd.lvm.lv=vg_VolGroup00/LogVol01
    vconsole.font=latarcyrheb-sun16 rd.lvm.lv=vg_VolGroup_1/root
    vconsole.keymap=us $([ -x /usr/sbin/rhcrashkernel-param ]  &&
    /usr/sbin/rhcrashkernel-param || :) rhgb quiet intel_iommu=on iommu=pt"

    注記

    IOMMU についての詳細は、付録E IOMMU グループの使用 を参照してください。
  2. ブートローダー設定の再生成

    カーネルコマンドラインの変更を適用するには、grub2-mkconfig を使用してブートローダーの設定を再生成します。
    # grub2-mkconfig -o /etc/grub2.cfg
    UEFI ベースのホストの場合、ターゲットファイルは /etc/grub2-efi.cfg であることに注意してください。
  3. ホストを再起動します。

    変更を反映するには、ホストマシンを再起動します。
    # reboot

手順16.14 GPU デバイスを、ホスト物理マシンドライバーへのバインドから除外する

GPU 割り当ての場合、ホストドライバーはデバイスの動的なバインド解除をサポートしないことが多いため、デバイスをホストドライバーへのバインドから除外することをお勧めします。
  1. PCI バスアドレスを特定します。

    PCI バスアドレスとデバイスの ID を特定するには、以下の lspci コマンドを実行します。この例では、NVIDIA Quadro または GRID カードなどの VGA コントローラーが使用されます。
    # lspci -Dnn | grep VGA
    0000:02:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK106GL [Quadro K4000] [10de:11fa] (rev a1)
    結果の検索は、このデバイスの PCI バスアドレスが 0000:02:00.0 であることを示し、デバイスの PCI ID が 10de:11fa であることを示しています。
  2. ネイティブのホストマシンドライバーが GPU デバイスを使用しないようにします。

    ネイティブのホストマシンドライバーが GPU デバイスを使用しないようにするには、pci-stub ドライバーで PCI ID を使用します。これを実行するには、/etc/sysconfig/grub 設定ファイルにある GRUB_CMDLINX_LINUX 行に、PCI ID を値として pci-stub.ids オプションを追加します。例を以下に示します。
    GRUB_CMDLINE_LINUX="rd.lvm.lv=vg_VolGroup00/LogVol01
    vconsole.font=latarcyrheb-sun16 rd.lvm.lv=vg_VolGroup_1/root
    vconsole.keymap=us $([ -x /usr/sbin/rhcrashkernel-param ]  &&
    /usr/sbin/rhcrashkernel-param || :) rhgb quiet intel_iommu=on iommu=pt pci-stub.ids=10de:11fa"
    pci-stub 用に追加の PCI ID を追加するには、単にそれらをコンマで区切ります。
  3. ブートローダー設定の再生成

    grub2-mkconfig を使用してブートローダー設定を再生成し、このオプションが含まれるようにします。
    # grub2-mkconfig -o /etc/grub2.cfg
    UEFI ベースのホストの場合、ターゲットファイルは /etc/grub2-efi.cfg であることに注意してください。
  4. ホストマシンを再起動します。

    変更を反映するために、ホストマシンを再起動します。
    # reboot

手順16.15 任意設定: GPU IOMMU 設定の編集

GPU デバイスを割り当てる前に、ゲスト上で GPU が適切に動作するよう IOMMU 設定の変更が必要になることがあります。
  1. GPU の XML 情報の表示

    GPU の設定を XML 形式で表示するには、最初に pci_ を追加し、区切り文字をアンダースコアに変換して、PCI バスアドレスを libvirt 対応の形式に変換する必要があります。たとえば、0000:02:00.0 バスアドレス (以前の手順 で取得) と特定される GPU PCI デバイスは pci_0000_02_00_0 になります。virsh nodedev-dumpxml でデバイスの libvirt アドレスを使用して、XML 設定を表示します。
    # virsh nodedev-dumpxml pci_0000_02_00_0
    
    <device>
     <name>pci_0000_02_00_0</name>
     <path>/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0</path>
     <parent>pci_0000_00_03_0</parent>
     <driver>
      <name>pci-stub</name>
     </driver>
     <capability type='pci'>
      <domain>0</domain>
      <bus>2</bus>
      <slot>0</slot>
      <function>0</function>
      <product id='0x11fa'>GK106GL [Quadro K4000]</product>
      <vendor id='0x10de'>NVIDIA Corporation</vendor>
         <!-- pay attention to the following lines -->
      <iommuGroup number='13'>
       <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
       <address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/>
      </iommuGroup>
      <pci-express>
       <link validity='cap' port='0' speed='8' width='16'/>
       <link validity='sta' speed='2.5' width='16'/>
      </pci-express>
     </capability>
    </device>
    XML の <iommuGroup> 要素に注目してください。iommuGroup は、IOMMU 機能および PCI バストポロジーのために他のデバイスから分離されているとみなされるデバイスのセットを示します。iommuGroup 内のすべてのエンドポイントデバイス (PCIe root ポート、ブリッジ、またはスイッチポートではないデバイス) は、ゲストに割り当てるためにネイティブのホストドライバーのバインドを解除する必要があります。上記の例では、グループは GPU デバイス (0000:02:00.0) およびコンパニオンオーディオデバイス (0000:02:00.1) で構成されています。詳細は、付録E IOMMU グループの使用 を参照してください。
  2. IOMMU 設定の調整

    この例では、レガシーの中断サポートにおけるハードウェアの問題が原因で、NVIDIA オーディオ機能の割り当てはサポートされません。さらに、通常 GPU 自体がないと GPU オーディオ機能は役に立ちません。よって、GPU をゲストに割り当てるには、最初にオーディオ機能のネイティブホストドライバーへの割り当てを解除する必要があります。これは、以下の方法の 1 つを使用して行えます。

手順16.16 GPU の割り当て

以下の方法の 1 つを使用して、GPU をゲストに割り当てできます。
  1. 仮想マシンマネージャー インターフェースを使用します。詳細は 「virt-manager を使用した PCI デバイスの割り当て」 を参照してください。
  2. GPU の XML 設定フラグメントを作成し、virsh attach-device で割り当てます。
    1. 以下のような XML をデバイス用に作成します。
      
      <hostdev mode='subsystem' type='pci' managed='yes'>
       <driver name='vfio'/>
       <source>
        <address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
       </source>
      </hostdev>
    2. これをファイルに保存し、virsh attach-device [domain] [file] --persistent を実行して XML がゲストの設定に含まれるようにします。ゲストマシン内の既存のエミュレートされたグラフィックスデバイスのほかに、割り当てられた GPU が追加されることに注意してください。割り当てられた GPU は、仮想マシン内のセカンダリーグラフィックスデバイスとして処理されます。プライマリーグラフィックスデバイスとしての割り当てはサポートされず、ゲストの XML 内のエミュレートされたグラフィックスデバイスは削除することができません。
  3. virsh edit コマンドを使用してゲストの XML 設定を編集し、適切な XML セグメントを手作業で追加します。

手順16.17 ゲスト上の Xorg 設定の編集

ゲスト上の GPU の PCI バスアドレスはホスト上のものとは異なります。ホストが GPU を適切に使用できるようにするには、割り当てられた GPU アドレスを使用するようゲストの Xorg 表示サーバーを設定します。
  1. ゲストで lspci コマンドを使用し、GPU の PCI バスアドレスを検出します。
    # lspci | grep VGA
    00:02.0 VGA compatible controller: Device 1234:111
    00:09.0 VGA compatible controller: NVIDIA Corporation GK106GL [Quadro K4000] (rev a1)
    この例では、バスアドレスは 00:09.0 になります。
  2. ゲストの /etc/X11/xorg.conf ファイルに BusID を追加し、検出したアドレスを次のように調整します。
    		Section "Device"
    		    Identifier     "Device0"
    		    Driver         "nvidia"
    		    VendorName     "NVIDIA Corporation"
    		    BusID          "PCI:0:9:0"
    		EndSection

    重要

    手順 1 で検出されたバスアドレスは 16 進数であるため、区切り文字の間にある値を 10 進数に変換する必要があります。たとえば、00:0a.0 は PCI:0:10:0 に変換する必要があります。

注記

ゲスト内で割り当てられた NVIDIA GPU を使用する場合、NVIDIA ドライバーのみがサポートされます。他のドライバーは機能せず、エラーを出す可能性があります。Red Hat Enterprise Linux7 ゲストの場合、nouveau ドライバーが、インストール時にカーネルコマンドラインでオプションの modprobe.blacklist=nouveau を使用することでブラックリスト化される可能性があることに注意してください。他のゲスト仮想マシンについての情報は、オペレーティングシステム固有のドキュメントを参照してください。
ゲストオペレーティングシステムに応じて、NVIDIA ドライバーがロードされた状態で、ゲストはエミュレートされたグラフィックスと割り当てられたグラフィックスの両方を同時にサポートするか、またはエミュレートされたグラフィックスを無効にすることができます。割り当てられたグラフィックスフレームバッファーは、virt-manager などのアプリケーションでは提供されないことに注意してください。割り当てられた GPU が物理ディスプレイに接続されていない場合、ゲストベースのリモートソリューションが GPU デスクトップにアクセスするために必要になる場合があります。すべての PCI デバイス割り当ての場合と同様、割り当てられた GPU を持つゲストの移行はサポートされておらず、それぞれの GPU は単一ゲストによって排他的に所有されます。ゲストオペレーティングシステムにより、GPU のホットプラグサポートを利用できる場合があります。

16.7.2. NVIDIA vGPU の割り当て

NVIDIA vGPU の機能は、物理 GPU デバイスを 媒介デバイス (mediated device) と呼ばれる複数の仮想デバイスに分割することができます。媒介デバイスは仮想 GPU として複数のゲストに割り当てすることができます。そのため、これらのゲストは 1 つの物理 GPU のパフォーマンスを共有します。

重要

この機能は、限定された NVIDIA GPU のセットでのみ使用できます。これらのデバイスの最新リストは、NVIDIA GPU ソフトウェアのドキュメント を参照してください。

NVIDIA vGPU の設定

vGPU を設定するには、最初に GPU デバイスの NVIDIA vGPU ドライバーを取得し、媒介デバイスを作成した後、目的のゲストマシンに割り当てる必要があります。
  1. NVIDIA vGPU ドライバーを取得し、システムにインストールします。手順は、NVIDIA のドキュメント を参照してください。
  2. NVIDIA ソフトウェアインストーラーが /etc/modprobe.d/nvidia-installer-disable-nouveau.conf ファイルを作成しなかった場合は、/etc/modprobe.d/ ディレクトリーに .conf ファイル (ファイル名は自由) を作成します。このファイルに以下の行を追加します。
    blacklist nouveau
    options nouveau modeset=0
  3. 現在のカーネルの初期 RAM ディスクを再生成し、再起動します。
    # dracut --force
    # reboot
    サポートされる以前のカーネルバージョンを媒介デバイスに使用する必要がある場合、インストールされたすべてのカーネルバージョンの初期 RAM ディスクを再生成します。
    # dracut --regenerate-all --force
    # reboot
  4. nvidia_vgpu_vfio モジュールがカーネルによってロードされ、nvidia-vgpu-mgr.service サービスが稼働中であることを確認します。
    # lsmod | grep nvidia_vgpu_vfio
    nvidia_vgpu_vfio 45011 0
    nvidia 14333621 10 nvidia_vgpu_vfio
    mdev 20414 2 vfio_mdev,nvidia_vgpu_vfio
    vfio 32695 3 vfio_mdev,nvidia_vgpu_vfio,vfio_iommu_type1
    # systemctl status nvidia-vgpu-mgr.service
    nvidia-vgpu-mgr.service - NVIDIA vGPU Manager Daemon
       Loaded: loaded (/usr/lib/systemd/system/nvidia-vgpu-mgr.service; enabled; vendor preset: disabled)
       Active: active (running) since Fri 2018-03-16 10:17:36 CET; 5h 8min ago
     Main PID: 1553 (nvidia-vgpu-mgr)
     [...]
  5. デバイス UUID を /sys/class/mdev_bus/pci_dev/mdev_supported_types/type-id/create に書き込みます。pci_dev はホスト GPU の PCI アドレスに置き換え、type-id はホスト GPU タイプの ID に置き換えます。
    以下の例は、NVIDIA Tesla P4 カード上に nvidia-63 vGPU タイプの媒介デバイスを作成する方法を表しています。
    # uuidgen
    30820a6f-b1a5-4503-91ca-0c10ba58692a
    # echo "30820a6f-b1a5-4503-91ca-0c10ba58692a" > /sys/class/mdev_bus/0000:01:00.0/mdev_supported_types/nvidia-63/create
    特定のデバイスの type-id 値については、仮想 GPU ソフトウェアのドキュメント の「section 1.3.1. Virtual GPU Types」を参照してください。GRID P4-2Q などの Q シリーズの NVIDIA vGPU のみが GPU タイプの媒介デバイスとして Linux ゲストでサポートされることに注意してください。
  6. 以下の行を、vGPU リソースを共有するゲストの XML 設定にある <devices/> セクションに追加します。前のステップで uuidgen コマンドによって生成された UUID 値を使用します。各 UUID は 1 度に 1 つのゲストのみに割り当てできます。
    
    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci'>
      <source>
        <address uuid='30820a6f-b1a5-4503-91ca-0c10ba58692a'/>
      </source>
    </hostdev>
    

    重要

    vGPU の媒介デバイスが割り当てられたゲストで適切に動作するようにするには、ゲストに NVIDIA vGPU ゲストのソフトウェアライセンスを設定する必要があります。詳細および手順は、NVIDIA 仮想 GPU ソフトウェアのドキュメント を参照してください。

NVIDIA vGPU デバイスの削除

媒介の vGPU デバイスを削除するには、デバイスがアクティブでない状態で以下のコマンドを使用します。uuid はデバイスの UUID に置き換えます (例: 30820a6f-b1a5-4503-91ca-0c10ba58692a)。
# echo 1 > /sys/bus/mdev/devices/uuid/remove
ゲストが現在使用している vGPU デバイスを削除しようとすると、以下のエラーが発生します。
echo: write error: Device or resource busy

NVIDIA vGPU 機能のクエリー

指定タイプの媒介デバイスをいくつ作成できるかなど、システムの媒介デバイスに関する追加情報を取得するには、virsh nodedev-list --cap mdev_types または virsh nodedev-dumpxml コマンドを使用します。たとえば、以下は Tesla P4 カードで利用可能な vGPU タイプを表示します。

$ virsh nodedev-list --cap mdev_types
pci_0000_01_00_0
$ virsh nodedev-dumpxml pci_0000_01_00_0
<...>
  <capability type='mdev_types'>
    <type id='nvidia-70'>
      <name>GRID P4-8A</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>1</availableInstances>
    </type>
    <type id='nvidia-69'>
      <name>GRID P4-4A</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>2</availableInstances>
    </type>
    <type id='nvidia-67'>
      <name>GRID P4-1A</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>8</availableInstances>
    </type>
    <type id='nvidia-65'>
      <name>GRID P4-4Q</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>2</availableInstances>
    </type>
    <type id='nvidia-63'>
      <name>GRID P4-1Q</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>8</availableInstances>
    </type>
    <type id='nvidia-71'>
      <name>GRID P4-1B</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>8</availableInstances>
    </type>
    <type id='nvidia-68'>
      <name>GRID P4-2A</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>4</availableInstances>
    </type>
    <type id='nvidia-66'>
      <name>GRID P4-8Q</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>1</availableInstances>
    </type>
    <type id='nvidia-64'>
      <name>GRID P4-2Q</name>
      <deviceAPI>vfio-pci</deviceAPI>
      <availableInstances>4</availableInstances>
    </type>
  </capability>
</...>

NVIDIA vGPU のリモートデスクトップストリーミングサービス

Red Hat Enterprise Linux 7 上の NVIDIA vGPU 機能とテスト済みのリモートデスクトップストリーミングサービスは次のとおりです。
  • HP-RGS
  • Mechdyne TGX: 現在 Windows Server 2016 ゲストで Mechdyne TGX を使用することはできません。
  • NICE DCV: このストリーミングサービスを使用する場合、動的解像度を使用すると真っ黒な画面が表示されることがあるため、Red Hat は固定解像度設定の使用を推奨します。