Since commit (047f7038f58 cli: add --preconfig option) QEMU is stuck with indefinite timeout in os_host_main_loop_wait() at RUN_STATE_PRECONFIG even if --preconfig option wasn't used when it's started with -nodefaults CLI option like this:
./s390x-softmmu/qemu-system-s390x -nodefaults It's caused by the fact that slirp_pollfds_fill() bails out early and slirp_update_timeout() won't be called to update timeout to a reasonable value (1 sec) so timeout would be left with infinite value (0xFFFFFFFF). Default infinite timeout though doen't make sense and reducing it to 1 second as in slirp_update_timeout() won't affect host. Fix issue by simplifying default timeout to the same 1sec as it is in slirp_update_timeout() and cleanup the later. It makes default timeout the same regardless of slirp_pollfds_fill() exited early or not (i.e. -nodefaults won't have any effect on main_loop_wait() anymore, which would provide more consistent behavior between both variants of startup). Reported-by: Lukáš Doktor <ldok...@redhat.com> Signed-off-by: Igor Mammedov <imamm...@redhat.com> --- PS: it doesn't fix issue reported by Max where "echo foo | $QEMU" is also broken due to commit 047f7038f58, but there is antoher fix on the list to fix that (either Michal's or Daniel's). --- slirp/slirp.c | 10 ++-------- util/main-loop.c | 13 ++----------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/slirp/slirp.c b/slirp/slirp.c index 1cb6b07..1112f86 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -358,13 +358,8 @@ void slirp_cleanup(Slirp *slirp) static void slirp_update_timeout(uint32_t *timeout) { Slirp *slirp; - uint32_t t; - if (*timeout <= TIMEOUT_FAST) { - return; - } - - t = MIN(1000, *timeout); + assert(*timeout > TIMEOUT_FAST); /* If we have tcp timeout with slirp, then we will fill @timeout with * more precise value. @@ -375,10 +370,9 @@ static void slirp_update_timeout(uint32_t *timeout) return; } if (slirp->do_slowtimo) { - t = MIN(TIMEOUT_SLOW, t); + *timeout = MIN(TIMEOUT_SLOW, *timeout); } } - *timeout = t; } void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout) diff --git a/util/main-loop.c b/util/main-loop.c index 992f9b0..fd23166 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -497,25 +497,16 @@ static int os_host_main_loop_wait(int64_t timeout) void main_loop_wait(int nonblocking) { int ret; - uint32_t timeout = UINT32_MAX; int64_t timeout_ns; + uint32_t timeout = nonblocking ? 0 : 1000 /* milliseconds */; - if (nonblocking) { - timeout = 0; - } /* poll any events */ g_array_set_size(gpollfds, 0); /* reset for new iteration */ /* XXX: separate device handlers from system ones */ slirp_pollfds_fill(gpollfds, &timeout); - if (timeout == UINT32_MAX) { - timeout_ns = -1; - } else { - timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS); - } - - timeout_ns = qemu_soonest_timeout(timeout_ns, + timeout_ns = qemu_soonest_timeout((uint64_t)timeout * (int64_t)(SCALE_MS), timerlistgroup_deadline_ns( &main_loop_tlg)); -- 2.7.4