clear-pkgs-linux-iot-lts2018/0520-VHM-bug-fix-on-operati...

89 lines
2.7 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2018-10-11 02:06:46 +08:00
From: "Zheng, Gen" <gen.zheng@intel.com>
Date: Fri, 31 Aug 2018 10:59:01 +0800
Subject: [PATCH] VHM: bug fix on operating multi-thread synchronization
2018-10-11 02:06:46 +08:00
With current code, the ioreq client based on VHM kthread may access
client->wq after the client got freed.
The acrn_ioreq_destroy_client_pervm should wait for the client thread
exit then free its client.
So do the following fixes:
Make the client threads for vcpu and hyper-dma mark kthread_exit
flag as true before exit.
Make the task that triggered to destroy the client thread, explicitly
waits for the kthread_exit flag turnning to true.
Signed-off-by: Zheng, Gen <gen.zheng@intel.com>
Reviewed-by: Chen, Jason CJ<jason.cj.chen@intel.com>
Reviewed-by: Zhao, Yakui <yakui.zhao@intel.com>
---
drivers/vhm/vhm_ioreq.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/vhm/vhm_ioreq.c b/drivers/vhm/vhm_ioreq.c
2020-10-27 02:14:06 +08:00
index 08826c575780..b570b826be95 100644
2018-10-11 02:06:46 +08:00
--- a/drivers/vhm/vhm_ioreq.c
+++ b/drivers/vhm/vhm_ioreq.c
@@ -91,8 +91,8 @@ struct ioreq_client {
*/
bool fallback;
- bool destroying;
- bool kthread_exit;
+ volatile bool destroying;
+ volatile bool kthread_exit;
/* client covered io ranges - N/A for fallback client */
struct list_head range_list;
@@ -260,15 +260,15 @@ static void acrn_ioreq_destroy_client_pervm(struct ioreq_client *client,
struct list_head *pos, *tmp;
unsigned long flags;
- /* blocking operation: notify client for cleanup
- * if waitqueue not active, it means client is handling request,
- * at that time, we need wait client finish its handling.
- */
- while (!waitqueue_active(&client->wq) && !client->kthread_exit)
- msleep(10);
client->destroying = true;
acrn_ioreq_notify_client(client);
+ /* the client thread will mark kthread_exit flag as true before exit,
+ * so wait for it exited.
+ */
+ while (!client->kthread_exit)
+ msleep(10);
+
spin_lock_irqsave(&client->range_lock, flags);
list_for_each_safe(pos, tmp, &client->range_list) {
struct ioreq_range *range =
@@ -495,6 +495,10 @@ static int ioreq_client_thread(void *data)
is_destroying(client)));
}
+ /* the client thread such as for hyper-dma will exit from here,
+ * so mark kthread_exit as true before exit */
+ client->kthread_exit = true;
+
return 0;
}
@@ -543,8 +547,12 @@ int acrn_ioreq_attach_client(int client_id, bool check_kthread_stop)
is_destroying(client)));
}
- if (is_destroying(client))
+ if (is_destroying(client)) {
+ /* the client thread for vcpu will exit from here,
+ * so mark kthread_exit as true before exit */
+ client->kthread_exit = true;
return 1;
+ }
}
return 0;
--
https://clearlinux.org
2018-10-11 02:06:46 +08:00