X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=main-loop.c;h=f46aece8b86b7fc27698521aa319afb1bf69f228;hb=a875711af9518f0878e084aef00c323098b8f972;hp=8c9b58c14c897766313558bd8839d612fb5749c9;hpb=9cbaacf999b01b27dc3a22502705178057af66de;p=qemu.git diff --git a/main-loop.c b/main-loop.c index 8c9b58c14..f46aece8b 100644 --- a/main-loop.c +++ b/main-loop.c @@ -109,6 +109,11 @@ static int qemu_signal_init(void) static AioContext *qemu_aio_context; +AioContext *qemu_get_aio_context(void) +{ + return qemu_aio_context; +} + void qemu_notify_event(void) { if (!qemu_aio_context) { @@ -183,14 +188,39 @@ static void glib_pollfds_poll(void) } } +#define MAX_MAIN_LOOP_SPIN (1000) + static int os_host_main_loop_wait(uint32_t timeout) { int ret; + static int spin_counter; glib_pollfds_fill(&timeout); + /* If the I/O thread is very busy or we are incorrectly busy waiting in + * the I/O thread, this can lead to starvation of the BQL such that the + * VCPU threads never run. To make sure we can detect the later case, + * print a message to the screen. If we run into this condition, create + * a fake timeout in order to give the VCPU threads a chance to run. + */ + if (spin_counter > MAX_MAIN_LOOP_SPIN) { + static bool notified; + + if (!notified) { + fprintf(stderr, + "main-loop: WARNING: I/O thread spun for %d iterations\n", + MAX_MAIN_LOOP_SPIN); + notified = true; + } + + timeout = 1; + } + if (timeout > 0) { + spin_counter = 0; qemu_mutex_unlock_iothread(); + } else { + spin_counter++; } ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout);