Vega PCIE Passthrough stuttering

I’ve set up a QEMU VM running Windows 10 passing through a Vega 64 graphics card on a Ryzen 2700x running Ubuntu 20.04. It was kind of a struggle.

The VM works but has a couple of strange problems with it. Sometimes, the two monitors connected via HDMI will go to “snow”… it looks like the fuzz you would get on an old TV that wasn’t tuned to anything. Then, a few seconds later, it stops and I get back to the desktop. The audio gets reset too.

Other times, the VM will stutter, which seems to happen most often when playing games. The whole system will freeze for just a second and then snap out of it.

There’s nothing in dmesg or in journalctl -u libvirtd related to these errors, and they seem to happen randomly. Sometimes things will be just fine for 30 minutes or so, sometimes it does it once every minute.

Any idea what I can do to stop one or both of these things from happening? I’m happy to post whatever config, I just didn’t know where to start… TIA.

how are your drives being passed to the VM? the stutter and freezing looks very much like it could be an IO bottleneck and not being able to keep up with the system. If this is the case you have two options to increase IO performance.

The first is to pass the physical SATA controller through to the VM using vfio, this usually has the best performance but not very versatile or possible on all systems with a single SATA controller.

The second is to configure the disks to use scsi with io threads with a separate scsi controller for each drive so they each have their own io and preferably passing a whole disk to the VM instead of an image but that isn’t as critical.

This topic by gnif goes into it more and how it can increase your perofrmance:

but todo this using virtio you can simply just set the Disk bus to SCSI and IO mode to threads. you can do this in virt-manager using the UI but the xml for it looks like this:

<disk type="file" device="disk">
  <driver name="qemu" type="raw" io="threads"/>
  <source file="/mnt/storage/images/vms/windows10.img"/>
  <target dev="sda" bus="scsi"/>
  <address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>

and if you want to use a whole disk you’d set the disk type to block and the source to the disk id like this:

<disk type="block" device="disk">
  <driver name="qemu" type="raw" io="threads"/>
  <source dev="/dev/disk/by-id/usb-ULT-Best_FX-D0002.HDD_20150718-0:0"/>
  <target dev="sda" bus="scsi"/>
  <boot order="1"/>
  <address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>

If you have more than a single drive you can just add another Virtio SCSI controller and set the controller in the XML on one of the drives from 0 to 1:

<address type="drive" controller="1" bus="0" target="0" unit="0"/>

lastly since your using Windows 10 it doesn’t by default have the vioscsi drivers and you’ll have to install them manually for the drives to be detected. You can get an iso image with the correct drivers from here:

https://docs.fedoraproject.org/en-US/quick-docs/creating-windows-virtual-machines-using-virtio-drivers/

The easiest way I found todo this from a working install is add either a single or dummy drive as an scsi, boot windows, download and mount the virtio-win.iso file, go to Device Manager > Other devices, right click on the device > Update Driver > Browse my computer for driver software and set the path to the root of the virtio-win.iso and it should find it. now you can shutdown and set your C drive to scisi and reboot.

This should increase your io perforamnce massively and hopefully also solve all of your stuttering issues too.

Sorry this got a little long winded but if you have any questions please ask :slight_smile:

Is there a log file or dmesg output that I can use to confirm that it’s an IO issue? I ask because the fact that the signal drops from the video card indicates very much that this has something to do with the Vega 64. I figure I’ve messed up the PCIE passthrough somehow.

Did you try cpu pinning? Like assigning specific threads to the VM threads. I’ve done that in mine and it really helped my stutter issues.

I found CPU pinning and changing the scaling governor to performance mode fixed my stutter issues.

#!/bin/bash
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "performance" > $file; done
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

you can revert to ‘on demand’ mode when you don’t need to go full tilt all the time by switching it back.

#!/bin/bash
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "ondemand" > $file; done
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

Found it to help out in a few other situations too, like when running games with WINE & DXVK for more framerate stabillity & higher performance overall.