diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2023-10-17 21:40:46 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2023-10-17 21:40:46 +0200 |
commit | a940daa52167e9db8ecce82213813b735a9d9f23 (patch) | |
tree | d5346c51351ccd1da7532cbec3127e6b73ec59c9 /kernel/cpu.c | |
parent | 32e4fa37fa667fdf53499b9de92737dc75199d8e (diff) | |
parent | 58720809f52779dc0f08e53e54b014209d13eebb (diff) |
Merge branch 'linus' into smp/core
Pull in upstream to get the fixes so depending changes can be applied.
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r-- | kernel/cpu.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index f6811c857102..6de7c6bb74ee 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1487,8 +1487,22 @@ out: return ret; } +struct cpu_down_work { + unsigned int cpu; + enum cpuhp_state target; +}; + +static long __cpu_down_maps_locked(void *arg) +{ + struct cpu_down_work *work = arg; + + return _cpu_down(work->cpu, 0, work->target); +} + static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) { + struct cpu_down_work work = { .cpu = cpu, .target = target, }; + /* * If the platform does not support hotplug, report it explicitly to * differentiate it from a transient offlining failure. @@ -1497,7 +1511,15 @@ static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) return -EOPNOTSUPP; if (cpu_hotplug_disabled) return -EBUSY; - return _cpu_down(cpu, 0, target); + + /* + * Ensure that the control task does not run on the to be offlined + * CPU to prevent a deadlock against cfs_b->period_timer. + */ + cpu = cpumask_any_but(cpu_online_mask, cpu); + if (cpu >= nr_cpu_ids) + return -EBUSY; + return work_on_cpu(cpu, __cpu_down_maps_locked, &work); } static int cpu_down(unsigned int cpu, enum cpuhp_state target) |