On 2026/03/02 5:48, Dmitry Osipenko wrote:
QEMU's display GL core is tied to main-loop thread and virtio-gpu
interacts with display while processing GPU commands. virtio_gpu_ctrl_bh()
works in generic AIO context that can be processed from vCPU thread, while
GL and UI toolkits are bound to the main-loop thread. Bounce the ctrl-bh
execution if running from a thread other than main to fix the problem.

I think you can make use of iohandler_get_aio_context() instead of bouncing.

Regards,
Akihiko Odaki


  0  SDL_GL_MakeCurrent() (libSDL3)
  1  SDL_GL_MakeCurrent_REAL() (libSDL2)
  2  sdl2_gl_make_context_current() (ui/sdl2-gl.c:201)
  3  make_current() (virglrenderer.c:639)
  4  vrend_finish_context_switch() (vrend_renderer.c:11630)
  5  vrend_hw_switch_context() (vrend_renderer.c:11613)
  6  vrend_renderer_force_ctx_0() (vrend_renderer.c:12986)
  7  virgl_renderer_force_ctx_0() (virglrenderer.c:460)
  8  virtio_gpu_virgl_process_cmd() (virtio-gpu-virgl.c:1013)
  9  virtio_gpu_process_cmdq() (virtio-gpu.c:1050)
  10 virtio_gpu_gl_handle_ctrl() (virtio-gpu-gl.c:86)
  11 aio_bh_poll() (util/async.c)
  12 aio_poll() (util/aio-posix.c)
  13 blk_pwrite() (block/block-gen.c:1985)
  14 pflash_update() (pflash_cfi01.c:396)
  15 pflash_write() (pflash_cfi01.c:541)
  16 memory_region_dispatch_write() (system/memory.c:1554)
  17 flatview_write() (system/physmem.c:3333)
  18 address_space_write() (system/physmem.c:3453)
  19 kvm_cpu_exec() (accel/kvm/kall-all.c:3248)
  20 kvm_vcpu_thread_fn() (accel/kvm/kaccel-ops.c:53)

Cc: [email protected]
Signed-off-by: Dmitry Osipenko <[email protected]>
---
  hw/display/virtio-gpu.c        | 12 +++++++++++-
  include/hw/virtio/virtio-gpu.h |  2 ++
  2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 643e91ca2a7a..d0737cbba8a2 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1126,7 +1126,16 @@ static void virtio_gpu_ctrl_bh(void *opaque)
      VirtIOGPU *g = opaque;
      VirtIOGPUClass *vgc = VIRTIO_GPU_GET_CLASS(g);
- vgc->handle_ctrl(VIRTIO_DEVICE(g), g->ctrl_vq);
+    /*
+     * Bounce handling to main-loop thread as display UI toolkit
+     * and GL context are bounded there.
+     */
+    if (qemu_get_thread_id() == g->thread_id) {
+        vgc->handle_ctrl(VIRTIO_DEVICE(g), g->ctrl_vq);
+    } else {
+        aio_bh_schedule_oneshot(qemu_get_aio_context(),
+                                virtio_gpu_ctrl_bh, g);
+    }
  }
static void virtio_gpu_handle_cursor(VirtIODevice *vdev, VirtQueue *vq)
@@ -1533,6 +1542,7 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error 
**errp)
      QTAILQ_INIT(&g->reslist);
      QTAILQ_INIT(&g->cmdq);
      QTAILQ_INIT(&g->fenceq);
+    g->thread_id = qemu_get_thread_id();
  }
static void virtio_gpu_device_unrealize(DeviceState *qdev)
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 58e0f91fda65..d3bd8ed0d28a 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -218,6 +218,8 @@ struct VirtIOGPU {
      } dmabuf;
GArray *capset_ids;
+
+    int thread_id;
  };
struct VirtIOGPUClass {


Reply via email to