hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAO4PE CVE: NA
----------------------------------------
Calling cpuinspect_unregister_inspector() while the inspector is running will lead a issue as follow:
[ 733.650856] Unable to handle kernel paging request at virtual address ffff80000922b0e4 [ 733.651118] Call trace: [ 733.651136] run_inspector+0xe4/0x220 [cpu_inspect] [ 733.651148] kthread+0x108/0x150 [ 733.651154] ret_from_fork+0x10/0x18
Return -EBUSY do not prevent the inspector form being removed. Fix this by providing a synchronized stop function to ensure inspect threads are really finished.
Fixes: 069486b6d964 ("cpuinspect: add CPU-inspect infrastructure") Signed-off-by: Yu Liao liaoyu15@huawei.com --- drivers/cpuinspect/cpuinspect.c | 14 ++++++++++++++ drivers/cpuinspect/cpuinspect.h | 1 + drivers/cpuinspect/inspector.c | 5 +---- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/cpuinspect/cpuinspect.c b/drivers/cpuinspect/cpuinspect.c index 65a935f6264d..65ce790fe28d 100644 --- a/drivers/cpuinspect/cpuinspect.c +++ b/drivers/cpuinspect/cpuinspect.c @@ -149,6 +149,20 @@ int stop_inspect_threads(void) return 0; }
+/** + * stop_inspect_threads_sync - Stop all the inspect threads and wait for + * current inspect tasks to finish. + * + * This function must be called with the cpuinspect lock held. + */ +void stop_inspect_threads_sync(void) +{ + stop_inspect_threads(); + + while (atomic_read(&active_threads_num)) + cpu_relax(); +} + /** * cpuinspect_init - core initializer */ diff --git a/drivers/cpuinspect/cpuinspect.h b/drivers/cpuinspect/cpuinspect.h index 9a336d396a16..508309d34b39 100644 --- a/drivers/cpuinspect/cpuinspect.h +++ b/drivers/cpuinspect/cpuinspect.h @@ -16,6 +16,7 @@ void cpuinspect_result_notify(void); /* inspect control */ int start_inspect_threads(void); int stop_inspect_threads(void); +void stop_inspect_threads_sync(void); int cpuinspect_is_running(void);
/* switch inspector */ diff --git a/drivers/cpuinspect/inspector.c b/drivers/cpuinspect/inspector.c index e56e35ec6325..10e905c4eb5c 100644 --- a/drivers/cpuinspect/inspector.c +++ b/drivers/cpuinspect/inspector.c @@ -106,10 +106,7 @@ int cpuinspect_unregister_inspector(struct cpu_inspector *insp)
mutex_lock(&cpuinspect_lock); if (curr_cpu_inspector == insp) { - if (ci_core.inspect_on) { - mutex_unlock(&cpuinspect_lock); - return -EBUSY; - } + stop_inspect_threads_sync();
curr_cpu_inspector = NULL; }