<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/index.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>./techtipsy</title><link>https://ounapuu.ee/tags/vfio/</link><description>Recent content on ./techtipsy, a blog written by Herman Õunapuu.</description><generator>Hugo -- gohugo.io</generator><language>en-GB</language><managingEditor>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</managingEditor><webMaster>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</webMaster><lastBuildDate>Wed, 03 Jul 2024 06:00:00 +0300</lastBuildDate><atom:link href="https://ounapuu.ee/tags/vfio/index.xml" rel="self" type="application/rss+xml"/><item><title>About the time my ThinkPad T430 ran with an external GPU</title><link>https://ounapuu.ee/posts/2024/07/03/thinkpad-t430-egpu/</link><pubDate>Wed, 03 Jul 2024 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2024/07/03/thinkpad-t430-egpu/</guid><description>I had dumb ideas during my university days as well, but the budget was smaller.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/posts/2024/07/03/thinkpad-t430-egpu/media/cover_hu_edb0986a7ce4b00b.jpg" width="1200" height="630" alt="About the time my ThinkPad T430 ran with an external GPU" /><p>The ThinkPad T430 is not a remarkable laptop. It&rsquo;s thick, bulky and built like
a tank. I got mine in 2016 when the first university scholarship money dropped,
and it&rsquo;s still my backup laptop of choice.</p>
<p>Around 2017 I did something every reasonable poor computer science student
would do: I got an eGPU adapter for it to play some games. I never ended up
playing many games, but I loved tinkering with and testing this setup a lot.</p>
<p>These are my notes on the setup that I used to have. The notes used to be on
Reddit, but after yet another user-hostile change<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> I deleted my account
and all the content associated with it.</p>
<h2 id="the-specs">
  <a class="heading-anchor" href="#the-specs">The specs<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The ThinkPad T430 that I used had a CPU swap at one point, running an Intel
i7-3820QM. This upgrade doubled the CPU performance on the laptop compared
to the dual-core CPU that was in it before. This change was critical because
it opened the door to running lots of modern games at reasonable performance.</p>
<p>The eGPU adapter I ran with was the EXP GDC Beast v8.4, using the ExpressCard34
connector. This adapter turned the ExpressCard34 slot into a PCIe 2.0 x1 slot.
It&rsquo;s not really hotpluggable, but using this connector instead of something
like the internal Wi-Fi adapter slot made this setup much more portable. Done
gaming? Shut down, disconnect the ExpressCard cable and you&rsquo;re good to go!</p>
<p>This adapter is also a good example of connector reuse. The other end of the
ExpressCard plug is an HDMI port. Video signals require good quality cables, and
so does PCI Express.</p>









<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-connector.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-connector_hu_bcf4ea89c1948520.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="Close-up of the ExpressCard34 connector.">

  </a>
  <figcaption class="center">Close-up of the ExpressCard34 connector.</figcaption>
</figure>

<p>The eGPU was once powered by a simple ATX PSU with the jumper wire set on the
24-pin connector, but eventually I bought a Dell DA-2 power supply. The adapter
has a power connector designed specifically for that pinout and it made the setup
a lot cleaner.</p>









<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-atx.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-atx_hu_c7488d9aa2981290.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="The setup with an ATX PSU.">

  </a>
  <figcaption class="center">The setup with an ATX PSU.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-psu.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-psu_hu_367576f51290bf0e.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="The setup with a Dell DA-2 PSU. Much cleaner, isn&#39;t it?">

  </a>
  <figcaption class="center">The setup with a Dell DA-2 PSU. Much cleaner, isn&#39;t it?</figcaption>
</figure>

<p>At one point I got a fully metal case for the eGPU. It made the setup a lot cleaner
and the risk of the GPU tipping over while turned on was also substantially reduced.</p>









<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-case.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-case_hu_aaa43de0ce81aed3.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="The case had no right to be this good for a janky setup.">

  </a>
  <figcaption class="center">The case had no right to be this good for a janky setup.</figcaption>
</figure>

<p>I tested a few GPU-s:</p>
<ul>
<li>AMD Radeon HD 6870</li>
<li>nVidia GTX 950</li>
<li>nVidia GTX 1080</li>
<li>AMD Radeon RX 480</li>
</ul>
<p>The HD 6870 was an old card back in 2017, and it did not run great at all with
this eGPU adapter. It was buggy and the performance sucked.</p>
<p>Loaner GPU-s, such as the RX 480 and GTX 1080 were much better experiences, as
long as you output the video signal to an external display right from the GPU.</p>
<p>The nVidia GTX 950 was the card I ran with for the longest time in this setup.
It worked well with this setup and had decent gaming performance.</p>









<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/gpuz-info.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/gpuz-info_hu_e074ca0f223b64ac.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="GPU-z info while the GPU is idle. Note that the PCIe link speed is set to gen 1.1 under &#34;Bus Interface&#34;.">

  </a>
  <figcaption class="center">GPU-z info while the GPU is idle. Note that the PCIe link speed is set to gen 1.1 under &#34;Bus Interface&#34;.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/gpuz-linkspeed.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/gpuz-linkspeed_hu_c99b51ff47cc1c11.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="When the GPU is under load, the PCIe connection switches to PCIe 2.0.">

  </a>
  <figcaption class="center">When the GPU is under load, the PCIe connection switches to PCIe 2.0.</figcaption>
</figure>

<h2 id="egpu-tech-tips">
  <a class="heading-anchor" href="#egpu-tech-tips">eGPU tech tips<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>You will want to use an eGPU adapter with an external monitor for the best performance.
The PCIe bandwidth is very limited in a setup like this. Using the internal
display of the laptop will mean that the final rendered image will have to be
sent back from the eGPU to the CPU. 1x PCIe 2.0 lane is about 500 MB/s of bandwidth.
Sending 60+ frames in the native resolution (1600x900) will eat it all up.
The higher the resolution on the internal display, the fewer frames you&rsquo;ll get.</p>
<p>I tested out these two scenarios in CSGO. The internal display yielded about 61 FPS
while an external display would result in 100-180+ FPS.</p>
<p>The PCIe link bandwidth was not actually that noticeable in a lot of games, such
as GTA V, Rocket League and Dirt 3.</p>
<p>In some games, such as Dirt Rally (2015), it did not matter what settings
you went with, something about the game made it run poorly no matter what
graphics settings you went with. In cases like that you might as well cap the
framerate to something tolerable like 30 FPS and crank the graphics settings up.</p>
<h2 id="vfio-on-a-laptop">
  <a class="heading-anchor" href="#vfio-on-a-laptop">VFIO on a laptop???<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>This setup was also around the time when I first learned about <a href="https://youtu.be/16dbAUrtMX4">the magical world
of VFIO and GPU passthrough.</a></p>
<p>The logical continuation of that discovery was to try it out on my laptop, and
to my surprise it actually worked. I could pass the eGPU to a VM and play GTA V
on it!</p>
<p>This setup ran on Antergos OS, a flavor of Arch Linux. <a href="https://en.wikipedia.org/wiki/Antergos">It&rsquo;s been so long since then that the flavor
of Arch Linux is now discontinued.</a><sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>









<figure class="center">
  <a href="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-vfio.jpg">
    <img src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-vfio_hu_b6f5e698500d56ab.webp"
     width="800"
     height="600"
     loading="lazy"
     decoding="async"
     alt="Antergos OS on the host, Windows 10 on the guest VM running Furmark.">

  </a>
  <figcaption class="center">Antergos OS on the host, Windows 10 on the guest VM running Furmark.</figcaption>
</figure>

<p>The laptop was ideal for this purpose as well. You have the integrated GPU, display,
keyboard and mouse for the host system, and you can pass USB devices and the eGPU
to the VM.</p>
<p>There were the usual VFIO tricks that I had to try out to avoid the dreaded
<code>error code 43</code> issue, but after that it was smooth sailing.</p>
<p>The performance was very similar to what I saw on the host system.</p>


<figure class="center">
  <video class="post-video" width="1280" height="720" style="aspect-ratio: 1280 / 720;" controls poster="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu-poster.webp" playsinline preload="none">
    <source src="/posts/2024/07/03/thinkpad-t430-egpu/media/egpu.webm" type="video/webm">
    GTA V? On a laptop? With an eGPU? In a VM? On Arch? It&#39;s more likely than you think.
  </video>
  <figcaption class="center">GTA V? On a laptop? With an eGPU? In a VM? On Arch? It&#39;s more likely than you think.</figcaption>
</figure>

