On 3/3/26 07:30, Akihiko Odaki wrote: > On 2026/03/02 23:59, 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 BHs >> work in generic AIO context that can be invoked on vCPU thread, while >> GL and UI toolkits are bound to the main-loop thread. >> >> Make virtio-gpu BHs use iohandler AIO context that is handled in a >> main-loop thread only. >> >> 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-virgl.c | 4 +--- >> hw/display/virtio-gpu.c | 6 +++--- >> include/hw/virtio/virtio.h | 7 +++++++ >> 3 files changed, 11 insertions(+), 6 deletions(-) >> >> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu- >> virgl.c >> index 0f754829fb71..97baf9b8ca96 100644 >> --- a/hw/display/virtio-gpu-virgl.c >> +++ b/hw/display/virtio-gpu-virgl.c >> @@ -1203,9 +1203,7 @@ int virtio_gpu_virgl_init(VirtIOGPU *g) >> } >> #if VIRGL_VERSION_MAJOR >= 1 >> - gl->cmdq_resume_bh = aio_bh_new(qemu_get_aio_context(), >> - virtio_gpu_virgl_resume_cmdq_bh, >> - g); >> + gl->cmdq_resume_bh = >> virtio_bh_io_new(virtio_gpu_virgl_resume_cmdq_bh, g); >> #endif >> return 0; >> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c >> index 643e91ca2a7a..0d88e7b3cdff 100644 >> --- a/hw/display/virtio-gpu.c >> +++ b/hw/display/virtio-gpu.c >> @@ -1526,9 +1526,9 @@ void virtio_gpu_device_realize(DeviceState >> *qdev, Error **errp) >> g->ctrl_vq = virtio_get_queue(vdev, 0); >> g->cursor_vq = virtio_get_queue(vdev, 1); >> - g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g); >> - g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g); >> - g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g); >> + g->ctrl_bh = virtio_bh_io_new(virtio_gpu_ctrl_bh, g); >> + g->cursor_bh = virtio_bh_io_new(virtio_gpu_cursor_bh, g); >> + g->reset_bh = virtio_bh_io_new(virtio_gpu_reset_bh, g); >> qemu_cond_init(&g->reset_cond); >> QTAILQ_INIT(&g->reslist); >> QTAILQ_INIT(&g->cmdq); >> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h >> index 9dd93cf965ae..bc1ddd3bc4e0 100644 >> --- a/include/hw/virtio/virtio.h >> +++ b/include/hw/virtio/virtio.h >> @@ -547,4 +547,11 @@ QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, >> #define virtio_bh_new_guarded(dev, cb, opaque) \ >> virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb))) >> +/* >> + * The "_io" variant runs BH only on a main-loop thread, while >> generic BH >> + * may run on a vCPU thread. >> + */ >> +#define virtio_bh_io_new(cb, opaque) \ >> + aio_bh_new(iohandler_get_aio_context(), (cb), (opaque)) >> + > > The reentrancy guard virtio_bh_new_guarded() implements should be > preserved.
Thanks, now I see that the guard was addressing bug report that should be reproducible. Will take a closer look as it wasn't obvious to me how re-entrance could happen with virtio-gpu. -- Best regards, Dmitry
