117 lines
3.6 KiB
Diff
117 lines
3.6 KiB
Diff
|
|
From c2b377814e7874811d7eb98462d5153e966281cf Mon Sep 17 00:00:00 2001
|
||
|
|
From: Fei Xu <xufei30@huawei.com>
|
||
|
|
Date: Wed, 3 Apr 2024 18:05:25 +0800
|
||
|
|
Subject: [PATCH] coro: support live patch for libcare
|
||
|
|
|
||
|
|
Signed-off-by: Dawei Jiang <jiangdawei15@huawei.com>
|
||
|
|
---
|
||
|
|
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 7b304c79d9..650c21846d 100644
|
||
|
|
--- a/util/coroutine-ucontext.c
|
||
|
|
+++ b/util/coroutine-ucontext.c
|
||
|
|
@@ -80,6 +80,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.
|
||
|
|
@@ -340,3 +353,42 @@ bool qemu_in_coroutine(void)
|
||
|
|
|
||
|
|
return self && self->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 5fd2dbaf8b..f550214484 100644
|
||
|
|
--- a/util/qemu-coroutine.c
|
||
|
|
+++ b/util/qemu-coroutine.c
|
||
|
|
@@ -89,6 +89,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);
|
||
|
|
@@ -99,6 +101,8 @@ static void coroutine_delete(Coroutine *co)
|
||
|
|
{
|
||
|
|
co->caller = NULL;
|
||
|
|
|
||
|
|
+ qemu_coroutine_info_delete(co);
|
||
|
|
+
|
||
|
|
if (IS_ENABLED(CONFIG_COROUTINE_POOL)) {
|
||
|
|
if (release_pool_size < qatomic_read(&pool_max_size) * 2) {
|
||
|
|
QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next);
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|