<p>Smartphone cameras have
come a long way since then.</p>
<h2 id="expresscard-egpu-s-in-2024">
  <a class="heading-anchor" href="#expresscard-egpu-s-in-2024">ExpressCard eGPU-s in 2024?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What got me started with writing down my notes were <a href="https://youtu.be/390FuyadPIw">some YouTube videos that were
made on this topic recently.</a></p>
<p>A pimped-out ThinkPad T430 can still be a perfectly serviceable computer in 2024,
and an eGPU will completely sidestep the problem of the weak integrated GPU.</p>
<p>The T430 is not powerful enough to natively run a 3440x1440 ultrawide monitor at
60 Hz. It is even struggling to do it at 30 Hz. An eGPU adapter with a modern
low-power GPU, such as the AMD Radeon RX 6400, could solve this issue nicely and
give the ThinkPad T430 a new lease of life.</p>
<p>I&rsquo;d be lying if I wasn&rsquo;t considering remaking this setup with everything I&rsquo;ve
learned 6 years later. GPU pricing sucks, though.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>
They still sell these eGPU kits in various forms, however the price has doubled
or even tripled over the years.</p>
<p>If you&rsquo;re interested in building a similar setup, then do check out <a href="https://egpu.io/">egpu.io</a>.
With an M.2 or Thunderbolt connector you can build a much more capable eGPU setup.</p>
<p><a href="https://www.youtube.com/watch?v=SH9RUpK4SsM">If you can get a PCI Express signal out of a computer, then you can probably
rig a GPU up to it.</a> Unless you&rsquo;re
Jeff Geerling, in which case you might need to <a href="https://www.jeffgeerling.com/blog/2023/external-gpus-working-on-raspberry-pi-5">recompile the kernel a few times.</a></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>guess which one.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>validates my view that it&rsquo;s still a good idea to stick to the big distros
that these short-lived Linux distros are based off of.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>I&rsquo;ve survived two cryptocurrency mining hype cycles, and now we are in an
LLM bubble. Great.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>ASRock X570M Pro4 motherboard overview</title><link>https://ounapuu.ee/posts/2022/02/02/asrock-x570m-pro4-overview/</link><pubDate>Wed, 02 Feb 2022 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2022/02/02/asrock-x570m-pro4-overview/</guid><description>Quick overview from someone who does this thing as a hobby, focusing on PCIe connectivity, fan control and the poor state of AM4 socket and UEFI upgrades.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="ASRock X570M Pro4 motherboard overview" /><p>Not too long ago, I had the goal of consolidating all my computing needs onto a
single desktop PC. That meant moving from an mITX-based build to something that
had a bit more expandability. Since I already had a
<a href="https://www.fractal-design.com/products/cases/meshify/meshify-c-mini-dark-tempered-glass/black/">Fractal Meshify C Mini</a>,
I decided to go for an mATX motherboard. And that&rsquo;s how I ended up with an
<a href="https://www.asrock.com/mb/AMD/X570M%20Pro4/">ASRock X570M Pro4</a>.</p>









<figure class="center">
  <a href="/posts/2022/02/02/asrock-x570m-pro4-overview/media/glamshot.jpg">
    <img src="/posts/2022/02/02/asrock-x570m-pro4-overview/media/glamshot_hu_96cab6cd6b670713.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="ASRock X570M Pro4. Looks great, doesn&#39;t it?">

  </a>
  <figcaption class="center">ASRock X570M Pro4. Looks great, doesn&#39;t it?</figcaption>
</figure>

<h2 id="matx-a-dying-breed">
  <a class="heading-anchor" href="#matx-a-dying-breed">mATX: a dying breed?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>One of the requirements for the build was that it had to support IOMMU well so
that a VFIO setup would be possible. While AMD B-series motherboards may work
just fine in such scenarios, the X-series boards allegedly have better IOMMU
groups and thus better compatibility with VFIO.</p>
<p>Once I started the search for the new motherboard, I was surprised to see that
locally there was only one mainstream option available. There were plenty of
B450 and B550 boards available, but only a single X570 board in this form factor.</p>
<p>I checked the board out, saw that it had plenty of NVMe and SATA storage options,
and went for it.</p>
<h2 id="pcie-connectivity">
  <a class="heading-anchor" href="#pcie-connectivity">PCIe connectivity<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>When you have a bunch of PCIe devices to connect, the way those lanes are
connected start to matter.</p>
<p>Based on my own testing, I&rsquo;ve found the following:</p>
<ul>
<li>the first M.2 slot (under the heatsink) is connected to the CPU</li>
<li>the first PCIe x16 slot is also connected to the CPU</li>
<li>the rest of PCIe connectivity goes through the chipset</li>
<li>most (if not all) SATA ports seem to go through the chipset as well</li>
</ul>









<figure class="center">
  <a href="/posts/2022/02/02/asrock-x570m-pro4-overview/media/lstopo.jpg">
    <img src="/posts/2022/02/02/asrock-x570m-pro4-overview/media/lstopo_hu_2ebd299829f27b52.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Hardware topology, as shown by `lstopo`.">

  </a>
  <figcaption class="center">Hardware topology, as shown by `lstopo`.</figcaption>
</figure>

<p>This matters, because anything connected to the CPU via the chipset shares the
bandwidth of a limited x4 link. This was apparent when running two NVMe drives and
noticing that one of them was much slower when I also put load on SATA SSD-s.</p>
<p>GPU-s can still work fine when connected via the chipset, but there&rsquo;s definitely
a performance penalty involved. While I don&rsquo;t have the exact numbers available
at this time, I do remember a CSGO benchmarking map showing at least a double-digit
framerate difference compared to the full x16 slot.</p>









<figure class="center">
  <a href="/posts/2022/02/02/asrock-x570m-pro4-overview/media/gpu-in-chipset.jpg">
    <img src="/posts/2022/02/02/asrock-x570m-pro4-overview/media/gpu-in-chipset_hu_9392dfe09abc1536.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The GPU works just fine in the chipset PCIe slot, albeit at lower performance.">

  </a>
  <figcaption class="center">The GPU works just fine in the chipset PCIe slot, albeit at lower performance.</figcaption>
</figure>

<p>I also gave PCIe bifurcation a go. I borrowed an ASUS PCIe adapter card that can
support up to 4 NVMe SSD-s, hoping that I could set up a crazy storage setup.
The bifurcation works, but for the CPU I used (AMD Ryzen 7 5700G) I was only
provided the option of 2x4 split, which meant that at most I could run two SSD-s
in the riser card at a time. A non-APU Ryzen CPU is likely needed to take full
advantage of the bifurcation support.</p>









<figure class="center">
  <a href="/posts/2022/02/02/asrock-x570m-pro4-overview/media/bifurcation-uefi.jpg">
    <img src="/posts/2022/02/02/asrock-x570m-pro4-overview/media/bifurcation-uefi_hu_471a7ba53278b5d0.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The setting that controls bifurcation in ASRock UEFI settings.">

  </a>
  <figcaption class="center">The setting that controls bifurcation in ASRock UEFI settings.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2022/02/02/asrock-x570m-pro4-overview/media/bifurcation-card.jpg">
    <img src="/posts/2022/02/02/asrock-x570m-pro4-overview/media/bifurcation-card_hu_9f046ac9c2554355.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="ASUS Hyper M.2 PCIe card installed in the system.">

  </a>
  <figcaption class="center">ASUS Hyper M.2 PCIe card installed in the system.</figcaption>
</figure>

<p>For VFIO, this board is fine. Anything in PCIe slots, including the chipset ones,
I was able to pass through to the VM. USB and SATA ports were a different story,
I wasn&rsquo;t able to pass through a single controller, the VM would not start up
properly.</p>
<p>If you have an use case where you need reliable and fast PCIe connectivity,
then I&rsquo;d recommend another platform that has lots of real PCIe connectivity,
such as the AMD Threadripper/EPYC platform. This board exhibited some odd
behaviour when trying to utilize all the PCIe slots, or when trying to use the
ASUS Hyper M.2 card in bifurcation mode while also having the GPU connected at
the bottom PCIe x16 slot.</p>
<h2 id="chipset-fan">
  <a class="heading-anchor" href="#chipset-fan">Chipset fan<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>One aspect of X570 boards that stuck out to most people on release was the
