<div dir="ltr"><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Thu, Apr 10, 2025 at 3:18 PM Michael Scherle <<a href="mailto:michael.scherle@rz.uni-freiburg.de">michael.scherle@rz.uni-freiburg.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
I’ve encountered an issue with the new DMA-BUF -> video encoding feature <br>
in SPICE. When connecting, the first frame is only sent once the GPU <br>
renders a new frame. However, this can take quite some time if the VM is <br>
idle (e.g., sitting on the desktop), since the GPU only renders a new <br>
frame when something on the screen changes. To address this, I wanted to <br>
force a frame to be sent when the display channel is connected.<br>
<br></blockquote><div><br></div><div>Which makes sense.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
My initial, naive attempt was to grab the latest DMA-BUF on the display <br>
channel's connection in the SPICE server, encode it, and send it. <br>
However, this led to race conditions and crashes—particularly when QEMU <br>
happened to perform a scanout at the same time, closing the DMA-BUF in <br>
the process.<br>
<br></blockquote><div>By "closing" do you mean calling close() function? No, we should have ownership.</div><div>What exact race did you encounter?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
As a second approach, I modified the QXLInterface to pass the display <br>
channel on_connect event back to QEMU. I couldn’t find any existing <br>
mechanism in QEMU to detect the connection of a display channel. Within <br>
QEMU, I then used qemu_spice_gl_monitor_config, and spice_gl_refresh to <br>
trigger a spice_gl_draw. This solution works, but the downside is that <br>
it requires changes to SPICE, QEMU, and especially the <br>
QXLInterface—which is obviously not ideal.<br>
<br></blockquote><div>Not ideal is a compliment. I would say complicated, hard to maintain, adding too much coupling.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
So now I’m wondering: does anyone have a better idea for how to tackle <br>
this problem?<br>
<br></blockquote><div>I would define "the problem" first, currently you mentioned a race condition without describing the details of the race.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Best regards,<br>
Michael<br></blockquote><div><br></div><div>I could suspect the race is more in the current implementation of the interface. Indeed that interface does not fit entirely in the Spice server model.</div><div><br></div><div>Externally there are 2 functions, spice_qxl_gl_scanout and spice_qxl_gl_draw_async, the callback async_complete is used to tell Qemu when we finish with the scanout. So, spice_qxl_gl_scanout should set the scanout (or frame if you prefer), while spice_qxl_gl_draw_async tells Spice to use the scanout, till async_complete is called (which should be done in a time fashion, I think Qemu timeout is 1 second). In theory the scanout can be reused for multiple draws (which was never the case, but that's another story). In theory a partial draw of the scanout can be requested. In theory the scanout should not be used after async_complete is called as Qemu could reuse the scanout for next drawings. That last point is a bit of a problem here and to be honest something I think is an issue of the external interface definition. In hardware you set the framebuffer and the video card will continue to use it, no matter what, the computer can freeze or panic and the video card will continue to use the same frame over and over. Also, considering that the maximum that can happen is to get a partial draw that will be fixed, I think it's correct to use the last scanout to solve your initial problem.</div><div><br></div><div>Internally Spice server stores the scanout in the RedQxl thread (Qemu I/O one) but uses it in the RedWorker thread. This is pretty uncommon, usually data is passed from a thread to the other, ownership included. This, probably, leads to the race you are facing. If that's the issue I think really the best option is to fix that race.</div><div><br></div><div>Regards,</div><div>  Frediano</div><div> <br></div></div></div>