LINUX.ORG.RU

Проброс видеокарты NVIDIA

 , ,


0

1

Здрасти,

Я тут немного извращаюсь, пытаюсь найти решение, но возможно вы ускорите всё это, либо идею какую-то подадите.

Есть ПК, Intel i7-8700k, Nvidia RTX 2070. Собирал в основном для игр, поэтому стоит дуалбут с офтопиком. Для меня работать/отдыхать на линуксе намного удобнее, поэтому основная система линь. Немного надоело перезагружаться чтобы поиграть/перестать играть, поэтому захотелось попробовать держать винду на виртуалке и просто пробросить ей видеокарту.

И так, желание примерно следующее. Компьютер включается с линуксом, который использует nvidia (так как это бывает нужно, что-нибудь порендерить/поиграть нативное и т.п.). Когда мне хочется поиграть, я просто запускаю виртуалку и nvidia передаётся виртуалке, а потом останавливаю виртуалку и возвращаюсь к линуксу. При этом, у меня два монитора, на одном я всегда хочу видеть линукс, а второй монитор будет переключаться между линуксом и виртуалкой. При этом хочу иметь возможность юзать обе системы/монитора. То бишь, просто провести мышку на первый монитор и там «полинуксить», а потом переключить опять на второй и продолжить играть.

Что имеется:

  1. Две видеокарты - intel и nvidia и два монитора. На UEFI врубил режим multi-gpu - один монитор подключен к материнке, второй к видеокарте. Линукс стартует на первом мониторе с интелом, а потом прогружается nvidia и оба монитора/видеокарты работают.

  2. Видеокарту я пробросил через qemu/kvm и всё работает. Для совместной работы в двух системах тестово использовал barrier, работает. Не тестил производительность, но если что, можно будет что-нибудь придумать (квм свитч или как-нибудь приделать проброс клавиатуры).

Но есть проблема. Чтобы загружалась виртуалка, нужно убирать из ядра nvidia. Но сделать это не получается, так как она используется иксами. Можно конечно убивать иксы, отключать нвидиа и опять стартовать, но тогда сессия вылетает. Но у меня и интел используется, который также рисует на одном из мониторов, можно ли как-то не убивая иксы убрать из ядра нвидиа и стартануть виртуалку?

Решения по типу «вайн» не принимаются, так как не всё гладко.


Чуть позже напишу полный гайд, а пока вкратце.

По железу: MB - Asus Prime z370-a

CPU - Intel i7-8700k (6 core 12 threads)

RAM - Corsair Vengeance RGB (2x16GB)

GPU - NVIDIA RTX 2070 (ASUS)

iGPU - Intel UHD Graphics 630

SSD - Intel 660p (1Tb)

HDD - Seagate (1Tb)

Monitor 1 - Dell 24" 1080p

Monitor 2 - LG 32" 1440p

SoundCard - NoName usb sound card

В UEFI врублен vt-d (для проброса видеокарты виртуалке) и iGPU Multi-Monitor (чтобы можно было использовать интегрированную карту). От материнки идут 2 видеовыхода на каждый из мониторов; от видеокарты идёт 1 видеовыход на LG монитор.

По софту:

OS - Arch

DM - SDDM

WM - i3-gaps

bumblebee, mesa, libvirt, virt-manager, qemu-kvm, barrier

Для видеокарты нужно установить bumblebee. Куча гайдов про то, как настроить vfio и т.п., но на деле это ничего не нужно (кроме intel_iommu=on) , если установлен bumblee. Как я понимаю, он при включении не даёт видеокарте загрузиться и в целом держит её подальше от ядра, благодаря чему видеокарту можно свободно использовать как в виртуалке, так и в свободное время просто запустив приложение через optirun.

Для ядра в граб добавляется -

GRUB_CMDLINE_LINUX="intel_iommu=on isolcpus=4-7 nohz_full=4-7 rcu_nocbs=4-7"