inclusion of a chipset fan. Not too long after, people started to report that
those fans are very loud and low quality, resulting in them failing easily.</p>
<p>For this particular board, ASRock provides an option in UEFI settings that allows
you to run this chipset fan semi-passively. It will spin up once on boot and
sit idle the rest of the time, unless the temperatures are high enough. I was
not able to get that fan to spin even with a full GPU load and all SSD-s running
heavy read operations at the same time.</p>
<p>If you have PWM fans, it&rsquo;s also possible to manually control these in Linux
with the use of <a href="https://wiki.archlinux.org/title/fan_speed_control#Fancontrol_%28lm-sensors%29">fancontrol</a>.
For me, it just took a bit of trial and error to figure out the mapping between
the software fan controls and the actual fan in the PC, after that I could
fine-tune them to run as quietly as possible. Yes, even the chipset fan was
controllable using the same method.</p>
<h2 id="am4-socket-long-term-support">
  <a class="heading-anchor" href="#am4-socket-long-term-support">AM4 socket long term support<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>AMD introduced the <a href="https://en.wikipedia.org/wiki/Socket_AM4">AM4 socket</a> back in
2016 and promised to support it until 2020. I applaud that effort and am
happy that I was able to run the latest AMD Ryzen 5000 series APU on a B450
board. If you happen to have a newer CPU that requires a UEFI upgrade for it to
be supported, then you will be in a world of hurt.</p>
<p>I found myself in a situation where I had a motherboard that didn&rsquo;t have the
newest UEFI version from the factory, and a CPU that was just a bit too new for
it to work. The board supported AMD Ryzen 5000 series CPU-s, not 5000 G-series
CPU-s. I also didn&rsquo;t have an older CPU available that I could use to perform
this upgrade on my own. Luckily I was able to find a loaner 5000 series CPU,
perform the upgrade and finally assemble the machine.</p>
<p>At least ASRock puts a sticker with the UEFI version on the chip itself so that
you can check the CPU support once you physically have the motherboard, but it&rsquo;s
pretty much useless when buying this board online. There&rsquo;s no indication as to
which version it will ship with, the best you can do is to look for some Reddit
threads where others have shared their experiences with the board and the UEFI
version it shipped with from the factory.</p>
<p>Pro tip for CPU and motherboard manufacturers: if you&rsquo;re going for long-term
support on your platform, please include a CPU-less UEFI upgrading solution.
Some high-end motherboards already ship with that type of functionality, but I
believe it should be made mandatory for all boards. Avoiding headaches like that
will be worth the extra cost.</p>
<h2 id="verdict">
  <a class="heading-anchor" href="#verdict">Verdict<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It&rsquo;s fine, looks good and gets the job done. Can&rsquo;t recommend it for someone who
needs a lot of performance and PCIe lanes, but for hobbyist workloads it will
<em>probably</em> be just fine. UEFI flashing situation really soured the experience
though.</p>
]]></content:encoded></item><item><title>VR, VFIO and how latency ruined everything</title><link>https://ounapuu.ee/posts/2021/12/29/vr-vfio-latency/</link><pubDate>Wed, 29 Dec 2021 06:00:00 +0200</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/12/29/vr-vfio-latency/</guid><description>Alternative title: "Honey, I completely changed my server setup again!"</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="VR, VFIO and how latency ruined everything" /><p>I&rsquo;ve been running my <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/"><em>all-in-one</em></a>
PC for a while now. It was my desktop, my NAS and my gaming PC.
However, during the next couple of months I kept hitting small bumps along the
road. Most of these were quite straightforward to fix, but there is one that
finally convinced me to go back to a simpler setup.</p>
<h2 id="iscsi">
  <a class="heading-anchor" href="#iscsi">iSCSI<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>As mentioned in <a href="/posts/2021/10/13/diy-cloud-gaming-nvidia-moonlight/">one of my previous posts</a>,
I had set up the storage on my gaming VM over iSCSI. If you don&rsquo;t know what
iSCSI is: think of it like a hard drive that you can hook up to your machine
over the network. This setup had a couple of benefits: the amount allocated to
the VM was flexible and I would always have a snapshot of my game data in case
the Windows VM decided to nuke itself.</p>
<p>What I didn&rsquo;t take into account was the configuration. <code>tgt</code> allows you to
define the IP address of the client machine, which can be seen as an additional
layer of security. My gaming VM has two virtual NIC-s, one pointing to the
actual physical network, and another one to a virtual one. This resulted in the
iSCSI connection being flaky on startup: the disk was not present in the VM on
first boot, but was there after a reboot.</p>
<p>This issue was gone once I removed this restriction from the iSCSI target
configuration on the Linux VM. My best guess is that the iSCSI stack in Windows
might have tried to initiate a connection over the wrong NIC, depending on
whichever one was brought up first.</p>
<p>After &ldquo;solving&rdquo; this issue, it had been smooth sailing.</p>
<h2 id="gpu-audio-issues">
  <a class="heading-anchor" href="#gpu-audio-issues">GPU audio issues<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>When the Windows VM had been on for a while, the HDMI audio output would start
to glitch out after a while, with the audio sounding slow, robotic and garbled.
After doing some research, I found some resources that mentioned enabling MSI
interrupts in Windows. The guide for this can be found over at
<a href="https://forums.guru3d.com/threads/windows-line-based-vs-message-signaled-based-interrupts-msi-tool.378044/">Guru3D forums</a>.</p>
<p>After tweaking the Windows registry settings and reminding myself that I do have
snapshots to fall back to in case I mess up, I got the issue fixed.</p>
<h2 id="gpu-driver-issues">
  <a class="heading-anchor" href="#gpu-driver-issues">GPU driver issues<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Whenever there&rsquo;s a new big and popular game released, NVIDIA usually releases
an updated version of their GPU drivers. I try to keep my software up to date,
so I usually install these updates when they come out. Just one problem: when I
upgrade the GPU drivers in the VM, the screen will stay black. After some time
passes, I have to force a reboot using <code>virt-manager</code>.</p>
<p>I have not looked into this issue yet as it only happens during driver updates,
but it&rsquo;s definitely an annoying thing to have.</p>
<h2 id="uefi-and-csm">
  <a class="heading-anchor" href="#uefi-and-csm">UEFI and CSM<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>UEFI updates have a bad habit of resetting all the custom settings that you
have made, and at least with the motherboards I have used, the settings cannot
be restored if the backed up settings are from an older UEFI version. This
means that I have to navigate the UEFI quite often to configure all the
settings that I need to have in place for VFIO to work.</p>
<p>There is one setting that I didn&rsquo;t expect to cause that much trouble though:
CSM support. CSM (compatibity support module) is generally enabled by default
and allows you to boot off of legacy operating systems if needed. I don&rsquo;t have
that requirement, so I went ahead and set my boot options to boot in UEFI mode
only.</p>
<p>Reboot, start up Fedora, and boom, anything VFIO related is spewing errors like
crazy.</p>
<p>Turns out that enabling UEFI only mode in UEFI settings somehow grabs the GPU
and causes problems when you try to then pass the GPU to a VM. While in this
mode, I noticed that the GPU was also shown in a separate menu in UEFI settings.
Enabling CSM support fixed this issue for me.</p>
<h2 id="vr-and-usb-issues">
  <a class="heading-anchor" href="#vr-and-usb-issues">VR and USB issues<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>With the situation in the world being less than optimal, I decided to spice up
my gaming setup with the addition of a <a href="https://www.vive.com/us/product/vive-cosmos/features/">HTC Vive Cosmos</a>
in case in-door activities become much more popular suddenly.</p>
<p>First issue: I can&rsquo;t get the damn thing working. My gaming VM setup has the
<a href="https://www.inateck.com/products/inateck-kt4006-dual-port-usb-3-0-pci-express-card-20-pin-connector-no-power-connection">inateck KT4006</a>
passed through so that I can plug peripherals to the PC and make them available
to the gaming VM with ease. After plugging everything in according to
instructions and turning the link box on, I&rsquo;m met with a barrage of USB
connected-disconnected sound effects. 6 or 7 cycles later the sound stops, and
with that do the rest of my USB devices.</p>
<p>I took the USB 3.0 card and tried it in an older machine that doesn&rsquo;t have a
fancy VFIO setup on it. Same issue. However, when connected to an USB 2.0 port,
the setup shows a warning in VIVE Console, but at least it works! Since my PC
literally has no USB 2.0 ports, I had to get a bit creative and plug an USB 2.0
extension cable between the PC and the USB 3.0 cable coming from the link box.</p>
<p>With the help of my friend I got confirmation that the issue is indeed with my
USB ports. I also ordered a different USB PCIe card from inateck, this time the
<a href="https://www.inateck.com/products/pci-e-to-usb-3-0-4-ports-pci-express-card-and-15-pin-power-connector-red-kt4001">inateck KTU3FR-4P</a>.
I made the assumption that since <a href="https://www.vive.com/eu/support/vive/category_howto/headset-not-detected-due-to-usb-issue.html">the VIVE support page also recommends an inateck card</a>,
then they must be fit for purpose.</p>
<p>Nope. The second card apparently has the same chipset and the same issue.</p>
<p>What did end up working was a random VIA USB 3.0 PCIe card, which shows up as
<code>VIA Technologies, Inc. VL805/806 xHCI USB 3.0 Controller</code> on my machine. Just
one issue: it has PCIe device reset issues. If I shut down the Windows VM and
start it up again, I would sometimes get a bunch of <code>IO_PAGE_FAULT</code> errors in
my kernel logs. No worries, guess I&rsquo;ll just avoid rebooting a notoriously
reboot-happy OS.</p>
<h2 id="latency-the-straw-that-broke-the-camels-back">
  <a class="heading-anchor" href="#latency-the-straw-that-broke-the-camels-back">Latency: the straw that broke the camel&rsquo;s back<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>If there&rsquo;s one thing you don&rsquo;t want to see in a VR gaming setup, it&rsquo;s latency.</p>
