Разговор пойдёт об AMD APU Ryzen 3 2200G, Ryzen 5 2400G и подобных им.
В обсуждениях на англоязычных форумах упоминается, что iGPU Vega10 более
технологически продвинут, и, в принципе, он может быть использован как
ведущий адаптер для dGPU предыдущих версий GCN 1,2,3 в рамках модели
памяти iGPU Vega10 (GCN 5).
Однако, с одной стороны это потребует большое количество человеко-часов для
написания таких драйверов под OS Linux. А, с другой стороны, новые адаптеры
линии RDNA полностью соответствуют этой модели памяти. И, в принципе,
состыковка iGPU Vega10 с dGPU RDNA, есть задача более простая и более перспективная.
Поэтому, в ближайшее время нормальной состыковки видеокарт GCN 1,2,3 и iGPU
Vega10 (GCN 5) в Linux, судя по всему, ожидать не приходится.
Соответственно, всё, что описано далее, это воркэраунд для сложившейся ситуации.
Пошаговая инструкция
Вот работоспособная конфигурация:
(01) Устанавливаем Fedora 31 (я использовал версию с MATE GUI).
Не забываем сразу добавить пользователя в группу video .
(02) Загружаем пакет kernel-5.3.16-300.fc31.src.rpm, и разворачиваем его для
компиляции в ${HOME}/rpmbuild/SOURCES/
(03) Идём на страничку
https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/issues/66 и загружаем
оттуда патч под нашу версию ядра
0003-allows-to-choose-iGPU-or-dGPU-memory-management-mode.patch.txt
по ссылке
https://github.com/RadeonOpenCompute/ROCK-Kernel-Driver/files/3614247/0003-allows-to-choose-iGPU-or-dGPU-memory-management-mode.patch.txt
Попутно читаем на английском про особенности работы встроенной карты, там много удивительного.
Выжимка, кому интересно, иначе можно пропустить:
модель памяти у iGPU и dGPU различна;
драйвер amdkfd по умолчанию использует модель памяти адаптера, проинициализировавшегося первым;
не смотря на то, что dGPU может быть первым и будет использована его модель
памяти, тем не менее iGPU Vega10 более технологически продвинут и именно он
получит первый номер во внутреннем дереве топологии драйвера amdkfd, что в
общем-то неправильно, так как карта адаптеров и фактическое их наличие не будут
соответствовать друг другу. Как результат, оба GPU будут нерабочими в ROCm (и
не только в нём);
двое разработчиков ROCm под никами fxkamd и Djip007 сформировали патч
для драйвера amdkfd, позволяющий на этапе загрузки ядра сказать драйверу
amdkfd, какую модель памяти использовать и какие адаптеры допустимы в дереве
топологии amdkfd, скажем "Большое Спасибо!" им за это.
(04) Копируем патч в каталог ${HOME}/rpmbuild/SOURCES/
$ cp 003-allows-to-choose-iGPU-or-dGPU-memory-management-mode.patch.txt ${HOME}/rpmbuild/SOURCES/003-allows-to-choose-iGPU-or-dGPU-memory-management-mode.patch
Исправляем в kernel.spec
%global baserelease 300
на произвольное большее
%global baserelease 307
Добавляем в kernel.spec после описания всех патчей, после строки
Patch536: .....
строку с описанием нового патча
Patch537: 0003-allows-to-choose-iGPU-or-dGPU-memory-management-mode.patch
как раз перед строкой
# END OF PATCH DEFINITIONS
Делаем линк kernel.spec:
$ cd ${HOME}/rpmbuild/SPECS/
$ ln ../SOURCES/kernel.spec
Запускаем сборку пакетов ядра с патчем:
$ rpmbuild -ba --nodebuginfo --target x86_64-redhat-linux --define "%_without_debug 1" --define "%set_build_flags echo" --define "%make_build make" --define "%make_install make install DESTDIR=%{buildroot}" kernel.spec
Внимание, потребуется много места на диске!
В моём случае сборки для x86_64 конфигов это было около 27 GB временных файлов.
По завершении сборки в директории ${HOME}/rpmbuild/RPMS/x86_64/
будут лежать новые пакеты:
kernel-5.3.16-307.fc31.x86_64.rpm
kernel-core-5.3.16-307.fc31.x86_64.rpm
kernel-debuginfo-5.3.16-307.fc31.x86_64.rpm
kernel-debuginfo-common-x86_64-5.3.16-307.fc31.x86_64.rpm
kernel-devel-5.3.16-307.fc31.x86_64.rpm
kernel-modules-5.3.16-307.fc31.x86_64.rpm
kernel-modules-extra-5.3.16-307.fc31.x86_64.rpm
Устанавливаем это новое ядро и его модули (естественно, с опцией --nogpgcheck).
(05) Обновляем загружаемый микрокод для видеокарт:
# dnf upgrade linux-firmware libclc
(06) Добавляем в настройки dracut несколько опций
# cat /etc/dracut.conf.d/my20200224.conf
add_drivers+=" amd_iommu_v2 amdgpu nvme_core nvme "
fw_dir+=" /lib/firmware/amdgpu "
install_items+=" /lib/firmware/amdgpu/raven_* /lib/firmware/amdgpu/polaris* "
(07) Аккуратно настраиваем X-сервер в /etc/X11/xorg.conf.
Чтобы он видел dGPU как первичный адаптер, а iGPU , как вторичный адаптер без экрана.
Однако к монитору iGPU должен быть подключен физически (или к его HW-эмулятору).
Создаём шаблон xorg.conf командой:
# X -configure
Затем копируем его в /etc/X11/xorg.conf и редактируем, оставляя:
Layout0 с двумя картами Card0 и Card1
Card0 это первичный dGPU с монитором и экраном, с точным указанием BusID
Card1 это вторичный iGPU без монитора и без экрана, с точным указанием BusID
Например:
Section "Device"
# dGPU
Identifier "Card0"
Driver "amdgpu"
BusID "PCI:1:0:0"
Option "TearFree" "True"
Option "Accel" "True"
EndSection
Section "Device"
# iGPU
Identifier "Card1"
Driver "amdgpu"
BusID "PCI:9:0:0"
EndSection
Ваши GPU могут иметь другие номера на шине pci, смотрим командой:
# lspci -v
.....
Пропускаем секции "Monitor1" и "Screen1" для iGPU в нашем случае, как это
регламентировано в мануале для xorg.conf.
Просто комментируем соответствующие разделы:
#Section "Monitor"
# Identifier "Monitor1"
.....
#Section "Screen"
# Identifier "Screen1"
.....
(08) Добавляем опцию для kfd из рекомендаций установки ROCm:
# cat /etc/udev/rules.d/70-kfd.rules
SUBSYSTEM=="kfd", KERNEL=="kfd", TAG+="uaccess", GROUP="video", MODE="0660"
Это позволит работать с dGPU пользователю из группы video.
(09) Перегенерим initramfs:
# dracut --force --kver 5.3.16-307.fc31.x86_64
(10) Добавляем в настройки grub2 несколько опций ядра для загрузки:
amd_iommu=fullflush iommu=pt video=efifb:off amdgpu.rocm_mode=2
(11) Дополнительно, устанавливаем воркэраунд от некогерентности кэша для GCN 1,2,3,5 видеокарт:
# cat /etc/environment
AMD_DEBUG=nongg,nodma
RADV_DEBUG=nongg
DRI_PRIME=0
К сожалению, воркэраунды снижают производительность от 1.5 до 15 раз (судя по
тесту Glmark2), но зато дают стабильность GUI-десктопу.
Для RDNA 1,2 видеокарт вроде бы это не нужно, но я не проверял, так как не на чем.
Перезагружаемся.
(12) Настраиваем в EFI dGPU как первичную видеокарту, а iGPU, соответственно,
становится вторичной видеокартой, урезаем ей RAM до 64 MB. Загружаемся.
Вот и всё.
Проверка
Теперь проверяем корректность результата.
# dmesg | grep -i -e amdgpu -e kfd -e drm -e ttm -e atomic -e crat
.....
[ 3.414606] kfd kfd: Ignoring ACPI CRAT on disabled iGPU (rocm_mode!=ROCM_MODE_IGPU)
.....
[ 3.667325] kfd kfd: added device 1002:wxyz
.....
[ 3.733956] kfd kfd: skipped DID 15dd, don't support dGPU memory management models
.....
Выбрана модель памяти для dGPU, добавление iGPU в топологию kfd пропущено, а
топология kfd для dGPU сформирована правильно.
# lspci -nnk -d 1002:
01:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] .....
Subsystem: .....
Kernel driver in use: amdgpu
Kernel modules: amdgpu
09:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Raven Ridge [Radeon Vega Series / Radeon Vega Mobile Series] [1002:15dd] (rev c8)
Subsystem: .....
Kernel driver in use: amdgpu
Kernel modules: amdgpu
09:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Raven/Raven2/Fenghuang HDMI/DP Audio Controller [1002:15de]
Subsystem: .....
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel
Всем видны оба видео-адаптера AMD на pci шине: и dGPU и iGPU.
Важно, чтобы неиспользуемый iGPU контроллировался ядерным драйвером amdgpu.
Если этого не будет (например, можно удалить устройства из дерева pci
средствами udev на раннем этапе загрузки), то iGPU будет сильно греть APU (max
75*C вместо max 60*C). И это при том, что сам iGPU вообще не будет никак
использоваться. Может возникнуть впечатление, что появились проблемы с кулером
APU, но это не так.
$ less /var/log/Xorg.0.log
[ 15.962] (**) ServerLayout "Layout0"
[ 15.962] (**) |-->Screen "Screen0" (0)
[ 15.962] (**) | |-->Monitor "Monitor0"
[ 15.962] (**) | |-->Device "Card0"
[ 15.962] (**) | |-->GPUDevice "Card1"
[ 15.962] (**) |-->Input Device "Mouse0"
[ 15.962] (**) |-->Input Device "Keyboard0"
.....
[ 15.964] (II) xfree86: Adding drm device (/dev/dri/card0)
[ 15.970] (II) xfree86: Adding drm device (/dev/dri/card1)
[ 15.973] (--) PCI:*(1@0:0:0) .....
[ 15.973] (--) PCI: (9@0:0:0) .....
.....
[ 15.979] (II) LoadModule: "amdgpu"
[ 15.980] (II) Loading /usr/lib64/xorg/modules/drivers/amdgpu_drv.so
.....
[ 15.983] (II) AMDGPU: Driver for AMD Radeon:
All GPUs supported by the amdgpu kernel driver
[ 15.983] (II) modesetting: Driver for Modesetting Kernel Drivers: kms
[ 15.983] (II) AMDGPU(0): [KMS] Kernel modesetting enabled.
.....
Т.е. видим, что X-сервер обнаружил обе видеокарты, но активно использует только
одну и именно дискретную видеокарту.
Далее можем, например, установить ROCm 3 _без_ dkms драйвера в соответствие с родной инструкцией:
# dnf install rocm-dev rocm-libs
Следующие программы дополнительно покажут корректность описанной выше пошаговой настройки.
rocm-smi нормально отображает всю статистику по dGPU и управляет ею.
rocminfo отрабатывает без ошибок и отображает 2 вычислительных агента CPU и gfx803.
clinfo отрабатывает без ошибок и отображает 1 платформу AMD-APP и 1
устройство gfx803 (не считая Mesa Clover и Pocl).
hashcat видит устройство и работает нормально. (Самосборный пакет из
оригинальных исходников, т.к. из репозитория Fedora 31 сборка имеет урезанную
функциональность и проблемы с запуском.)
Компилятор AOMP в составе ROCm 3.1 проходит успешно 67 тестов из 69 из
приложенного набора тестов smoke.
vainfo , vdpauinfo отрабатывают нормально.
Итоги
В результате настройки получаем устойчивый GUI-десктоп с корректно работающим
dGPU и с условно корректно отключенным, "не используемым" iGPU.
Дополнительно
PS:
Пока удалось нарушить работу dGPU, только используя в Avidemux HW-кодер "Intel AVC HW (VA)".
В то же время HW-кодер "Intel HEVC" в Avidemux работает довольно быстро.
А "Intel H264" не работает совсем, и, судя по всему, встройка тут не при чём.
Запуск командой:
$ ( DRI_PRIME=1 avidemux3_qt5 )
позволяет использовать встроенные HW-кодеры "не используемого" iGPU, работают они примерно так же.
PPS:
В принципе, в ядро 5.6 были добавлены полезные патчи для Raven iGPU, и, с
применением воркэраунда для Mesa 19.2.8
# cat /etc/environment
AMD_DEBUG=nongg,nodma,nodcc
RADV_DEBUG=nongg
DRI_PRIME=0
стало возможным использовать Raven iGPU как первичную видеокарту в EFI, а dGPU
использовать вторичной видеокартой.
Соответственно, просто меняем местами BusID карт в xorg.conf , и включаем
вторичную dGPU в MATE: меню System -> Control Center -> Displays -> второй
дисплей , ON , Applay , Close (настройка сохраняется в ${HOME}/.config/dconf/).
В этом случае производительность dGPU в графике снижается.
Зато появляется возможность работать с tensorflow-rocm при 100% нагрузке dGPU
без замираний первичного экрана, и наблюдать происходящее в процессе.
И, однако, попутно выясняется, что ядро 5.6.8 (со своим таким же патчем с той
же веб-странички) _не_ загружается с primary dGPU в EFI.
Возможно, что для сочетаний конкретных APU и MainBoard это вылечится
обновлением Grub2 до актуальной версии.
Вероятно, старая версия Grub2 неправильно транслирует какие-то параметры ядру из EFI.
Этот момент и более поздние версии ядер 5.6.n и 5.7.n , пардон, проверить не
успел, т.к. заапгрейдил APU на обычный CPU Ryzen без iGPU.
Перспективы
Общие соображения, которые с одной стороны можно было бы и не добавлять в
статью, а с другой, почему бы и не добавить.
Судя по всему, RDNA 1 и 2 как архитектуры GPU есть шаги по направлению к
когерентной архитектуре Gen-Z.
Это означает, что:
основной свичованой шиной станет CCIX как приоритезированный PCIe Gen4 (и выше)
RAM будет выделена в отдельные модули на CCIX-шине
контроллер памяти будет в диспетчере и каждом модуле RAM
кэши CPU, GPU, RAM, плат расширения будут когерентны
IOMMUv2 (или выше) будет обязателено by design
GPU станут более самостоятельными относительно CPU (как вычислительные устройства)
iGPU / APU не вполне вписываются в эту концепцию
Выводы, конечно же, каждый сделает сам.
|