В virt-manager куча нюансов относительно процессора, как для обмана видеокарты (для установки драйвера, иначе ругается), так и для оптимизации производительности, звука.

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
  <name>win10</name>
  <uuid>23795b4a-69db-428e-88eb-0532383d6f0c</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit="KiB">16777216</memory>
  <currentMemory unit="KiB">16777216</currentMemory>
  <vcpu placement="static">8</vcpu>
  <iothreads>1</iothreads>
  <cputune>
    <vcpupin vcpu="0" cpuset="2"/>
    <vcpupin vcpu="1" cpuset="8"/>
    <vcpupin vcpu="2" cpuset="3"/>
    <vcpupin vcpu="3" cpuset="9"/>
    <vcpupin vcpu="4" cpuset="4"/>
    <vcpupin vcpu="5" cpuset="10"/>
    <vcpupin vcpu="6" cpuset="5"/>
    <vcpupin vcpu="7" cpuset="11"/>
    <emulatorpin cpuset="0,6"/>
    <iothreadpin iothread="1" cpuset="0,6"/>
  </cputune>
  <os>
    <type arch="x86_64" machine="pc-q35-4.2">hvm</type>
    <loader readonly="yes" type="pflash">/usr/share/ovmf/x64/OVMF_CODE.fd</loader>
    <nvram>/usr/share/ovmf/x64/OVMF_VARS.fd</nvram>
    <boot dev="hd"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vendor_id state="on" value="1234567890ab"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
  <cpu mode="host-passthrough" check="partial">
    <topology sockets="1" cores="4" threads="2"/>
  </cpu>
  <clock offset="localtime">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
    <timer name="hypervclock" present="yes"/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="file" device="disk">
      <driver name="qemu" type="qcow2"/>
      <source file="/home/doctor/vms/win10.qcow2"/>
      <target dev="sda" bus="sata"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>
    <disk type="block" device="disk">
      <driver name="qemu" type="raw" cache="none" io="native"/>
      <source dev="/dev/nvme0n1p3"/>
      <target dev="sdb" bus="sata"/>
      <address type="drive" controller="0" bus="0" target="0" unit="1"/>
    </disk>
    <controller type="usb" index="0" model="qemu-xhci" ports="15">
      <address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
    </controller>
    <controller type="sata" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
    </controller>
    <controller type="pci" index="0" model="pcie-root"/>
    <controller type="pci" index="1" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="1" port="0x10"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
    </controller>
    <controller type="pci" index="2" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="2" port="0x11"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
    </controller>
    <controller type="pci" index="3" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="3" port="0x12"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
    </controller>
    <controller type="pci" index="4" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="4" port="0x13"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
    </controller>
    <controller type="pci" index="5" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="5" port="0x14"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
    </controller>
    <controller type="pci" index="6" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="6" port="0x15"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
    </controller>
    <controller type="pci" index="7" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="7" port="0x16"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
    </controller>
    <controller type="pci" index="8" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="8" port="0x17"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
    </controller>
    <controller type="pci" index="9" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="9" port="0x18"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
    </controller>
    <controller type="pci" index="10" model="pcie-to-pci-bridge">
      <model name="pcie-pci-bridge"/>
      <address type="pci" domain="0x0000" bus="0x09" slot="0x00" function="0x0"/>
    </controller>
    <controller type="pci" index="11" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="11" port="0x19"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
    </controller>
    <controller type="pci" index="12" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="12" port="0x1a"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
    </controller>
    <controller type="virtio-serial" index="0">
      <address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
    </controller>
    <controller type="scsi" index="0" model="virtio-scsi">
      <address type="pci" domain="0x0000" bus="0x0b" slot="0x00" function="0x0"/>
    </controller>
    <interface type="bridge">
      <mac address="52:54:00:1b:af:60"/>
      <source bridge="virbr0"/>
      <model type="virtio"/>
      <address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
    </interface>
    <input type="mouse" bus="ps2"/>
    <input type="keyboard" bus="ps2"/>
    <sound model="ich9">
      <codec type="micro"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
    </sound>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x1"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x2"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x3"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
    </hostdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
    </memballoon>
  </devices>
  <qemu:commandline>
    <qemu:arg value="-audiodev"/>
    <qemu:arg value="pa,id=pa1,server=/run/user/1000/pulse/native,in.latency=20000,out.latency=20000"/>
  </qemu:commandline>
</domain>

В i3 также два хоткея - Win PgUP, Win PgDwn

bindsym $mod+Prior exec sudo /home/doctor/bin/win10-on				### LAUNCH VM
bindsym $mod+Next exec sudo /home/doctor/bin/win10-off				### POWEROFF VM

а в самих скриптах пока что простенько, win10-on

#!/bin/sh

# Turn to 1 screen
bash /home/doctor/.screenlayout/singlescreen.sh

# Run cpu governer
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor;
do	echo "performance" > $file 
done

# Run vm
virsh start win10

и win10-off

#!/bin/sh

# Shutdown vm
virsh shutdown win10

# Stop gpu governer
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
do echo "powersave" > $file
done

# Turn to 2 screens
bash /home/doctor/.screenlayout/dualscreen.sh

