2019-03-29 14:12:17 +08:00
|
|
|
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
|
2019-03-29 14:12:17 +08:00
|
|
|
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
|
2019-03-29 14:12:17 +08:00
|
|
|
index 08826c5..b570b82 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;
|
|
|
|
--
|
2019-03-29 14:12:17 +08:00
|
|
|
2.21.0
|
2018-10-11 02:06:46 +08:00
|
|
|
|