<p>I&rsquo;ve covered <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/">the tweaks I&rsquo;ve made to my setup in a previous post</a>.
Turns out that those might not be enough. The <a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Example_with_systemd">CPU isolation using systemd</a>
works well in general, but not with kernel threads.</p>
<p>Whenever I did something IO heavy on an NVMe-based btrfs file system, it would
introduce stutter to the gaming VM. Running a scrub operation on the filesystem
was enough to put a huge load on the CPU, likely due to the raw speed that the
NVMe SSD-s can provide. This results in the gaming VM experiencing stutter
that ruins the whole experience.</p>
<p>Here&rsquo;s an illustration.</p>









<figure class="center">
  <a href="/posts/2021/12/29/vr-vfio-latency/media/normalusage.jpg">
    <img src="/posts/2021/12/29/vr-vfio-latency/media/normalusage_hu_bddd6f0b9c862f0f.webp"
     width="956"
     height="800"
     loading="lazy"
     decoding="async"
     alt="SteamVR performance statistics with a light load on the host system.">

  </a>
  <figcaption class="center">SteamVR performance statistics with a light load on the host system.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/12/29/vr-vfio-latency/media/latencyhell.jpg">
    <img src="/posts/2021/12/29/vr-vfio-latency/media/latencyhell_hu_6ffdf367424bccee.webp"
     width="927"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The purple spikes mean that you are having a real bad time right now.">

  </a>
  <figcaption class="center">The purple spikes mean that you are having a real bad time right now.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/12/29/vr-vfio-latency/media/latencynative.jpg">
    <img src="/posts/2021/12/29/vr-vfio-latency/media/latencynative_hu_d9c371c91ecc08fe.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="For comparison: VR performance running natively on Windows 10.">

  </a>
  <figcaption class="center">For comparison: VR performance running natively on Windows 10.</figcaption>
</figure>

<p>Similar issues could be observed whenever I tried to run another VM that
shares the same cores.</p>
<p>I looked into alternative solutions as well, and it does seem to be possible
to also isolate those CPU cores from the kernel. They will probably work to
some extent, but implementing them feels a bit hacky at the moment. I&rsquo;m hoping
that in the future these kinds of tweaks will be exposed as a simple checkbox
in <code>virt-manager</code> itself.</p>
<p>At that point I had enough. If I&rsquo;m not going to be able to use the machine for
other purposes at the same time without experiencing all these issues and
having to work around them, then I&rsquo;ll just go back to a simpler setup. I&rsquo;ll lose
some of the benefits, but at least I don&rsquo;t have to spend time debugging all
these issues.</p>
<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>VFIO and virtualization are still interesting topics to learn about and try
out, but for my use case they are just too limiting. I&rsquo;d imagine that an use
case that didn&rsquo;t have such strict latency requirements would still be able to
run just fine, unfortunately gaming just isn&rsquo;t one of them.</p>
<p>This experience has been quite fun in general, but I&rsquo;m calling quits, at least
for now. The one machine that does it all turned out to be a jack of all
trades, master of none.</p>
]]></content:encoded></item><item><title>DIY cloud gaming: NVIDIA and Moonlight</title><link>https://ounapuu.ee/posts/2021/10/13/diy-cloud-gaming-nvidia-moonlight/</link><pubDate>Wed, 13 Oct 2021 05:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/10/13/diy-cloud-gaming-nvidia-moonlight/</guid><description>Comparing the experience that AMD and NVIDIA can provide in a DIY cloud gaming setup.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="DIY cloud gaming: NVIDIA and Moonlight" /><p>As you might have read from <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/">my previous post on this topic</a>, I
have a pretty neat &ldquo;cloud&rdquo; gaming setup running. I have one powerful desktop PC, one virtual machine with a GPU attached
to it, and client machines that can be used to stream games from. To keep things simple (and because my current ISP is
unbelievably bad), I have so far used streaming only over my local network.</p>
<p>However, there were some pretty annoying issues with this setup:</p>
<ul>
<li>The AMD GPU encoder is bad. 720p streaming was the best I could do if I wanted reasonable performance.</li>
<li>The Windows 10 VM would sometimes not be able to start the host encoder, and the GPU drivers reported issues. This was
fixed with a couple of reboots to the VM and I suspect that this may be related to the notorious GPU reset issues that
AMD cards are infamous for in the VFIO world, but I wasn&rsquo;t interested in digging that deep into that topic.</li>
<li>The stream would sometimes randomly crash or lag. This might have been down to the AMD GPU
or <a href="https://parsec.app/">Parsec</a> itself.</li>
</ul>
<p>I read about this topic for a while and found that the overwhelming number of threads related to this topic recommend an
NVIDIA GPU and Moonlight for the best streaming experience. And so I went out to get one.</p>
<h2 id="the-gpu">
  <a class="heading-anchor" href="#the-gpu">The GPU<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>It&rsquo;s 2021. The world is on fire and GPU prices are insane. With that in mind, I tempered my expectations and went for
something simple: a NVIDIA GTX 1060 6G by MSI. Simple, relatively modern for my games and the price was around the
retail price 5 years ago (260 EUR), which is the best you can do in these lousy times.</p>
<p>But hey, it works! From the testing I
did <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/">in a previous post</a>, I knew that NVIDIA had finally
stopped intentionally throwing <code>error code 43</code> in their drivers, which made this option viable. Replacing the GPU was
simple, I just had to change the PCI device ID-s according to the VFIO setup guide and changed the devices attached to
the Windows 10 VM using <code>virt-manager</code>, and that was it!</p>
<h2 id="parsec-amd-vs-nvidia">
  <a class="heading-anchor" href="#parsec-amd-vs-nvidia">Parsec: AMD vs NVIDIA<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Since I was already using Parsec for my streaming purposes, I decided to do a quick test to see what the difference is
between the two cards.</p>
<p>The previous GPU was an AMD Radeon RX 570 4GB by Sapphire. These two GPU-s are in the same performance class, which
makes for a good comparison.</p>
<p>Here are some results taken in two quick testing sessions in Dirt Rally. Take these results with a spoonful of salt as
these have not been conducted with any kind of standards. I just picked the same graphics preset, resolution and let it
run with Parsec statistics view open.</p>
<h3 id="h264">
  <a class="heading-anchor" href="#h264">H.264<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>AMD RX 570: 10ms</p>
<p>NVIDIA GTX 1060: 3ms</p>
<h3 id="h265">
  <a class="heading-anchor" href="#h265">H.265<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h3>
<p>AMD RX 570: 8ms</p>
<p>NVIDIA GTX 1060: 3ms</p>
<p>The difference in the encode performance is huge, especially if you consider that the time between two frames is 16.6ms
for a 60 FPS stream. Some of that budget is also taken up by network and decode latency in the client, so the shorter
the encode time is, the better.</p>
<p>Parsec is fine, but I have had some trouble getting GPU-accelerated decode working on my Linux clients, and it also
lacks an iOS client. While the latter isn&rsquo;t a deal-breaker, the first one definitely is.</p>
<h2 id="moonlight-an-open-source-gem">
  <a class="heading-anchor" href="#moonlight-an-open-source-gem">Moonlight: an open-source gem<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p><a href="https://moonlight-stream.org/">Moonlight</a> is an alternative to Parsec. It implements the NVIDIA GameStream protocol and