Чтобы можно было свободно двигать мышкой/клавиатурой между виртуалкой и хостом и иметь общий буфер стоит barrier.



Последнее исправление: Datt_ (всего исправлений: 8)

Твоя задача вообще не так решается. Следует вообще отказаться от работы в хост-ос. Да, пара виртуалок. Один ГПУ потребуется под хост-ос и как минимум еще один ГПУ для гостей. В случае linux в госте, можно попробовать сэкономить и использовать virtio-gpu. Я как раз готовлюсь на такую схему перейти. Только я еще буду гостям цельные физические диски отдавать, чтобы можно было прямо с этих дисков загрузиться.

targitaj ★★★★★
()
Ответ на: комментарий от targitaj

Без понятия. Там куча магии под капотом, копия vbios, неинициализированное фейковое состояние, всего и не упомнишь. А просветишь? Я искренне не понимаю, как это поможет тебе доказать, что повторный проброс не работает, когда он работает.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Ты читать вообще умеешь, не? При повторном пробросе у тебя гость КАЖДЫЙ РАЗ ЖЕЛЕЗО ПРИ ЗАПУСКЕ ИНИЦИАЛИЗИРУЕТ. КАЖДЫЙ. РАЗ.

targitaj ★★★★★
()
Ответ на: комментарий от targitaj

Ну с повторной инициализацией можно потом разобраться, надо хотя бы подумать, как загрузить на хосте, потом кинуть на виртуалку

Datt_
() автор топика
Ответ на: комментарий от Datt_

Тебя не напрягает, что первое достигается относительно легко и ненапряжно, а второе полный тред народа в один голос воспринимает как что-то невиданное?

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Он намекает на то, что при выключении виртуалки видюха выключится, и хост получит выключеную видюху, то бишь она обычным modprobe nvidia не запустится

Datt_
() автор топика
Ответ на: комментарий от Datt_

Я не знаю достаточно по материальной части чтобы сказать что-то конкретное по поведению. Но знаю достаточно чтобы задаться вопросом. Вот я и задаюсь вопросом…

targitaj ★★★★★
()
Ответ на: комментарий от targitaj

На данный момент virtio-gpu так себе работает. Вроде бы, только opengl и не старше 3 версии. Может, 3.1.

anonymous
()
Ответ на: комментарий от Datt_

Хм. На реддите человек написал, что у него работает через какой-то PRIME (две дискретные amd-карточки). Правда, на wayland. В xorg не работает.

Но я только мельком топик глянул.

anonymous
()
Ответ на: комментарий от anonymous

И так, есть определённый прогресс, хоть я особо и не тратил времени на это. Пока еще виртуалку не развернул, но сам запуск вмки с проброшенной картой, отключение вмки и запуск glxgears через optirun подтвердить могу. Всё не так сложно. Пошёл по гайду этого парня - https://www.youtube.com/watch?v=ssfvpLXK8po&t=197s

Bumblebee is the secret sauce to getting this setup. It’s is only required if you want to use the gpu without restarting xorg. The bumblebee service is started when the vm is not running, and bumblebee runs a xorg server in the background that’s using the nvidia gpu. With primusrun/optirun, games can be run there and frames gets copied to the main xorg desktop. This works the same on desktop as on Optimus laptops.

В общем то, подключаем оба монитора к интегрированной карте, всё что нужно поставить это bumblebee. Когда нам нужно переключиться на виртуалку, стопим демон бамблбии, тем самым освобождаем видюху и она спокойно пробрасывается на виртуалку. А когда нужно использовать какие-то приложения на самом хосте с видюхой, запускаем их через optirun. Производительность не тестил, завтра буду, скорее всего.

Плюс парень советует looking glass. Посмотрим, что будет.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Всё настолько банально, что даже не верится.

Даже не нужно отключать bumblebee. Он просто установлен. Я просто через virt manager создал виртуалку, примапил ей видеокарту и запустил вмку. Всё работает. При рабочей вмке попробовал запустить какое-то приложение через optirun - не пашет. Но если выключить виртуалку - работает, без лишних движений. С virt-manager пришлось немного пошаманить, потому что поломали nvram, плюс надо прятать, что видюха запущена на виртуалке, а то дрова не ставятся. Но как итог - видюха на виртуалке, всё работает как надо. Поставил looking glass, вроде запахал, осталось с клавой и мышкой разобраться и тесты провести

Datt_
() автор топика
Ответ на: комментарий от Datt_

