From 2135fe8e9c4d459d3f06babf3bfd71b5387b0214 Mon Sep 17 00:00:00 2001 From: jiang-dawei15 Date: Tue, 15 Mar 2022 10:28:34 +0800 Subject: [PATCH] fixed 0ec976f from https://gitee.com/yezengruan/qemu/pulls/266 coro: support live patch for libcare Description: For coroutine live patch, we need find all coroutines stack and check them before patching. There is no structure to manage all coroutines in qemu. So we add a list which contain all running coroutines to accelerate libcare live patch. --- include/qemu/coroutine_int.h | 3 ++- util/coroutine-ucontext.c | 52 ++++++++++++++++++++++++++++++++++++ util/qemu-coroutine.c | 4 +++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index 1da148552f..11b550a0fc 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -73,5 +73,6 @@ Coroutine *qemu_coroutine_new(void); void qemu_coroutine_delete(Coroutine *co); CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to, CoroutineAction action); - +void qemu_coroutine_info_add(const Coroutine *co_); +void qemu_coroutine_info_delete(const Coroutine *co_); #endif diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c index 904b375192..23ab7cdf74 100644 --- a/util/coroutine-ucontext.c +++ b/util/coroutine-ucontext.c @@ -79,6 +79,19 @@ union cc_arg { int i[2]; }; +/** + * coroutines list for libcare + */ +struct CoroutineInformation { + sigjmp_buf *env; + QLIST_ENTRY(CoroutineInformation) next; +}; + +static QemuMutex coro_mtx; +QLIST_HEAD(, CoroutineInformation) coro_info_list = QLIST_HEAD_INITIALIZER(pool); +int coro_env_offset = offsetof(struct CoroutineInformation, env); +int coro_next_offset = offsetof(struct CoroutineInformation, next); + /* * QEMU_ALWAYS_INLINE only does so if __OPTIMIZE__, so we cannot use it. * always_inline is required to avoid TSan runtime fatal errors. @@ -330,3 +343,42 @@ bool qemu_in_coroutine(void) { return current && current->caller; } + +static void __attribute__((constructor)) coro_mutex_init(void) +{ + qemu_mutex_init(&coro_mtx); +} + +void qemu_coroutine_info_add(const Coroutine *co_) +{ + CoroutineUContext *co; + struct CoroutineInformation *coro_info; + + /* save coroutine env to coro_info_list */ + co = DO_UPCAST(CoroutineUContext, base, co_); + coro_info = g_malloc0(sizeof(struct CoroutineInformation)); + coro_info->env = &co->env; + + qemu_mutex_lock(&coro_mtx); + QLIST_INSERT_HEAD(&coro_info_list, coro_info, next); + qemu_mutex_unlock(&coro_mtx); +} + +void qemu_coroutine_info_delete(const Coroutine *co_) +{ + CoroutineUContext *co; + struct CoroutineInformation *coro_info; + + /* Remove relative coroutine env info from coro_info_list */ + co = DO_UPCAST(CoroutineUContext, base, co_); + + qemu_mutex_lock(&coro_mtx); + QLIST_FOREACH(coro_info, &coro_info_list, next) { + if (coro_info->env == &co->env) { + QLIST_REMOVE(coro_info, next); + g_free(coro_info); + break; + } + } + qemu_mutex_unlock(&coro_mtx); +} diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c index b9586d6929..9c81336d8e 100644 --- a/util/qemu-coroutine.c +++ b/util/qemu-coroutine.c @@ -75,6 +75,8 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque) co = qemu_coroutine_new(); } + qemu_coroutine_info_add(co); + co->entry = entry; co->entry_arg = opaque; QSIMPLEQ_INIT(&co->co_queue_wakeup); @@ -85,6 +87,8 @@ static void coroutine_delete(Coroutine *co) { co->caller = NULL; + qemu_coroutine_info_delete(co); + if (CONFIG_COROUTINE_POOL) { if (release_pool_size < POOL_BATCH_SIZE * 2) { QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next); -- Gitee