coroutine: avoid co_queue_wakeup recursion
commitc40a2545700e9ad2ef67d5972484bbee4c83b2a6
authorStefan Hajnoczi <stefanha@redhat.com>
Thu, 22 Mar 2018 15:28:33 +0000 (22 15:28 +0000)
committerStefan Hajnoczi <stefanha@redhat.com>
Tue, 27 Mar 2018 12:05:28 +0000 (27 13:05 +0100)
tree2c550ddaf9a59a58c3c07e40c02aded945384cd1
parent67a74148d8828f611fc5a7a23277b8eceb4c9430
coroutine: avoid co_queue_wakeup recursion

qemu_aio_coroutine_enter() is (indirectly) called recursively when
processing co_queue_wakeup.  This can lead to stack exhaustion.

This patch rewrites co_queue_wakeup in an iterative fashion (instead of
recursive) with bounded memory usage to prevent stack exhaustion.

qemu_co_queue_run_restart() is inlined into qemu_aio_coroutine_enter()
and the qemu_coroutine_enter() call is turned into a loop to avoid
recursion.

There is one change that is worth mentioning:  Previously, when
coroutine A queued coroutine B, qemu_co_queue_run_restart() entered
coroutine B from coroutine A.  If A was terminating then it would still
stay alive until B yielded.  After this patch B is entered by A's parent
so that a A can be deleted immediately if it is terminating.

It is safe to make this change since B could never interact with A if it
was terminating anyway.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 20180322152834.12656-3-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
block/io.c
include/qemu/coroutine_int.h
util/qemu-coroutine-lock.c
util/qemu-coroutine.c