давно уже пора всем вфио освоить и тогда вообще игры в линуксе после этого не нужны будут

а тут всё какие-то старперы со своим дуалбутом

anonymous
()
Ответ на: комментарий от Datt_

looking-glass работает только с windows-10. И видеокарточку нужно будет подключить к монитору (или к фейковой затычке, которая передаст edid), иначе винда не сможет выставить разрешение и looking-glass-client ничего не покажет.

Иногда looking-glass начинает подтормаживать по какой-то причине, приходится клиент перезапускать.

anonymous
()
Ответ на: комментарий от Datt_

looking-glass имеет встроенную поддержку spice. Можно через него передавать. Я использую evdev-passthrough.

anonymous
()
Ответ на: комментарий от anonymous

Не до конца разобрался с ним, немного геморно вышло с клавой и мышкой, решил пойти по другому пути.

Основной монитор подключен как к материнке, так и к видюхе. При запуске виртуалки я через xrandr отключаю основной монитор, переключаясь напрямую на видюху. Потому что looking glass занимает рабочий стол, а они у меня на i3wm. То бишь, если какие-то рабочие столы у меня на основном экране вместе с looking-glass, то они «пропадут», лучше пусть всё будет переключаться на второй монитор. Оставался вопрос клавиатуры и мышки. evdev-passthrough не устраивает, потому что хочется shared clipboard. Поставил barrier, вроде как пашет как надо, удобно работать с хоткеями и т.п.

Datt_
() автор топика
Ответ на: комментарий от Datt_

И так, после небольших тестов на паре игр (батлфилд 5, вархаммер верминтайд 2, ведьмак 3) увидел большую просадку по процессору, он буквально умирал. Нашел гайды по оптимизации, они дело сделали. Возможно еще много чего можно оптимизировать, но в целом ситуация примерно следующая. При одинаковых настройках (2к, настройки ультра) в батле разница в среднем в 10-15 фпс (на железе скачет 105-120, на виртуалке 90-110), в ведьмаке ~70 фпс (84 фпс судя по инету для моих параметров). Но учитывая, что со своего i7-8700k я отдаю виртуалке только 8 потоков, при этом у меня на хосте открыт браузер и пара других приложений, довольно неплохо. Монитор ресурсов для ведьмака вообще показывает никакую нагрузку, просто выше 70-75 почему-то не поднимается. Задержек со стороны клавиатуры/мышки не заметил.
Думаю можно забыть про дуалбут.

Datt_
() автор топика
Ответ на: комментарий от Datt_

Распиши в первом сообщении полный сетап по железу и софту.

targitaj ★★★★★
()

По звуку для пульсы и qemu 4-ой ветки:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <devices>
    <sound model='ich9'>
      <codec type='micro'/>
    </sound>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-audiodev'/>
    <qemu:arg value='pa,id=pa1,server=/run/user/1000/pulse/native,in.latency=20000,out.latency=20000'/>
  </qemu:commandline>
</domain>

anonymous
()
Ответ на: комментарий от anonymous

Да вот только что нашел, зашел добавить, правда немного в другом виде, но суть одна и та же

Datt_
() автор топика
Ответ на: комментарий от Datt_

И так, почти неделю на виртуалке играю. В целом, никаких проблем нет, но всё же гложет меня потеря производительности. Решил прогнать какой-то бенчмарк, взял первое что попало под руку - novabenchmark. Скорее всего проблемы бэнчмарка, но возможно действительно есть какая-то проблема. на нативной среде общая производительность 2845 ЦПУ - 1284, ГПУ - 1031, Оперативка - 340, Диск - 190

на виртуалке - 2327 ЦПУ - 1000, ГПУ - 773, Оперативка - 292, Диск - 262

И это довольно странно. Насчёт проца всё понятно, я использую 10/12 потоков, плюс он показывает 3.70 и вроде как не меняется. Но это не страшно

ГПУ.. странно. Я конечно понимаю, что это проброс видеокарты, но почему я теряю производительность?

Оперативка.. Отдаю только половину (16), ну и виртуализация, всё норм.

Диск - ??? Я просто создал qcow2 файл, почему он быстрее, чем виндовс с нативным разделом?

Как бы понять, почему у меня видеокарта проседает?

Datt_
() автор топика
Ответ на: комментарий от anonymous

Ну вывод звука без тресков работает во всех играх, в ICH6 был треск, в 9 его нет. А микрофон нет, трещит, поэтому я его пробросил на виртуалку. Если звук сделать через ivshmem, микрофон не будет трещать?

Datt_
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.