has clients for most common platforms. My testing has been performed on Linux clients running Fedora 34, a Windows 10
laptop (ThinkPad X230), iPhone SE 2020 and an old Google Nexus 5. I also made an attempt to run the Moonlight client on
a Raspberry Pi 1 B+, but it seems that it is simply too old for the Moonlight client, resulting in an error on startup.</p>









<figure class="center">
  <a href="/posts/2021/10/13/diy-cloud-gaming-nvidia-moonlight/media/image.jpg">
    <img src="/posts/2021/10/13/diy-cloud-gaming-nvidia-moonlight/media/image_hu_10280f4a7e25eb3d.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="GTA V on a Google Nexus 5? More likely than you think.">

  </a>
  <figcaption class="center">GTA V on a Google Nexus 5? More likely than you think.</figcaption>
</figure>

<p>To set up Moonlight, I opened up the client and tried the automatic detection over the network. Unfortunately that did
not yield any results, so I input the IP address of the Windows VM manually. That worked well. This initiated a pairing
process that I had to continue using Parsec, because you need to input a code on the host machine. After that, I had to
quit Parsec and start streaming using Moonlight.</p>
<p>OK, not quite yet. Moonlight is able to detect the games installed on your system, but for a remote desktop experience,
you
<a href="https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide#using-moonlight-to-stream-your-entire-desktop">have to do a small tweak</a>
for it to be equivalent to the experience you get from Parsec.</p>
<p>One thing that I noticed at the start was that the image quality on the desktop isn&rsquo;t as good as on Parsec. However, it
more than makes up for it in-game. Moonlight just works. There are plenty of knobs you can turn as well, including
configuring the image quality by setting the resolution, framerate and network limits.</p>
<p>What makes Moonlight more suitable for me is that
the <a href="https://flathub.org/apps/details/com.moonlight_stream.Moonlight">Linux client packaged as a Flatpak</a>
is able to use the GPU for hardware-accelerated decode. The experience is great on a Linux machine and it just works,
which is not something you can always expect to happen. Even an older XBOX ONE controller connected over Bluetooth works
just fine over Moonlight!</p>
<p>The only issues that I had with Moonlight were later determined to be caused by networking issues. This shows up well on
the integrated statistics that Moonlight provides using the <code>Ctrl + Alt + Shift + S</code> key combination under
the <code>Network jitter</code> field. After stopping some services on my network, the issues went away.</p>
<h2 id="the-setup-one-month-later">
  <a class="heading-anchor" href="#the-setup-one-month-later">The setup: one month later<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>After a month of use, I have made some adjustments to the setup. I used to keep the VM running so that I could just jump
in and start playing whenever I liked it, but due to a tweak I made in the name of improving gaming performance, half
the CPU cores on my system were not available for other purposes, such as suffering through IntelliJ indexing the
project again. I decided to only power on the VM if I actually was about to take the time to play it. I haven&rsquo;t yet
figured out the best way to make this more convenient, though. I did make the &ldquo;Calculator&rdquo; key on my keyboard start/stop
the VM on demand, but then GNOME started ignoring the shortcut I had setup and opened the calculator anyway, so that was
a short-lived tweak.</p>
<p>A bigger change that I made to the setup was to store all my games on my ZFS pool that lives in another VM. For that,
I <a href="https://forum.level1techs.com/t/run-your-steam-library-from-a-nas-break-a-leg-challenge-update/107912">setup an iSCSI target using this guide as a starting point</a>
. I used the <a href="https://packages.debian.org/bullseye/tgt">tgt</a> package instead. That has worked out surprisingly well, but
the iSCSI target does not want to properly connect in the Windows VM on the first boot, which is mildly annoying. I soon
discovered that spinning rust just does not cut it and got more SSD-based storage, otherwise other processes on the NAS
could wreak havoc on the gaming experience in games like GTA V. Those issues were manifesting as long loading times and
objects popping in too late, resulting in half the roads and building being missing while driving around the map. The
iSCSI target solution also comes with the added bonus of having a proper backup of all my games. If Windows decides to
blow itself up again and I don&rsquo;t have a backup of the VM ready, then I could just reinstall it and not worry about
downloading and installing all the games again.</p>
<h2 id="verdict">
  <a class="heading-anchor" href="#verdict">Verdict<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Overall, I&rsquo;m very happy about the setup. I don&rsquo;t use it all too often, but occasionally launching <em>art of rally</em> or
<em>BeamNG.drive</em> on any random device I own is great. I do have some concerns about the future of this setup, especially
with Windows 11 having more strict system requirements and newer games demanding more performance. For the time being,
this works and I intend to keep it that way.</p>
<p><em>The one box that does it all</em>: so far so good!</p>
]]></content:encoded></item><item><title>DIY cloud gaming setup with VFIO, Parsec and AMD</title><link>https://ounapuu.ee/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/</link><pubDate>Tue, 07 Sep 2021 06:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/</guid><description>A build log of how I set up my own 'cloud gaming' setup, including all the issues I faced and attempts to fix those.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="DIY cloud gaming setup with VFIO, Parsec and AMD" /><p>This is a follow-up to <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/">my previous post</a> where I covered
the VFIO setup in general. For many people that would have been good enough, but my goal with this setup was to have a
powerful gaming setup that I could access from my living room PC with 20 meters of Ethernet cables between the two.</p>
<h2 id="cloud-gaming">
  <a class="heading-anchor" href="#cloud-gaming">Cloud gaming?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>The concept of <a href="https://en.wikipedia.org/wiki/Cloud_gaming">cloud gaming</a> has become more popular lately,
with <a href="https://www.xbox.com/en-US/xbox-game-pass/cloud-gaming">Microsoft</a>,
<a href="https://stadia.google.com/">Google</a>, <a href="https://www.NVIDIA.com/en-eu/geforce-now/">NVIDIA</a> and others offering services
that allow you to stream games to your device. These setups usually include a powerful server in a datacenter rendering
the game and sending the compressed video stream to your device. This works surprisingly well, but due to high cost,
poor internet connectivity in many places in the world
and <a href="https://www.NVIDIA.com/en-us/geforce/forums/gfn-announcements/22/346564/2k-games-on-geforce-now/">licensing issues</a>
, this setup might not work well for everyone.</p>
<p>However, if you already own a moderately powerful gaming PC and would like to use it to play games you already own over
the network, then there are plenty of solutions that can get you there.</p>
<p>Here are some options:</p>
<ul>
<li><a href="https://store.steampowered.com/remoteplay">Steam remote play</a>: works for games launched via Steam.</li>
<li><a href="https://parsec.app/">Parsec</a>: able to stream the whole desktop, including games.</li>
<li><a href="https://moonlight-stream.org/">Moonlight</a>: same, but only usable on hosts with NVIDIA GPU-s due to the implementation
relying on NVIDIA&rsquo;s GameStream protocol.</li>
</ul>
<p>In the past, I&rsquo;ve had OK results with Steam remote play, but the limiting factor has been the reliance on Steam. I have
bought a couple of games from <a href="https://www.gog.com/">GOG</a> as well, which I could probably also play remotely by
launching them via Steam, I just don&rsquo;t want to go through the hassle.</p>
<p>For this setup I&rsquo;ve opted to go with Parsec. It&rsquo;s not perfect, but it&rsquo;s still good enough for our purposes. The GPU
we&rsquo;re using (AMD Radeon RX 570) also limits our options because it won&rsquo;t work with Moonlight.</p>
<p>The installation of Parsec is pretty straightforward: just install it on your host and client machines. In my case the
client machine is
a <a href="/posts/2021/06/28/breaking-and-fixing-thinkpad-x230/">Lenovo ThinkPad X230 that was brought back from the dead</a>
. It&rsquo;s not powerful, but at least it can do H.264 hardware decoding and it uses only 12W of power when idle, making it a
perfect candidate for testing this out. It&rsquo;s also worth mentioning that both machines are connected on the local network
using an Ethernet connection to avoid Wi-Fi becoming a bottleneck.</p>
<h2 id="vfio-gaming-and-you">
  <a class="heading-anchor" href="#vfio-gaming-and-you">VFIO, gaming and you<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>What turned out to be a bigger hurdle was the performance of games inside the VM. After getting everything running with
