diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2018-03-22 15:28:33 +0000 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2018-03-27 13:05:28 +0100 |
commit | c40a2545700e9ad2ef67d5972484bbee4c83b2a6 (patch) | |
tree | 2c550ddaf9a59a58c3c07e40c02aded945384cd1 /include | |
parent | 67a74148d8828f611fc5a7a23277b8eceb4c9430 (diff) |
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>
Diffstat (limited to 'include')
-rw-r--r-- | include/qemu/coroutine_int.h | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index 59e8406398..bd6b0468e1 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -68,6 +68,5 @@ Coroutine *qemu_coroutine_new(void); void qemu_coroutine_delete(Coroutine *co); CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to, CoroutineAction action); -void coroutine_fn qemu_co_queue_run_restart(Coroutine *co); #endif |