Проброс видеокарты с помощью VFIO может быть знаком немногим, но по факту является очень удобным способом решить ряд насущных задач и упростить рабочий процесс в целом. В этом проекте мы настроим нужную конфигурацию из под Fedora 34 и поочередно пробросим две разные видеокарты в VM, попутно оценив полученную производительность.
Вступление
Прежде чем перейти ко всем подробностям, хочу вкратце описать, с чем вообще мы будем иметь дело, так как эти темы могут оказаться для вас незнакомыми. Технология VFIO является достаточно нишевой, и о ней мало кто знает.
- Проброс GPU: процесс, в котором виртуальной машине (VM) предоставляется в пользование выделенная видеокарта. Это позволяет выполнять внутри VM рабочие нагрузки, ориентированные на GPU, например, игры или иные задачи, опирающиеся на производительность GPU.
- VFIO: фреймворк, позволяющий выполнить эту операцию.
- IOMMU: аппаратная особенность, которая все это поддерживает.
- virt-manager: приложение GUI, через которое я управляю VM.
Какой вообще смысл заморачиваться и реализовывать подобное?
- Вы пользуетесь Linux, но хотите иногда запускать игры без перезагрузки под Windows.
- Вы хотите выполнять все рабочие, игровые и серверные процессы на одной машине.
- Вы просто не хотите собирать выделенный ПК под игры и предпочтете задействовать имеющиеся ресурсы на основной машине.
- Вам нужно больше контроля над установкой Windows, потому что Microsoft вы не доверяете.
- Вам нужно больше контроля над установкой Windows, а также возможность возвращать этот процесс к более ранней точке, используя файловую систему с поддержкой снимков состояния (BTRFS, ZFS).
- У вас есть несколько отдельных VM для разных целей, но вы хотите задействовать один GPU для всех.
При этом нужно помнить, что используемое вами аппаратное обеспечение играет здесь важную роль, поскольку является основой работоспособности всего решения. Вот некоторые из требований, которые необходимо учесть:
- Видеокарта, которую вы хотите пробросить, должна поддерживать UEFI. Ускорители, выпущенные в течение последних пяти лет, должны такую поддержку иметь. Если же у вас старенькая модель, которую вы хотите использовать для тестирования, то она может показать себя недостаточно хорошо.
- Вам понадобится достаточно мощный CPU и большой объем RAM, так как, по сути, вы будете запускать отдельный ПК внутри основного.
- Материнская плата должна поддерживать IOMMU и иметь группы IOMMU, позволяющие изолировать GPU и передать в распоряжение VM только его. Ребята на канале Level1Techs делают много обзоров на материнские платы, и Венделл, в том числе, обсуждает группы IOMMU, а также пригодность плат для VFIO. Также не будет лишним поискать в интернете энтузиастов, которые уже купили такую плату. Есть вероятность, что они поделились информацией о поддержке в ней IOMMU. Вот неплохой скрипт, который позволит выполнить проверку доступности групп IOMMU.
- Некоторые игры могут накладывать бан, если обнаружат запуск из-под VM. Это здорово, что в них реализована защита от читерства, но, к сожалению, пользователи VFIO в данном случае страдают несправедливо.
Так что, если вы много играете в соревновательные игры, то лучше прояснить этот момент заранее.
Надеюсь, что данное введение помогло вам понять, что к чему. Теперь же окунемся в сам процесс.
Настройка
Мы будем тестировать эту конфигурацию на оборудовании, о котором я уже писал. Особенность данной конфигурации в том, что мы используем AMD Ryzen 7 5700 APU на материнской плате mITX и один выделенный GPU. Это дает нам большие возможности в малых масштабах.
Да, существуют конфигурации, в которых можно реализовать VFIO с помощью одного GPU и пробросить его между основной ОС и VM, но такой конфиг будет сложновато использовать.
В качестве ОС у меня стоит Fedora 34. Для того чтобы все наладить, я воспользовался несколькими ресурсами:
- Руководство начинающего с форумов Level1Techs.
- Руководство по Fedora от Венделла из Level1Techs
- Прекрасное Wiki-руководство по Arch, где освещается большая часть из того, что нужно знать о настройке всего необходимого. Причем это руководство полезно не только для Arch, так как многое из описанного в нем применимо к любому дистрибутиву.
Тестирование
Начальное тестирование я решил произвести с Nvidia GT710. Она медленная, плохо работает под Linux с опен-сорсными драйверами Nouveau, но зато оказалась под рукой. Еще я недавно услышал, что Nvidia все-таки повернулись лицом к клиентам, позволив использовать видеокарты GeForce в VM Windows 10 без костылей.
Сам процесс тестирования относительно прост. Единственные сложности, с какими я столкнулся – это проблемы PEBCAK. Возможно, причина была в том, что тестированием я занимался уже после работы. Основная проблема – это небольшие опечатки в конфигурации dracut
или ошибки в ID устройств, добавляемых в параметры загрузки ядра. Когда я это выяснил и исправил, процесс пошел как по маслу.
Все руководство я здесь переписывать не стану – если вас заинтересуют дополнительные детали, прошу обратиться к приведенным выше ресурсам. К тому же эти ресурсы наверняка будут оперативнее обновляться в случае каких-либо нововведений или появления дополнительных возможностей.
Что касается самого процесса, то в общих чертах нужно проделать следующее:
- Убедится, что IOMMU активирована в настройках UEFI. По умолчанию эта опция наверняка установлена на
auto
, так что обязательно переключите наenabled
. - Установить видеокарту, которую планируете пробрасывать, и подключить к ней монитор.
- Установить в Fedora пакеты виртуализации:
sudo dnf install @virtualization
. - Включить IOMMU и предварительно загрузить модуль ядра VFIO, добавив в параметры загрузки
amd_iommu=on rd.driver.pre=vfio-pci
.- Я использую GRUB2, так что эти параметры находятся в
/etc/sysconfig/grub
. - Для применения изменений нужно повторно сгенерировать конфигурацию GRUB. Из-под Fedora это делается с помощью
grub2-mkconfig -o /etc/grub2-efi.cfg
- Я использую GRUB2, так что эти параметры находятся в
- Получить ID устройств для видеокарты и связанного аудиоустройства, которые планируется пробрасывать.
- Чтобы просмотреть устройства и их ID, выполните
lspci -nnk
. ID будут выглядеть как1002:aaf0
.
- Чтобы просмотреть устройства и их ID, выполните
- Привяжите GPU к
vfio-pci
, чтобы избежать перехвата драйвером видеокарты управления ей. В противном случае пробросить видеокарту в VM не удастся.- Я решил пойти простым путем и добавил ID устройств в параметры ядра:
vfio-pci.ids=1002:67df,1002:aaf0
. - В связи с этим мне пришлось еще раз сгенерировать конфигурацию GRUB.
- Я решил пойти простым путем и добавил ID устройств в параметры ядра:
- Убедитесь, что
initramfs
загружает необходимые драйверыvfio
на ранней стадии загрузки.- В случае с Fedora 34 это означает создание файла
/etc/dracut.conf.d/10-vfio.conf
с содержимымadd_drivers+=" vfio_pci vfio vfio_iommu_type1 vfio_virqfd "
. - Убедитесь в отсутствии опечаток.
- Повторно сгенерируйте
initramfs
:dracut -f
.
- В случае с Fedora 34 это означает создание файла
- Перезагружайте!
- Используя
virt-manager
, выберите VM, которой хотите пробросить видеокарту, и добавьте два устройства PCIe: видеокарту и связанное с ней аудиоустройство.- Если VM у вас еще не настроена, то перейдите к стандартной установке пока без проброса. Не забудьте создать UEFI VM, иначе могут возникнуть проблемы. Настроить это можно в разделе «_Overview_»
virt-manager
путем выбора чипсета Q35 и установки прошивки наOVMF_CODE.df
. - Если вы пробросили GPU, то не забудьте удалить из VM устройство
Display Spice
. - Если вам также нужен контроль над VM, то нужно дополнительно пробросить USB-устройства, например, беспроводной приемник Logitech.
- Если VM у вас еще не настроена, то перейдите к стандартной установке пока без проброса. Не забудьте создать UEFI VM, иначе могут возникнуть проблемы. Настроить это можно в разделе «_Overview_»
- Запустите VM и можете быть довольны, если на экране подключенного к проброшенной видеокарте монитора появится эмблема TianoCore.
Если вы это видите, значит, проброс выполнен успешно. Поздравляю!
Результаты для Nvidia GT 710
Начальное тестирование с Nvidia GT710 прошло успешно. Под «успешно» я подразумеваю, что видеокарта вывела изображение без автоматической установки своих драйверов.
Печально известный код ошибки Nvidia: 43
Чтобы исправить эту проблему, я скачал последние официальные драйверы Nvidia, чего оказалось достаточно – ошибка 43 исчезла.
Если ваша видеокарта исправно отображается в Device Manager, то все в порядке.
Однако веселья поубавилось, когда стало очевидно, что моя видеокарта слаба. Очень слаба. Несмотря на это, я решил продемонстрировать ее вычислительную удаль, скачав демку Art of Rally.
Примечание: игра просто улетная, обязательно попробуйте!
И демка запустилась! Не идеально, но все же запустилась.
Не передается: ужасная частота кадров.
Удовлетворенный результатами, я решил пойти до конца и заменить эту карту на AMD RX570, которую «одолжил» у недавно собранного ПК.
Результаты для AMD RX 570
Переставив видеокарту, я поменял ID устройств на новые значения и продолжил приключение с VFIO. На этот раз Windows автоматически установила драйверы видео, и все заработало сходу. Хотя это меня удивило, так как в моем опыте всегда что-то да идет не так. Всегда.
Я установил последние драйверы с сайта AMD и продолжил тестирование.
Furmark? Работает ожидаемым образом.
VM слева, показатели быстродействия VM справа, куча кабелей повсюду
GTA IV? Лагает не по-детски, но работает.
Слева: GTA IV напрямую с GPU. Справа: стриминг GTA IV через Parsec
В этой ситуации VM получила 4 ядра CPU, и я не делал ни привязки потоков к процессору, ни каких-либо оптимизаций, так что результат получился неплохой.
Хранилище
Так как я собрал этот конфиг на своей текущей рабочей/серверной машине, ситуация с хранилищем оказалась витиеватой. Другая VM, которая выполняет все службы, имеет полный доступ к двум дискам по 12Тб, а сетевое хранилище мне настраивать не хотелось. Единственными свободными точками у меня были:
- Раздел 120Гб на NVMe SSD. Достаточно для хранения системных файлов Windows 10.
- 2 раздела по 250Гб на SATA 1TB SSD. Как раз впору для хранения моих недавних игр, но не более. Настроены в чередующейся конфигурации под Windows.
Позже я решил расширить разделы под хранение игр до 375Гб, для чего потребовалось избавиться от дополнительного резервного пространства. Такая настройка вполне неплоха, но я теряю некоторые выгоды от виртуализации Windows.
Относительно передачи этого хранилища VM у меня было два варианта:
- Продолжить использовать виртуальный диск SATA: работает из коробки, но может проседать в производительности.
- Использовать
virtio
: необходимо вручную загрузить и установить драйверы для распознания этих дисков Windows, хотя быстродействие должно оказаться выше, чем в случае с SATA.
Я начал с SATA и провел сравнение с virtio
при помощи CrystalDiskMark.
Слева: SATA. Справа: virtio
Virtio несколько вырвался вперед в этих сравнениях, но меня бы наверняка устроила и производительность SATA.
Заключение
Одна из основных причин, по которым я настраиваю подобные сборки – это сам процесс воплощения технической идеи. Звучит странно, но иногда меня больше радует сам факт успешного завершения технической части и реализация чего-то нового, чем реальное дальнейшее использование этого.
Ранее я получил смешенный результат проброса видеокарты на ноутбуке ThinkPad T430 с eGPU, умудрившись запустить на виртуальной машине GTA V, хотя в другой тестовой сессии возникли проблемы, вызванные, как оказалось, дефектом CPU (множество ошибок PCIe).
В дальнейшем я планирую продолжить подобные эксперименты. Хочу задействовать эту VM в качестве игровой, чтобы стримить с нее игры через Parsec на любое устройство. Один из вариантов – это использовать Nvidia Shield TV в качестве маломощного блока, способного выполнять стриминг. В качестве альтернативы можно сделать сборку на базе миниатюрного ПК Dell/Lenovo/HP, который имеет достаточно мощи для работы с 4K дисплеем, потребляя при этом не так много энергии. Подробнее об этом в будущих постах.
Что касается хранилища, то я планирую его скорый апгрейд. Либо поменяю только диски, либо обновлю всю сборку, так как ATX-платы поддерживают больше SATA подключений и карт расширений. Если еще вписать все это в корпус типа Masterbox Q500L, снарядив его хорошим БП, то даже тогда получится все еще относительно небольшая конфигурация.