the VFIO setup, I didn&rsquo;t really spend any time trying to optimize the setup for the smoothest experience. When trying to
actually run this setup, I ran into quite a few problems with performance which mainly manifested as stutters and
unusually low framerates. Turns out that gaming has stricter latency requirements than other server workloads.</p>
<p>Thanks to the <a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Performance_tuning">great guide in Arch Wiki</a>,
I could get a lot of ideas on what to try out to improve the performance of this gaming virtual machine.</p>
<p>Before doing anything, I ran some benchmarks to get a sense of what performance levels I&rsquo;m dealing with. To test out
each individual change, I used GTA V as the gaming benchmark since it was pretty good at pointing out any performance
issues.</p>
<p>Here&rsquo;s a list of things that I ended up doing:</p>
<ul>
<li>setting the CPU model to <code>host-passthrough</code> in <code>virt-manager</code></li>
<li><a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Dynamically_isolating_CPUs">isolating CPU-s dynamically</a>
whenever the VM starts
and <a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#CPU_pinning">pinning those CPU-s</a> to the VM to avoid
the host OS and other VM-s from using those cores</li>
<li>setting the CPU governor to performance on isolated cores to rule out issues with the CPU not clocking high enough and
switching between idle/load power
modes: <code>echo performance &gt; /sys/devices/system/cpu/cpu[4-7]/cpufreq/scaling_governor</code></li>
<li><a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Static_huge_pages">enabling static hugepages</a> to rule out
issues stemming from poor memory access speeds</li>
<li>disabling SMT in UEFI settings to get rid of one additional variable</li>
<li>getting a 64 GB DDR4-3600 memory kit to allocate more RAM to the VM (16 GB) and leave enough for the host machine and
other services</li>
</ul>
<p>The golden rule of troubleshooting is to change one variable at a time and comparing results. Not every change that I
made ended up being a positive one. For example, when configuring the VM to use 4 cores and 8 threads instead of plain 4
cores, I saw the framerates in GTA V drop 50%. I assume that the VM treated the &ldquo;SMT cores&rdquo; as real ones, causing the
Windows scheduler to make incorrect decisions.</p>
<p>After playing around with this setup and accumulating these tweaks, I managed to get rid of most of the issues that
bothered me during gaming, resulting in a much smoother experience. It finally felt like the gaming VM behaved like a
machine with a 4 core CPU, 16 GB of RAM and an AMD RX 570 inside it.</p>









<figure class="center">
  <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/cpu-before.png">
    <img src="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/cpu-before_hu_f313c6dcbae3d716.webp"
     width="649"
     height="145"
     loading="lazy"
     decoding="async"
     alt="Passmark PerformanceTest CPU results before any tweaks.">

  </a>
  <figcaption class="center">Passmark PerformanceTest CPU results before any tweaks.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/cpu-after.png">
    <img src="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/cpu-after_hu_442aa75b18b01707.webp"
     width="961"
     height="209"
     loading="lazy"
     decoding="async"
     alt="Passmark PerformanceTest CPU results after tweaks.">

  </a>
  <figcaption class="center">Passmark PerformanceTest CPU results after tweaks.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/memory-before.png">
    <img src="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/memory-before_hu_d05a9f2cbaae0f6a.webp"
     width="539"
     height="142"
     loading="lazy"
     decoding="async"
     alt="Passmark PerformanceTest memory results before any tweaks.">

  </a>
  <figcaption class="center">Passmark PerformanceTest memory results before any tweaks.</figcaption>
</figure>










<figure class="center">
  <a href="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/memory-after.png">
    <img src="/posts/2021/09/07/diy-cloud-gaming-vfio-parsec-amd/media/memory-after_hu_e2a84ae685917fe.webp"
     width="810"
     height="206"
     loading="lazy"
     decoding="async"
     alt="Passmark PerformanceTest memory results after tweaks.">

  </a>
  <figcaption class="center">Passmark PerformanceTest memory results after tweaks.</figcaption>
</figure>

<p>At this point I&rsquo;d consider the setup to be fantastic for someone who wants to play games with a VFIO setup. Since I was
using this setup over the network with Parsec, I soon ran into more issues, but this time with the GPU.</p>
<h2 id="gpu-issues">
  <a class="heading-anchor" href="#gpu-issues">GPU issues<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Parsec and other similar solutions rely on the host GPU to encode the image into a video stream using the encoder
present on the GPU die itself. You might see this being referred to as <em>hardware encoding</em> in settings. What I didn&rsquo;t
know before trying this setup is that AMD GPU encoders have a reputation
for <a href="https://support.parsec.app/hc/en-us/articles/115002683371-Troubleshooting-Lag-Latency-and-Quality-Issues">just being plain bad</a>:</p>
<blockquote>
<p>If the host has an AMD card, AMD is usually known for having worse encode than NVIDIA and even Intel.
You should be fine at low resolutions. If all guests support H.265 and have it turned on,
you may see better performance than with it off</p>
</blockquote>
<p>And this shows. When trying to stream at 1080p, the result was a stuttery and inconsistent mess. Imagine trying to play
at around 30fps with the frame timings graph resembling a heart rate monitor, that&rsquo;s what it felt like. At 720p, the
experience was so much smoother. Yes, the image quality suffers because of that, but at least it was mostly playable.</p>
<p>I decided to also try out if changing the codec from H.264 to H.265 has a significant impact. I did a quick test in Dirt
Rally due to it having a benchmark loop mode and checked the statistics that Parsec shows. With H.264, I saw encode
latency of about 10ms. With H.265, this latency was now at 8ms. Still not great, but it is technically a ~20%
improvement. The downside of this for my setup is that the client laptop simply does not support hardware accelerated
H.265 decode, which is something that Intel integrated graphics received support for in 7th gen CPU-s.</p>
<p>The GPU seems to also cause some trouble for Parsec, as it would fail to connect occasionally and reports a host encoder
issue. This is usually overcome by rebooting the VM, which can get quite annoying after a couple of times. At other
times, Parsec sometimes just froze during gameplay and caused the client to freeze at 100% CPU usage. Not what I&rsquo;d call
smooth sailing.</p>
<p>Another issue that I noticed by using <a href="https://www.msi.com/Landing/afterburner/graphics-cards">MSI Afterburner</a> is that
the framerate was still not that stable in some games, such as GTA V. After all the fixes and tweaks, there were still
small stutters, even with vsync enabled. I decided to look over AMD Radeon settings to see if a driver feature had an
unintended side effect. I had picked the <em>Gaming</em>
preset because that was what I was using this GPU for, but decided to switch to the <em>Standard</em> mode instead. And just
like that, the stutters were gone! I suspect that the <em>Radeon Anti-Lag</em> feature might have been the cause to this, as
that was one of the main settings that was disabled after switching to the <em>Standard</em> settings preset.</p>
<h2 id="is-it-worth-it">
  <a class="heading-anchor" href="#is-it-worth-it">Is it worth it?<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I like a technical challenge and going through all the attempts to get more and more performance out of this setup was
interesting for me. However, it might not be the same way for everyone else. If you still feel like you want to go
through this and learn something along the way, then feel free to use this as a guide on what you can try. Make sure to
also read up on experiences that others have had with these tweaks and always measure your results to see if they had
the intended effect.</p>
<p>For those who just want to play games and not worry too much about getting the expected performance out of your machine,
I&rsquo;d still recommend going with building a separate gaming PC.</p>
<p>If I had to build a machine specifically for this type of workload, then I&rsquo;d make these changes:</p>
<ul>
<li>Replace the CPU with a non-APU model, such as the Ryzen 9 5950X. Due to
the <a href="https://images.anandtech.com/doci/16214/Ryzen9_3800X_Hand_575px_678x452.jpg">physical core layout</a> you could
assign one CPU core complex to the gaming VM and leave everything else to the host. These CPU-s also have a lot of L3
cache, which should help in workloads that require low latency, such as games.</li>
<li>If you&rsquo;re going for a streaming setup, then I&rsquo;d try it first with an NVIDIA GPU. The error code 43 issues are gone
now, making it a viable option with solutions like Moonlight.</li>
<li>More SATA or M.2 slots on the system. This makes passing through storage devices so much easier.</li>
</ul>
<h2 id="future-plans">
  <a class="heading-anchor" href="#future-plans">Future plans<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I&rsquo;m not planning on stopping this adventure just yet. I&rsquo;ve recently looked around for an NVIDIA GPU to do a comparison
