Я пишу это по нескольким причинам: чтобы лучше понимать проблему самому (я до сих пор толком не разобрался), чтобы не принимать самое простое решение как правильное, чтобы задокументировать проблему для сообщества, чтобы люди не тратили время на просмотр нерелевантной информации, и чтобы в будущем, когда я перейду к чему-то другому и забуду об этом, у меня был хороший источник информации, к которому можно было бы обращаться (у меня уже все вкладки в браузере на пределе...).
Если у вас есть GPU с >= 24 ГБ памяти и вы используете OVMF (EUFI) и используете PCI Passthrough для VM, вы сможете увидеть устройство с помощью lspci -v, сможете установить драйвер, но драйвер не загрузится, и вы увидите следующее сообщение об ошибке при попытке загрузки:
```
Code: [22.345395] kernel: NVRM: This PCI I/O region assigned to your NVIDIAdevice is invalid:
NVRM: BAR0 is 0M @ 0x0 (PCI:0000:48:00.0)
[22.348443] kernel: NVRM: The system BIOS may have misconfigured your GPU.
```
Proxmox 8.4.1 (последняя версия на 2024/04/12), несколько GPU (Nvidia V100, L40S, A100, H100). VM-хосты, на которых я развертываю и тестирую, работают на RHEL9.4. Использую различные Intel Xeon 4xxx, 6xxxx процессоры на платформах Dell (R750) и Supermicro (X13). Я потратил около двух дней на исследование этой проблемы и до сих пор не знаю всего о ней, но всё ещё учусь.
Неважно, но, судя по всему, плохие новости… это всё ещё актуальная проблема, как описано здесь, здесь, здесь и здесь. Хорошие новости в том, что есть простые обходные пути. Несколько человек задокументировали эту проблему на форумах Proxmox здесь, здесь, здесь, здесь и здесь, а также другие проблемы, которые завели меня в ложные преследования. Однако, пройдя по этим путям, я оказался в нескольких "кроличьих норах" и пришёл к тому, что, как мне кажется, это и есть корень проблемы.
Итак, если вам просто нужно знать, какой обходной путь использовать, у вас есть несколько вариантов:
* Используйте SeaBIOS вместо OVMF (EUFI) (как упоминается в вышеприведённых ссылках).
Ирония в том, что документация Proxmox гласит: [цитата из документации], но в этой ситуации это не так.
* Установите большее пространство Aperture на вашем VM (размер зависит от типа GPU).
```
qm set VMID -args '-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
```
* Измените тип процессора VM с x86-64-v2-AES на host:
```
qm set VMID -cpu host
```
Лучшие источники информации об этой проблеме я нашёл в отчёте об ошибке из kubevirt issue-11093, kubevirt issue-RFE Harvester/kubevirt и высокопроизводительные GPU с 32-разрядным слотом памяти BAR. На основе этого я нашёл блог о проблеме, который также привёл к коммиту в репозитории edk2, обсуждающем контекст, и углублённому обсуждению этой проблемы в рассылке edk2, объясняющем более подробно источник проблемы и почему её трудно исправить.
Дополнительный контекст о размере BAR от Nvidia и исправление для VMWare также. Nvidia даже упоминает сообщение об ошибке для BAR1.
Разбирая проблему и мой нынешний уровень понимания (поправьте меня, если я не прав)… Как упоминалось в рассылке edk2, OVMF предоставляет 64-разрядное пространство MMIO для распределения BAR PCI. Другими словами, OVMF предоставляет 64-разрядное пространство MMIO (Memory Mapped Input/Output), из которого 32 ГБ выделяется на распределение BAR PCI. Это 32 ГБ пространство также, похоже, называют "aperture" (?).
Очевидно, несколько устройств запрашивают место в пуле распределения MMIO PCI, поэтому, если несколько устройств суммарно составляют более 32 ГБ, некоторые устройства не смогут быть отображены. Вы можете посмотреть запросы BAR на хост-машине, запустив lspci -vvvs <deviceID>. Если драйверы работают на хосте, вы можете найти требования к памяти BAR1 с помощью nvidia-smi -q.
```
Code: 01:00.0 3D controller: NVIDIA Corporation AD102GL [L40S] (rev
[...]
Capabilities: [bb0 v1] Physical Resizable BAR
BAR 0: current size: 16MB, supported: 16MB
BAR 1: current size: 64GB, supported: 64GB
BAR 3: current size: 32MB, supported: 32MB
[...]
```
Как видите, L40S имеет размеры BAR 0, BAR 1 и BAR 3 в 16 МБ, 64 ГБ и 32 МБ соответственно. Для других устройств, таких как V100, BAR 0, BAR 1 и BAR 3 будут иметь размеры 16 МБ, 32 ГБ и 32 МБ соответственно.
Мораль истории: размер Aperture зависит от оборудования. Я не нашёл исчерпывающего списка, но Nvidia указывает требуемое пространство MMIO для нескольких версий своих GPU. В моём случае с L40s это карта памяти vRAM объёмом 48 ГБ, для которой потребуется 64 ГБ пространства MMIO. Это означает, что если я установлю пространство MMIO в 64 ГБ:
```
qm set <VMID> -args '-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
```
Общее пространство всё равно будет недостаточно, что я подтвердил.
Поскольку BAR — это степени двойки и из-за требований к выравниванию, они должны быть 131072. Я думаю, что пространство MMIO (aperture) может быть меньше, как указал Ласло, учитывая физические ограничения оборудования CPU. Это означает, что процессоры с шириной физического адреса 36 бит не смогут поддерживать больший размер aperture. Но в моём случае мои процессоры имеют физический адрес размером 46 бит. Вы можете проверить свой физический размер с помощью: `grep 'bits physical' /proc/cpuinfo`.
Стоит отметить, что по умолчанию тип процессора в Proxmox — x86-64-v2-AES — "40-битный физический", поэтому, если вам нужно передать 4+ GPU, такие как H100, с 128 ГБ MMIO, у вас закончится пространство памяти, как я понимаю.
Я бы отметил, что существует что-то под названием Resizeable BAR (ReBAR), когда вы можете изменить размер BAR 2 GPU, которые его поддерживают, но я не знаю, какие там последствия.
Некоторые источники для чтения
Итак, с этим вы сможете решить проблемы BAR с вашими GPU, используя passthrough.
После изучения этого вопроса в течение двух дней, как и я, многие люди просто наткнулись на решение, но я хотел знать больше, поэтому я здесь.
Что касается проекта Proxmox, как это можно обработать более чисто, у меня нет решения, и, похоже, OVMF или проект edk2 должны исправить эту проблему. Судя по всему, это не будет тривиальным исправлением, и неясно, станет ли это опцией, которую люди смогут установить для поддержки более крупных MMIO GPU, ReBAR или будет ли какое-то "волшебство", которое позволит это работать автоматически, как упомянул Дэниел. В любом случае, если это займет годы… возможно, фрагмент в документации, так как, я думаю, это станет более распространённой проблемой, по мере того как GPU начинают поставляться с большим объёмом vRAM. Надеюсь, это поможет.
Найти размер BAR ваших устройств
```
lspci | grep -i nvi
lspci -vvvs 3a:00.0
```
Источник: [ >)
Найти поддерживаемые CPU physical bits
```
grep 'bits physical' /proc/cpuinfo
```
Если у вас есть GPU с >= 24 ГБ памяти и вы используете OVMF (EUFI) и используете PCI Passthrough для VM, вы сможете увидеть устройство с помощью lspci -v, сможете установить драйвер, но драйвер не загрузится, и вы увидите следующее сообщение об ошибке при попытке загрузки:
```
Code: [22.345395] kernel: NVRM: This PCI I/O region assigned to your NVIDIAdevice is invalid:
NVRM: BAR0 is 0M @ 0x0 (PCI:0000:48:00.0)
[22.348443] kernel: NVRM: The system BIOS may have misconfigured your GPU.
```
Proxmox 8.4.1 (последняя версия на 2024/04/12), несколько GPU (Nvidia V100, L40S, A100, H100). VM-хосты, на которых я развертываю и тестирую, работают на RHEL9.4. Использую различные Intel Xeon 4xxx, 6xxxx процессоры на платформах Dell (R750) и Supermicro (X13). Я потратил около двух дней на исследование этой проблемы и до сих пор не знаю всего о ней, но всё ещё учусь.
Неважно, но, судя по всему, плохие новости… это всё ещё актуальная проблема, как описано здесь, здесь, здесь и здесь. Хорошие новости в том, что есть простые обходные пути. Несколько человек задокументировали эту проблему на форумах Proxmox здесь, здесь, здесь, здесь и здесь, а также другие проблемы, которые завели меня в ложные преследования. Однако, пройдя по этим путям, я оказался в нескольких "кроличьих норах" и пришёл к тому, что, как мне кажется, это и есть корень проблемы.
Итак, если вам просто нужно знать, какой обходной путь использовать, у вас есть несколько вариантов:
* Используйте SeaBIOS вместо OVMF (EUFI) (как упоминается в вышеприведённых ссылках).
Ирония в том, что документация Proxmox гласит: [цитата из документации], но в этой ситуации это не так.
* Установите большее пространство Aperture на вашем VM (размер зависит от типа GPU).
```
qm set VMID -args '-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
```
* Измените тип процессора VM с x86-64-v2-AES на host:
```
qm set VMID -cpu host
```
Лучшие источники информации об этой проблеме я нашёл в отчёте об ошибке из kubevirt issue-11093, kubevirt issue-RFE Harvester/kubevirt и высокопроизводительные GPU с 32-разрядным слотом памяти BAR. На основе этого я нашёл блог о проблеме, который также привёл к коммиту в репозитории edk2, обсуждающем контекст, и углублённому обсуждению этой проблемы в рассылке edk2, объясняющем более подробно источник проблемы и почему её трудно исправить.
Дополнительный контекст о размере BAR от Nvidia и исправление для VMWare также. Nvidia даже упоминает сообщение об ошибке для BAR1.
Разбирая проблему и мой нынешний уровень понимания (поправьте меня, если я не прав)… Как упоминалось в рассылке edk2, OVMF предоставляет 64-разрядное пространство MMIO для распределения BAR PCI. Другими словами, OVMF предоставляет 64-разрядное пространство MMIO (Memory Mapped Input/Output), из которого 32 ГБ выделяется на распределение BAR PCI. Это 32 ГБ пространство также, похоже, называют "aperture" (?).
Очевидно, несколько устройств запрашивают место в пуле распределения MMIO PCI, поэтому, если несколько устройств суммарно составляют более 32 ГБ, некоторые устройства не смогут быть отображены. Вы можете посмотреть запросы BAR на хост-машине, запустив lspci -vvvs <deviceID>. Если драйверы работают на хосте, вы можете найти требования к памяти BAR1 с помощью nvidia-smi -q.
```
Code: 01:00.0 3D controller: NVIDIA Corporation AD102GL [L40S] (rev
[...]
Capabilities: [bb0 v1] Physical Resizable BAR
BAR 0: current size: 16MB, supported: 16MB
BAR 1: current size: 64GB, supported: 64GB
BAR 3: current size: 32MB, supported: 32MB
[...]
```
Как видите, L40S имеет размеры BAR 0, BAR 1 и BAR 3 в 16 МБ, 64 ГБ и 32 МБ соответственно. Для других устройств, таких как V100, BAR 0, BAR 1 и BAR 3 будут иметь размеры 16 МБ, 32 ГБ и 32 МБ соответственно.
Мораль истории: размер Aperture зависит от оборудования. Я не нашёл исчерпывающего списка, но Nvidia указывает требуемое пространство MMIO для нескольких версий своих GPU. В моём случае с L40s это карта памяти vRAM объёмом 48 ГБ, для которой потребуется 64 ГБ пространства MMIO. Это означает, что если я установлю пространство MMIO в 64 ГБ:
```
qm set <VMID> -args '-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
```
Общее пространство всё равно будет недостаточно, что я подтвердил.
Поскольку BAR — это степени двойки и из-за требований к выравниванию, они должны быть 131072. Я думаю, что пространство MMIO (aperture) может быть меньше, как указал Ласло, учитывая физические ограничения оборудования CPU. Это означает, что процессоры с шириной физического адреса 36 бит не смогут поддерживать больший размер aperture. Но в моём случае мои процессоры имеют физический адрес размером 46 бит. Вы можете проверить свой физический размер с помощью: `grep 'bits physical' /proc/cpuinfo`.
Стоит отметить, что по умолчанию тип процессора в Proxmox — x86-64-v2-AES — "40-битный физический", поэтому, если вам нужно передать 4+ GPU, такие как H100, с 128 ГБ MMIO, у вас закончится пространство памяти, как я понимаю.
Я бы отметил, что существует что-то под названием Resizeable BAR (ReBAR), когда вы можете изменить размер BAR 2 GPU, которые его поддерживают, но я не знаю, какие там последствия.
Некоторые источники для чтения
Итак, с этим вы сможете решить проблемы BAR с вашими GPU, используя passthrough.
После изучения этого вопроса в течение двух дней, как и я, многие люди просто наткнулись на решение, но я хотел знать больше, поэтому я здесь.
Что касается проекта Proxmox, как это можно обработать более чисто, у меня нет решения, и, похоже, OVMF или проект edk2 должны исправить эту проблему. Судя по всему, это не будет тривиальным исправлением, и неясно, станет ли это опцией, которую люди смогут установить для поддержки более крупных MMIO GPU, ReBAR или будет ли какое-то "волшебство", которое позволит это работать автоматически, как упомянул Дэниел. В любом случае, если это займет годы… возможно, фрагмент в документации, так как, я думаю, это станет более распространённой проблемой, по мере того как GPU начинают поставляться с большим объёмом vRAM. Надеюсь, это поможет.
Найти размер BAR ваших устройств
```
lspci | grep -i nvi
lspci -vvvs 3a:00.0
```
Источник: [ >)
Найти поддерживаемые CPU physical bits
```
grep 'bits physical' /proc/cpuinfo
```
