[PATCH] cpu/hotplug: fix panic caused by empty doms_cur[]

cgel.zte@gmail.com posted 1 patch 4 years, 2 months ago
kernel/sched/topology.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
[PATCH] cpu/hotplug: fix panic caused by empty doms_cur[]
Posted by cgel.zte@gmail.com 4 years, 2 months ago
From: Ran Xiaokai <ran.xiaokai@zte.com.cn>

steps to reproduce this issue:
on a 8 cpu system:
1. starting kernel using "isolcpus=domain,4-7" cmdline
2. offline all the housekeeping cpu. [0-3]
   now ndoms_cur = 1 and doms_cur[0] will be with a empty cpumask.
3. offline anyone of the non-housekeeping cpu.

kernel panic whth:

Unable to handle kernel paging request at virtual address ffff80001128e9a1

Call trace:
 partition_sched_domains_locked+0x294/0x348
 rebuild_sched_domains_locked+0x3e4/0x750
 rebuild_sched_domains+0x2c/0x48
 cpuset_hotplug_workfn+0x45c/0x800
 process_one_work+0x1c4/0x498
 worker_thread+0x50/0x420
 kthread+0x114/0x150
Code: 9413028b f94037e1 f8605820 8b170017 (f944d2e0)
---[ end trace 81aa4bc5dcb7a4d5 ]---
Kernel panic - not syncing: Fatal exception

fix this whit a non-empty check with doms_cur[i]

Signed-off-by: Ran Xiaokai <ran.xiaokai@zte.com.cn>
---
 kernel/sched/topology.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 05b6c2a..4fa9bdf 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -2558,16 +2558,18 @@ void partition_sched_domains_locked(int ndoms_new, cpumask_var_t doms_new[],
 		for (j = 0; j < n && !new_topology; j++) {
 			if (cpumask_equal(doms_cur[i], doms_new[j]) &&
 			    dattrs_equal(dattr_cur, i, dattr_new, j)) {
-				struct root_domain *rd;
-
-				/*
-				 * This domain won't be destroyed and as such
-				 * its dl_bw->total_bw needs to be cleared.  It
-				 * will be recomputed in function
-				 * update_tasks_root_domain().
-				 */
-				rd = cpu_rq(cpumask_any(doms_cur[i]))->rd;
-				dl_clear_root_domain(rd);
+				if (!cpumask_empty(doms_cur[i])) {
+					struct root_domain *rd;
+
+					/*
+					 * This domain won't be destroyed and as such
+					 * its dl_bw->total_bw needs to be cleared.  It
+					 * will be recomputed in function
+					 * update_tasks_root_domain().
+					 */
+					rd = cpu_rq(cpumask_any(doms_cur[i]))->rd;
+					dl_clear_root_domain(rd);
+				}
 				goto match1;
 			}
 		}
-- 
2.15.2