against the AMD RX 570 and picked out an NVIDIA GTX 1060, which is from the same era and performance bracket. Should
make for an interesting comparison in both <em>Parsec vs Parsec</em> and <em>Parsec vs Moonlight</em> scenarios.</p>
<p>I&rsquo;m also hoping to eventually move to a more modern client PC that can support H.265 decoding and output at higher
resolutions. Yes, 4K at 60Hz is demanding for a laptop from 2012. Given that the laptop is an older ThinkPad, I expect
that to happen after 2025.</p>
<p>Regarding the storage setup, I&rsquo;ve got input from a friend saying that I might want to try setting up a Samba share on
my &ldquo;NAS&rdquo; VM and host my Steam library and other game files on that. After all, the virtual LAN has managed hit 2-3
Gbit/s in my testing and with L2ARC being persistent in ZFS 2.0, I might be able to take advantage of that as well (
assuming that I even need L2ARC, ARC efficiency is pretty good!). Currently I just have a Syncthing sync set up between
the &ldquo;NAS&rdquo; VM and the gaming VM so that there exists at least a basic backup of all my games.</p>
]]></content:encoded></item><item><title>Testing GPU passthrough on AMD Ryzen 7 5700G APU</title><link>https://ounapuu.ee/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/</link><pubDate>Sat, 28 Aug 2021 10:00:00 +0300</pubDate><author>ihavesomethoughtsonyourblog@ounapuu.ee (Herman Õunapuu)</author><guid>https://ounapuu.ee/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/</guid><description>A quick overview of my experience with setting it up on a small PC box and things to consider when attempting this yourself.</description><content:encoded><![CDATA[<img src="https://ounapuu.ee/media/cover_hu_4fe4cf2661554252.jpg" width="1200" height="630" alt="Testing GPU passthrough on AMD Ryzen 7 5700G APU" /><h2 id="introduction">
  <a class="heading-anchor" href="#introduction">Introduction<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Before we jump into all the nitty-gritty details, I&rsquo;d like to go over what we are dealing with here since these topics
may be unfamiliar to you. VFIO is quite a niche topic and not everyone knows about it.</p>
<p><a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF">GPU passthrough</a>: the process of allowing a VM (virtual
machine) to use a dedicated GPU. This allows you to run GPU-heavy workloads inside the VM, such as gaming or anything
that benefits from GPU compute power.</p>
<p><a href="https://www.kernel.org/doc/Documentation/vfio.txt">VFIO</a>: the framework that allows us to perform this operation.</p>
<p><a href="https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit">IOMMU</a>: hardware feature that supports all
of this.</p>
<p><a href="https://virt-manager.org/">virt-manager</a>: GUI application that I use to manage VM-s.</p>
<p>Reasons why you may want to go through all the hassle and use this approach:</p>
<ul>
<li>you&rsquo;re on Linux but want to play games occasionally without rebooting into Windows</li>
<li>you want to do all your work, gaming and server workloads on one machine</li>
<li>you simply don&rsquo;t want to build a dedicated PC for playing games and would like to utilize the existing resources on
your main machine</li>
<li>you want more control over the Windows installation because you simply don&rsquo;t trust Microsoft</li>
<li>you want to have more control over the Windows installation and the ability to revert the installation to an earlier
point in time using a filesystem that supports snapshots (BTRFS, ZFS)</li>
<li>you have multiple separate VM-s for different purposes, but you would like to use one single GPU for all of them</li>
</ul>
<p>One thing to keep in mind is that the hardware you use matters a lot here as that provides the foundation for getting
this solution working. Here are some of the requirements you should know about:</p>
<ul>
<li>The GPU you want to pass through has to support UEFI. GPU-s from the past 5 years should be good on that, but if you
have a really old GPU that you want to use for testing, then that might not work out that well.</li>
<li>You need to have a good-enough CPU and plenty of RAM. After all, you&rsquo;re essentially running a full PC within another
PC.</li>
<li>Your motherboard has to support IOMMU and have IOMMU groups that allow you to isolate the GPU and only pass the GPU to
the VM. <a href="https://www.youtube.com/user/teksyndicate">Level1Techs</a> does quite a few motherboard reviews and Wendell goes
over the IOMMU groups and suitability for VFIO in them. It also helps if you look around the internet for enthusiasts
that have already bought the same motherboard, they may have posted information about the groups. Here&rsquo;s
a <a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Ensuring_that_the_groups_are_valid">handy script that allows you to check your IOMMU groups.</a></li>
<li>Some games may ban you if they detect that you are running the game inside a VM. It&rsquo;s great that they&rsquo;re trying to do
something against cheaters, but unfortunately VFIO users get unfairly treated here. Please do some research beforehand
if you play competitive multiplayer games a lot!</li>
</ul>
<p>I hope that this introduction helped you understand the basics. Now, let&rsquo;s just jump right into it.</p>
<h2 id="setup">
  <a class="heading-anchor" href="#setup">Setup<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>We&rsquo;re going to test this setup
on <a href="/posts/2021/08/07/amd-ryzen-7-5700-first-impressions/">hardware that I have covered previously</a>. What makes this
setup a bit special is that we&rsquo;re using an AMD Ryzen 7 5700G APU on an mITX motherboard and a single dedicated GPU,
allowing us to do big things in a small package. Yes, there are setups where you can do VFIO with a single GPU and pass
it between the host OS and the VM, but that setup might be a bit tricky to use.</p>
<p>The OS is Fedora 34. To get this working, I&rsquo;ve used various resources:</p>
<ul>
<li><a href="https://forum.level1techs.com/t/the-vfio-and-gpu-passthrough-beginners-resource/129897">beginners guide on Level1Techs forums</a></li>
<li><a href="https://forum.level1techs.com/t/fedora-33-ultimiate-vfio-guide-for-2020-2021-wip/163814">Fedora-specific guide by Wendell from Level1Techs</a></li>
<li><a href="https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Ensuring_that_the_groups_are_valid">this brilliant Arch Wiki guide that covers most of what you need to know about setting this up.</a>
It&rsquo;s not only useful for Arch, a lot of what is written here applies for any distro.</li>
</ul>
<h2 id="testing">
  <a class="heading-anchor" href="#testing">Testing<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>I decided to do the initial testing with the Nvidia GT 710. It&rsquo;s slow, buggy on Linux on Nouveau open source drivers,
and I had it available. I also recently heard that Nvidia stopped being hostile towards their customers in one aspect
by <a href="https://www.nvidia.com/en-us/geforce/news/outriders-game-ready-driver/">allowing GeForce GPU-s to be used in a Windows 10 VM without having to resort to workarounds.</a></p>
<p>The testing itself was relatively straightforward. The only issues I had
were <a href="https://en.wiktionary.org/wiki/PEBCAK">PEBCAK</a> issues, possibly related to me performing this testing after work.
The main issues I ran were either small typos in dracut configuration or the wrong device ID-s being added to kernel
boot parameters. Once I discovered and fixed those, it was all smooth sailing.</p>
<p>I&rsquo;m not going to rewrite a full guide here, please refer to the previously linked resources if you need more details
than that. Those resources are also much more likely to receive updates about new finds and features.</p>
<p>The steps I took were roughly these:</p>
<ul>
<li>Make sure that IOMMU was enabled in UEFI settings. It&rsquo;s probably set to <code>auto</code> by default, make sure to set it
to <code>enabled</code>.</li>
<li>Install the GPU that I want to pass through and connect it to a monitor.</li>
<li>Install virtualization packages on Fedora: <code>sudo dnf install @virtualization</code></li>
<li>Enable IOMMU and preload the VFIO kernel module by adding <code>amd_iommu=on rd.driver.pre=vfio-pci</code> to Linux kernel
parameters.
<ul>
<li>I use GRUB2, these parameters live in <code>/etc/sysconfig/grub</code>.</li>
<li>To apply these changes, you have to regenerate the GRUB configuration. Under Fedora, this is done
using <code>grub2-mkconfig -o /etc/grub2-efi.cfg</code></li>
</ul>
</li>
<li>Get the device ID-s for the GPU and the related audio device that you&rsquo;re planning on passing through
<ul>
<li>To see the devices and ID-s, run <code>lspci -nnk</code>. The ID-s look something like <code>1002:aaf0</code>.</li>
</ul>
</li>
<li>Bind the GPU to <code>vfio-pci</code> to avoid the GPU driver from taking control of the GPU, otherwise you cannot pass it to the
VM.
<ul>
<li>I opted to go for the simple approach and added the device ID-s to kernel
parameters: <code>vfio-pci.ids=1002:67df,1002:aaf0</code></li>
<li>Since I went with this approach, then I have to regenerate GRUB configuration again.</li>
</ul>
</li>
<li>Make sure that the initramfs loads the necessary vfio drivers early in the boot.
<ul>
<li>With Fedora 34, this means creating a file <code>/etc/dracut.conf.d/10-vfio.conf</code> with
contents <code>add_drivers+=&quot; vfio_pci vfio vfio_iommu_type1 vfio_virqfd &quot;</code>.</li>
<li>Make sure that you don&rsquo;t have any typos in that.</li>
<li>Regenerate the initramfs: <code>dracut -f</code></li>
</ul>
</li>
<li>Reboot!</li>
<li>Using <code>virt-manager</code>, select the VM you want to pass the GPU through and add two PCIe devices: the GPU and its
associated audio device.
<ul>
<li>If you don&rsquo;t have the VM set up yet, then proceed with the normal installation without the GPU passed through yet.
Make sure to create an UEFI VM, otherwise you might run into issues. This can be configured in <code>virt-manager</code> _
Overview_ section by selecting the Q35 chipset and setting the firmware to <code>OVMF_CODE.df</code>.</li>
<li>If you have passed through the GPU, then make sure to remove the <code>Display Spice</code> device from the VM.</li>
<li>If you want to also control the VM, you need to also pass through your USB devices, such as a Logitech wireless
receiver.</li>
</ul>
</li>
<li>Start the VM and cheer once you notice TianoCore appearing on the monitor that&rsquo;s connected to the passed through GPU!</li>
</ul>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/vfio-success.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/vfio-success_hu_199212126e9325b5.webp"
     width="1107"
     height="800"
     loading="lazy"
     decoding="async"
     alt="If you see this, then you&#39;ve just successfully passed the GPU to the VM. Congratulations!">

  </a>
  <figcaption class="center">If you see this, then you&#39;ve just successfully passed the GPU to the VM. Congratulations!</figcaption>
