qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

aio-posix: disable fdmon-io_uring when GSource is used

The glib event loop does not call fdmon_io_uring_wait() so fd handlers
waiting to be submitted build up in the list. There is no benefit is
using io_uring when the glib GSource is being used, so disable it
instead of implementing a more complex fix.

This fixes a memory leak where AioHandlers would build up and increasing
amounts of CPU time were spent iterating them in aio_pending(). The
symptom is that guests become slow when QEMU is built with io_uring
support.

Buglink: https://bugs.launchpad.net/qemu/+bug/1877716
Fixes: 73fd282e7b6dd4e4ea1c3bbb3d302c8db51e4ccf ("aio-posix: add io_uring fd monitoring implementation")
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: Oleksandr Natalenko <oleksandr@redhat.com>
Message-id: 20200511183630.279750-3-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

+20
+3
include/block/aio.h
··· 701 701 */ 702 702 void aio_context_destroy(AioContext *ctx); 703 703 704 + /* Used internally, do not call outside AioContext code */ 705 + void aio_context_use_g_source(AioContext *ctx); 706 + 704 707 /** 705 708 * aio_context_set_poll_params: 706 709 * @ctx: the aio context
+12
util/aio-posix.c
··· 682 682 aio_free_deleted_handlers(ctx); 683 683 } 684 684 685 + void aio_context_use_g_source(AioContext *ctx) 686 + { 687 + /* 688 + * Disable io_uring when the glib main loop is used because it doesn't 689 + * support mixed glib/aio_poll() usage. It relies on aio_poll() being 690 + * called regularly so that changes to the monitored file descriptors are 691 + * submitted, otherwise a list of pending fd handlers builds up. 692 + */ 693 + fdmon_io_uring_destroy(ctx); 694 + aio_free_deleted_handlers(ctx); 695 + } 696 + 685 697 void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns, 686 698 int64_t grow, int64_t shrink, Error **errp) 687 699 {
+4
util/aio-win32.c
··· 414 414 { 415 415 } 416 416 417 + void aio_context_use_g_source(AioContext *ctx) 418 + { 419 + } 420 + 417 421 void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns, 418 422 int64_t grow, int64_t shrink, Error **errp) 419 423 {
+1
util/async.c
··· 362 362 363 363 GSource *aio_get_g_source(AioContext *ctx) 364 364 { 365 + aio_context_use_g_source(ctx); 365 366 g_source_ref(&ctx->source); 366 367 return &ctx->source; 367 368 }