</figure>

<h2 id="results-nvidia-gt-710">
  <a class="heading-anchor" href="#results-nvidia-gt-710">Results: Nvidia GT 710<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Initial testing with Nvidia GT 710 was successful. By successful, I mean that the GPU displayed an image and did not
install GPU drivers automatically.</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-error-43.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-error-43_hu_326f276537db01bf.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="The infamous Nvidia error code 43.">

  </a>
  <figcaption class="center">The infamous Nvidia error code 43.</figcaption>
</figure>

<p>To overcome that last issue, I downloaded the latest official Nvidia GPU drivers and was good to go. The news were true,
error code 43 was no longer an issue!</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-postinstall.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-postinstall_hu_42e3d99bf6c38aba.webp"
     width="600"
     height="800"
     loading="lazy"
     decoding="async"
     alt="If your GPU shows up like this in Device Manager, then it should work properly.">

  </a>
  <figcaption class="center">If your GPU shows up like this in Device Manager, then it should work properly.</figcaption>
</figure>

<p>Things got a bit less exciting when I got reminded that this GPU is weak. Very weak. Regardless, I decided to
demonstrate its computing prowess by downloading the <a href="https://funselektor.itch.io/art-of-rally">art of rally demo</a>. Side
note: it&rsquo;s a great game, go try it out!</p>
<p>The demo ran! Not well, but it still ran!</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-artofrally.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/nvidia-artofrally_hu_b26dfefd5196674e.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="Not pictured: the horrible framerate.">

  </a>
  <figcaption class="center">Not pictured: the horrible framerate.</figcaption>
</figure>

<p>Satisfied with the results, I decided to go for gold and replace this GPU with the AMD RX 570 that I &ldquo;borrowed&rdquo;
from <a href="/posts/2021/08/21/turning-leftover-parts-into-a-decent-gaming-pc/">this PC I built recently</a>.</p>
<h2 id="results-amd-rx-570">
  <a class="heading-anchor" href="#results-amd-rx-570">Results: AMD RX 570<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>After switching the GPU, I replaced the device ID-s with the new values and continued with the VFIO adventure. This
time, the GPU drivers were automatically installed by Windows and everything just worked. That&rsquo;s not supposed to happen,
at least in my experience <em>something</em> always goes wrong. Always.</p>
<p>I installed the latest drivers from AMD-s website and continued with testing.</p>
<p>Furmark? Runs as expected.</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/amd-furmark.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/amd-furmark_hu_27a05e2f78a7e673.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="VM on the left, VM performance stats on the right, mess of cables everywhere.">

  </a>
  <figcaption class="center">VM on the left, VM performance stats on the right, mess of cables everywhere.</figcaption>
</figure>

<p>GTA IV? A stuttery mess, so yeah, runs as expected.</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/amd-gta-iv.jpg">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/amd-gta-iv_hu_64a674dc7b9cffa9.webp"
     width="1067"
     height="800"
     loading="lazy"
     decoding="async"
     alt="On the left: GTA IV, straight from the GPU. On the right: GTA IV, streamed via Parsec.">

  </a>
  <figcaption class="center">On the left: GTA IV, straight from the GPU. On the right: GTA IV, streamed via Parsec.</figcaption>
</figure>

<p>At this point the VM was assigned 4 CPU cores and I had performed no CPU pinning or optimizations of any kind, so the
results were pretty good.</p>
<h2 id="storage">
  <a class="heading-anchor" href="#storage">Storage<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>Because I built this setup on my current workstation/server machine, the storage situation is a bit tricky. The other VM
that runs all the services has full access to the two 12TB hard drives and I wasn&rsquo;t interested in setting up a networked
storage setup. The only free spots I had were as follows:</p>
<ul>
<li>120GB partition from the NVMe SSD. Good enough for storing the Windows 10 system files.</li>
<li>2x 250GB partitions on the Samsung SATA 1TB SSD-s. Just enough to hold my recently played games, but not much more.
Running in striped configuration under Windows.</li>
</ul>
<p>I later opted to expand the game storage partitions to 375GB, which meant that I had to get rid of the extra
overprovisioning space that I had left aside. This setup is fine, but I&rsquo;m losing out on some of the benefits that come
with a virtualized Windows setup.</p>
<p>With regards to passing this storage to the VM, I had two options:</p>
<ul>
<li>keep using the SATA virtual disk: works out of the box, but might not perform as well.</li>
<li>use <code>virtio</code>: you need to manually load and install the drivers for Windows to recognize these disks, but allegedly
this has better performance than the SATA implementation.</li>
</ul>
<p>I started off with SATA and did a comparison against <code>virtio</code> using CrystalDiskMark.</p>









<figure class="center">
  <a href="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/crystaldiskmark.png">
    <img src="/posts/2021/08/29/testing-gpu-passthrough-on-amd-ryzen-5700g/media/crystaldiskmark_hu_71252985bd8c9ed3.webp"
     width="1280"
     height="467"
     loading="lazy"
     decoding="async"
     alt="Left: SATA. Right: virtio.">

  </a>
  <figcaption class="center">Left: SATA. Right: virtio.</figcaption>
</figure>

<p><code>virtio</code> did come ahead in these comparisons, but I would probably have been fine with the SATA performance as well.</p>
<h2 id="conclusion">
  <a class="heading-anchor" href="#conclusion">Conclusion<svg class="heading-anchor__icon" viewBox="0 0 24 24" width="0.75em" height="0.75em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></a>
</h2>
<p>One of the main reasons I do these kinds of setups is the technical challenge. It sounds weird, but sometimes I am
happier after having completed something technical and novel compared to actually using the setup.</p>
<p>Previously I&rsquo;ve had mixed results with GPU passthrough,
with <a href="https://www.reddit.com/r/linuxmasterrace/comments/7ry4jr/gta_v_on_arch_linux_how_i_managed_to_get_gpu/">ThinkPad T430 and eGPU somehow managing to run GTA V in a VM</a>
, while in another testing session I ran into issues which turned out to be related to the CPU being faulty (lots of
PCIe errors).</p>
<p>I do have more practical future plans with this. The plan is to use this VM as a gaming VM that I can stream games from
using <a href="https://parsec.app/">Parsec</a>
to any device that I wish. One idea is to use the <a href="https://www.nvidia.com/en-us/shield/shield-tv/">Nvidia Shield TV</a> as
a low-power box that is capable of performing streaming. Alternatively, I could also get a super tiny form factor
Dell/Lenovo/HP PC that has plenty of power to drive a 4K display and uses a reasonable amount of power. More on that in
a future post.</p>
<p>Regarding storage I foresee an upgrade coming soon, either to the drives themselves or the whole setup since ATX
motherboards support more SATA ports and expansion cards. If you also pair that up with a case
like <a href="https://www.coolermaster.com/catalog/cases/mid-tower/masterbox-q500l/">Masterbox Q500L</a> with a good power supply
placement, then you&rsquo;d still have a relatively small setup.</p>
]]></content:encoded></item></channel></rss>