cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself
Subsystems (23)
Frederic Weisbecker
maintainerv2 cover cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself
Hi,
As discussed in LPC, cpu_down()'s stop_machine() is a problem for running real time and nohz_full workloads, for example if we want to provide a cpuset interface for nohz_full and isolated partitions are created at the same time as those critical workloads.
Here is a first step to start. stop_machine() gets a new "post" callback that is executed after the main one such that:
* As before the main fn executes while all the other CPUs spin.
* While other CPUs can exit stop_machine(), the target keeps IRQs disabled and execute the post_fn.
All the states between CPUHP_AP_ONLINE and CPUHP_AP_OFFLINE are moved to the post callback because they can eventually run concurrently with the other CPUs. I made a dedicated commit for each of them with individual justification analysis and tweaked a bit CPUHP_AP_TICK_DYING to adapt it.
Please double check CPUHP_AP_CPU_PM_STARTING with which I'm not too confident.
In the end only CPUHP_TEARDOWN_CPU (which is __cpu_disable()) remains in the global stop machine, this will be the next step. The plan will be to (all with IRQs disabled)
* Clear the CPU from cpu_online_mask
* Start an RCU grace period and poll on it (while doing momentary eqs in the loop), this *should work* with IRQs disabled. So all CPUs observe the CPU as offline.
* Check if the rest of x86 __cpu_disable() can be accomodated to run without making other CPUs spin.
Changes since v2:
* Remove the irq work kick because nohz full kick now has content in its irq_work callback.
* Fix a build issues
* Kick the new timekeeper with the more appropriate wake_up_nohz_cpu() function.
git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git
core/hotplug-v2
HEAD: 12f90ee6b38dbe86a3c8b9eccd8a0b509bfc005b
Thanks,
Frederic
---
Frederic Weisbecker (47):
stop_machine: Add post function to execute while other CPUs can exit
x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine
sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine()
rcu: Move CPUHP_AP_RCUTREE_DYING to post stop_machine()
cpuidle: Move CPUHP_AP_CPU_PM_STARTING post stop_machine()
cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range post stop_machine() irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING post stop_machine()
cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range post stop_machine() irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING post stop_machine() irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING post stop_machine() irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING post stop_machine() irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING post stop_machine()
cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range post stop_machine() perf/x86: Move CPUHP_AP_PERF_X86_STARTING post stop_machine()
perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING post stop_machine()
cpu: Move CPUHP_AP_PERF_XTENSA_STARTING post stop_machine()
ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING post stop_machine()
cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range post stop_machine() perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING post stop_machine()
perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING post stop_machine()
ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING post stop_machine()
clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING post stop_machine() clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING post stop_machine() clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING post stop_machine() clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING post stop_machine() clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING post stop_machine()
ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING post stop_machine()
clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING post stop_machine() clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING post stop_machine() clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING post stop_machine()
LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING post stop_machine() clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING post stop_machine() clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING post stop_machine() clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING post stop_machine() clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING post stop_machine()
clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING post stop_machine() clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING post stop_machine() clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING post stop_machine()
clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING post stop_machine() clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING post stop_machine()
ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING post stop_machine()
ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING post stop_machine()
smp: Move CPUHP_AP_SMPCFD_DYING post stop_machine()
hrtimer: Move CPUHP_AP_HRTIMERS_DYING post stop_machine()
tick: Move CPUHP_AP_TICK_DYING post stop_machine()
x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING post stop_machine()
ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING post stop_machine()
arch/arm/kernel/patch.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm64/kernel/patching.c | 4 ++-- arch/csky/kernel/probes/kprobes.c | 3 ++- arch/loongarch/kernel/inst.c | 3 ++- arch/parisc/kernel/patch.c | 4 ++-- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- arch/powerpc/platforms/powernv/subcore.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 2 +- arch/riscv/kernel/patch.c | 3 ++- arch/s390/kernel/kprobes.c | 4 ++-- arch/s390/kernel/time.c | 3 ++- arch/x86/kernel/cpu/microcode/core.c | 3 ++- arch/x86/kernel/cpu/mtrr/mtrr.c | 3 ++- arch/x86/virt/vmx/tdx/seamldr.c | 2 +- arch/xtensa/kernel/jump_label.c | 4 ++-- include/linux/stop_machine.h | 12 ++++++++---- kernel/cpu.c | 21 +++++++++++++++++++-- kernel/sched/core.c | 1 - kernel/stop_machine.c | 14 +++++++++++--- kernel/time/tick-common.c | 15 +++++++++------ 21 files changed, 74 insertions(+), 37 deletions(-)
Frederic Weisbecker
maintainerPATCH v2 1/47 stop_machine: Add post function to execute while other CPUs can exit
Between CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, introduce a new stop machine post function to be executed after the main one while other CPUs are released. Now stop machine machine state becomes:
1) Schedule stop_machine on the given mask (all CPUs in the hotplug down case).
2) Global synchronization rendez-vous on MULTI_STOP_PREPARE
3) All CPUs disable IRQs on MULTI_STOP_DISABLE_IRQ
4) The outgoing CPU executes the main function
5) Rendez-vous on MULTI_STOP_EXIT so that all CPUs synchronize with the main function.
6) Concurrently with 5), the post function is executed on the outgoing CPU with IRQs still disabled while other CPUs can exit stop_machine().
Add the new post function argument with the following Coccinelle script:
@@ expression arg1, arg2, arg3; @@ - stop_machine_cpuslocked(arg1, arg2, arg3) + stop_machine_cpuslocked(arg1, NULL, arg2, arg3)
--- arch/arm/kernel/patch.c | 2 +- arch/arm/probes/kprobes/core.c | 2 +- arch/arm64/kernel/patching.c | 4 ++-- arch/csky/kernel/probes/kprobes.c | 3 ++- arch/loongarch/kernel/inst.c | 3 ++- arch/parisc/kernel/patch.c | 4 ++-- arch/powerpc/mm/book3s64/hash_pgtable.c | 4 ++-- arch/powerpc/platforms/powernv/subcore.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 2 +- arch/riscv/kernel/patch.c | 3 ++- arch/s390/kernel/kprobes.c | 4 ++-- arch/s390/kernel/time.c | 3 ++- arch/x86/kernel/cpu/microcode/core.c | 3 ++- arch/x86/kernel/cpu/mtrr/mtrr.c | 3 ++- arch/x86/virt/vmx/tdx/seamldr.c | 2 +- arch/xtensa/kernel/jump_label.c | 4 ++-- include/linux/stop_machine.h | 12 ++++++++---- kernel/cpu.c | 3 ++- kernel/stop_machine.c | 14 +++++++++++--- 19 files changed, 48 insertions(+), 29 deletions(-)
arch/arm/kernel/patch.c +1 -1
@@ -124,5 +124,5 @@ void __kprobes patch_text(void *addr, unsigned int insn) .insn = insn, }; -stop_machine_cpuslocked (patch_text_stop_machine, &patch,NULL ); +stop_machine_cpuslocked (patch_text_stop_machine,NULL , &patch,NULL ); }
arch/arm/probes/kprobes/core.c +1 -1
@@ -171,7 +171,7 @@ void __kprobes kprobes_remove_breakpoint(void *addr, unsigned int insn) .addr = addr, .insn = insn, }; -stop_machine_cpuslocked (__kprobes_remove_breakpoint, &p, +stop_machine_cpuslocked (__kprobes_remove_breakpoint,NULL , &p, cpu_online_mask); }
arch/arm64/kernel/patching.c +2 -2
@@ -233,6 +233,6 @@ int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt)if (cnt <=0 )return -EINVAL ; -return stop_machine_cpuslocked (aarch64_insn_patch_text_cb, &patch, - cpu_online_mask); +return stop_machine_cpuslocked (aarch64_insn_patch_text_cb,NULL , + &patch, cpu_online_mask); }
arch/csky/kernel/probes/kprobes.c +2 -1
@@ -48,7 +48,8 @@ static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode) {struct csky_insn_patch param = { addr, opcode,ATOMIC_INIT (0 ) }; -return stop_machine_cpuslocked (patch_text_cb, ¶m, cpu_online_mask); +return stop_machine_cpuslocked (patch_text_cb,NULL , ¶m, + cpu_online_mask); }static void __kprobes arch_prepare_ss_slot (struct kprobe *p)
arch/loongarch/kernel/inst.c +2 -1
@@ -284,7 +284,8 @@ int larch_insn_text_copy(void *dst, void *src, size_t len)return err; } - ret =stop_machine_cpuslocked (text_copy_cb, ©, cpu_online_mask); + ret =stop_machine_cpuslocked (text_copy_cb,NULL , ©, + cpu_online_mask); err =set_memory_rox (start, (end - start) /PAGE_SIZE );if (err) {
arch/parisc/kernel/patch.c +2 -2
@@ -114,7 +114,7 @@ void __kprobes patch_text(void *addr, unsigned int insn) .len = sizeof(insn), }; -stop_machine_cpuslocked (patch_text_stop_machine, &patch,NULL ); +stop_machine_cpuslocked (patch_text_stop_machine,NULL , &patch,NULL ); }void __kprobes patch_text_multiple (void *addr,u32 *insn,unsigned int len)
@@ -126,5 +126,5 @@ void __kprobes patch_text_multiple(void *addr, u32 *insn, unsigned int len) .len = len }; -stop_machine_cpuslocked (patch_text_stop_machine, &patch,NULL ); +stop_machine_cpuslocked (patch_text_stop_machine,NULL , &patch,NULL ); }
arch/powerpc/mm/book3s64/hash_pgtable.c +2 -2
@@ -551,8 +551,8 @@ static bool hash__change_memory_range(unsigned long start, unsigned long end,// Ensure state is consistent before we call the other CPUs mb (); -stop_machine_cpuslocked (change_memory_range_fn, &chmem_parms, - cpu_online_mask); +stop_machine_cpuslocked (change_memory_range_fn,NULL , + &chmem_parms, cpu_online_mask);cpus_read_unlock ();mutex_unlock (&chmem_lock);
arch/powerpc/platforms/powernv/subcore.c +1 -1
@@ -366,7 +366,7 @@ static int set_subcores_per_core(int new_mode)/* Ensure state is consistent before we call the other cpus */ mb (); -stop_machine_cpuslocked (cpu_update_split_mode, &new_mode, +stop_machine_cpuslocked (cpu_update_split_mode,NULL , &new_mode, cpu_online_mask);cpus_read_unlock ();
arch/powerpc/platforms/pseries/lpar.c +1 -1
@@ -1678,7 +1678,7 @@ static int pseries_lpar_resize_hpt(unsigned long shift) t1 =ktime_get (); - rc =stop_machine_cpuslocked (pseries_lpar_resize_hpt_commit, + rc =stop_machine_cpuslocked (pseries_lpar_resize_hpt_commit,NULL , &state,NULL ); t2 =ktime_get ();
arch/riscv/kernel/patch.c +2 -1
@@ -297,7 +297,8 @@ int patch_text(void *addr, u32 *insns, size_t len)*/ lockdep_assert_held (&text_mutex); riscv_patch_in_stop_machine = true; - ret =stop_machine_cpuslocked (patch_text_cb, &patch, cpu_online_mask); + ret =stop_machine_cpuslocked (patch_text_cb,NULL , &patch, + cpu_online_mask); riscv_patch_in_stop_machine = false;return ret; }
arch/s390/kernel/kprobes.c +2 -2
@@ -161,7 +161,7 @@ void arch_arm_kprobe(struct kprobe *p)swap_instruction (&args);text_poke_sync (); }else { -stop_machine_cpuslocked (swap_instruction, &args,NULL ); +stop_machine_cpuslocked (swap_instruction,NULL , &args,NULL ); } }NOKPROBE_SYMBOL (arch_arm_kprobe);
@@ -174,7 +174,7 @@ void arch_disarm_kprobe(struct kprobe *p)swap_instruction (&args);text_poke_sync (); }else { -stop_machine_cpuslocked (swap_instruction, &args,NULL ); +stop_machine_cpuslocked (swap_instruction,NULL , &args,NULL ); } }NOKPROBE_SYMBOL (arch_disarm_kprobe);
arch/s390/kernel/time.c +2 -1
@@ -588,7 +588,8 @@ static void stp_work_fn(struct work_struct *work)memset (&stp_sync,0 ,sizeof (stp_sync));cpus_read_lock ();atomic_set (&stp_sync.cpus,num_online_cpus () -1 ); -stop_machine_cpuslocked (stp_sync_clock, &stp_sync, cpu_online_mask); +stop_machine_cpuslocked (stp_sync_clock,NULL , &stp_sync, + cpu_online_mask);cpus_read_unlock (); }
arch/x86/kernel/cpu/microcode/core.c +2 -1
@@ -620,7 +620,8 @@ static int load_late_stop_cpus(bool is_safe)if (microcode_ops->use_nmi)static_branch_enable_cpuslocked (µcode_nmi_handler_enable); -stop_machine_cpuslocked (load_cpus_stopped,NULL , cpu_online_mask); +stop_machine_cpuslocked (load_cpus_stopped,NULL ,NULL , + cpu_online_mask);if (microcode_ops->use_nmi)static_branch_disable_cpuslocked (µcode_nmi_handler_enable);
arch/x86/kernel/cpu/mtrr/mtrr.c +2 -1
@@ -175,7 +175,8 @@ static void set_mtrr(unsigned int reg, unsigned long base, unsigned long size, .smp_type = type }; -stop_machine_cpuslocked (mtrr_rendezvous_handler, &data, cpu_online_mask); +stop_machine_cpuslocked (mtrr_rendezvous_handler,NULL , &data, + cpu_online_mask);generic_rebuild_map (); }
arch/x86/virt/vmx/tdx/seamldr.c +1 -1
@@ -341,7 +341,7 @@ int seamldr_install_module(const u8 *data, u32 data_len)/* Ensure a stable set of online CPUs for the update process. */ cpus_read_lock ();init_state (&update_ctrl); - ret =stop_machine_cpuslocked (do_seamldr_install_module, params, + ret =stop_machine_cpuslocked (do_seamldr_install_module,NULL , params, cpu_online_mask);cpus_read_unlock ();
arch/xtensa/kernel/jump_label.c +2 -2
@@ -60,8 +60,8 @@ static void patch_text(unsigned long addr, const void *data, size_t sz) .sz = sz, .data = data, }; -stop_machine_cpuslocked (patch_text_stop_machine, - &patch, cpu_online_mask); +stop_machine_cpuslocked (patch_text_stop_machine,NULL , &patch, + cpu_online_mask); }else {unsigned long flags;
include/linux/stop_machine.h +8 -4
@@ -131,6 +131,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);/** * stop_machine_cpuslocked: freeze the machine on all CPUs and run this function * @fn: the function to run +* @postfn: the function to run after @fn while other CPUs can exit * @data: the data ptr to pass to @fn() * @cpus: the cpus to run @fn() on (NULL = one unspecified online CPU) *
@@ -138,7 +139,8 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);* * Context: Must be called from within a cpus_read_lock() protected region. */ -int stop_machine_cpuslocked (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus); +int stop_machine_cpuslocked (cpu_stop_fn_t fn,cpu_stop_fn_t postfn, +void *data,const struct cpumask *cpus);/** * stop_core_cpuslocked: - stop all threads on just one core
@@ -161,13 +163,15 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus);#else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */ -static __always_inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, -const struct cpumask *cpus) +static __always_inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, cpu_stop_fn_t postfn, +void *data,const struct cpumask *cpus) {unsigned long flags;int ret;local_irq_save (flags); ret =fn (data); +if (!ret && postfn) + ret =postfn (data);local_irq_restore (flags);return ret; }
@@ -175,7 +179,7 @@ static __always_inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, static __always_inline intstop_machine (cpu_stop_fn_t fn,void *data,const struct cpumask *cpus) { -return stop_machine_cpuslocked (fn, data, cpus); +return stop_machine_cpuslocked (fn,NULL , data, cpus); }static __always_inline int
kernel/cpu.c +2 -1
@@ -1313,7 +1313,8 @@ static int takedown_cpu(unsigned int cpu)*/ irq_lock_sparse (); - err =stop_machine_cpuslocked (take_cpu_down,NULL ,cpumask_of (cpu)); + err =stop_machine_cpuslocked (take_cpu_down,NULL ,NULL , +cpumask_of (cpu));if (err) {/* CPU refused to die */ irq_unlock_sparse ();
kernel/stop_machine.c +11 -3
@@ -168,6 +168,7 @@ enum multi_stop_state {struct multi_stop_data {cpu_stop_fn_t fn; +cpu_stop_fn_t postfn;void *data;/* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */ unsigned int num_threads;
@@ -238,6 +239,10 @@ static int multi_cpu_stop(void *data)if (is_active) err = msdata->fn (msdata->data);break ; +case MULTI_STOP_EXIT : +if (!err && is_active && msdata->postfn) + err = msdata->postfn (msdata->data); +break ;default :break ; }
@@ -582,11 +587,12 @@ static int __init cpu_stop_init(void) }early_initcall (cpu_stop_init); -int stop_machine_cpuslocked (cpu_stop_fn_t fn,void *data, -const struct cpumask *cpus) +int stop_machine_cpuslocked (cpu_stop_fn_t fn,cpu_stop_fn_t postfn, +void *data,const struct cpumask *cpus) {struct multi_stop_data msdata = { .fn = fn, + .postfn = postfn, .data = data, .num_threads =num_online_cpus (), .active_cpus = cpus,
@@ -608,6 +614,8 @@ int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data,local_irq_save (flags);hard_irq_disable (); ret = (*fn)(data); +if (!ret && postfn) + ret = (*postfn)(data);local_irq_restore (flags);return ret;
@@ -624,7 +632,7 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)/* No CPUs can come up or down during this. */ cpus_read_lock (); - ret =stop_machine_cpuslocked (fn, data, cpus); + ret =stop_machine_cpuslocked (fn,NULL , data, cpus);cpus_read_unlock ();return ret; }
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 2/47 x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The cpu_cacheinfo_mask is only accessed by hotplug operations and therefore the current CPU can be cleared from it while other CPUs have exited hotplug stop machine.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 21 +++++++++++++++++++-- kernel/sched/core.c | 1 - 2 files changed, 19 insertions(+), 3 deletions(-)
kernel/cpu.c +19 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CACHECTRL_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1294,9 +1294,26 @@ static int take_cpu_down(void *_param)*/ cpuhp_invoke_callback_range_nofail (false, cpu, st, target); +return 0 ; +} + +static int take_cpu_down_post (void *_param) +{ +struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE ); +int cpu =smp_processor_id (); + +WARN_ON (st->state !=CPUHP_AP_CACHECTRL_STARTING ); + +/* +* Invoke the former CPU_DYING callbacks. DYING must not fail! +*/ +cpuhp_invoke_callback_range_nofail (false, cpu, st, target); +/* Park the stopper thread */ stop_machine_park (cpu);return 0 ; + }static int takedown_cpu (unsigned int cpu)
@@ -1313,7 +1330,7 @@ static int takedown_cpu(unsigned int cpu)*/ irq_lock_sparse (); - err =stop_machine_cpuslocked (take_cpu_down,NULL ,NULL , + err =stop_machine_cpuslocked (take_cpu_down, take_cpu_down_post,NULL ,cpumask_of (cpu));if (err) {/* CPU refused to die */
kernel/sched/core.c +0 -1
@@ -6003,7 +6003,6 @@ static void sched_tick_stop(int cpu)WARN_ON_ONCE (!tick_work_cpu); twork =per_cpu_ptr (tick_work_cpu, cpu); -/* There cannot be competing actions, but don't rely on stop-machine. */ os =atomic_xchg (&twork->state,TICK_SCHED_REMOTE_OFFLINING );WARN_ON_ONCE (os !=TICK_SCHED_REMOTE_RUNNING );/* Don't cancel, as this would mess up the state machine. */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 3/47 sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
- The nohz_full remote tick can be shutdown safely while it runs concurrently.
- Updating the RQ clock shouldn't be a problem while offline with other CPUs around.
- Since it is seen offline, no task can be queued to it remotely.
- dl server stop is sychronized with rq lock. hrtimer_try_to_cancel() can become racy but then if it fires, it will just early return.
- calc_load_migrate() just folds local load to the global accumulation
- update_max_interval() only depends on the number of online CPUs, which is stable at this stage.
- hrtick_clear() deals with a strictly local timer
- sched_core_cpu_dying() doesn't race with anything
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/cpu.c +2 -3
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CACHECTRL_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_SCHED_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,8 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_CACHECTRL_STARTING ); - +WARN_ON (st->state !=CPUHP_AP_SCHED_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 4/47 rcu: Move CPUHP_AP_RCUTREE_DYING to post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
Here RCU just does tracing with already proper handling of racy accesses.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_SCHED_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_RCUTREE_DYING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_SCHED_STARTING ); +WARN_ON (st->state !=CPUHP_AP_RCUTREE_DYING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 5/47 cpuidle: Move CPUHP_AP_CPU_PM_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here only touches local data and also the local power device under its power lock. Therefore it should be safe to run against other CPUs.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_RCUTREE_DYING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CPU_PM_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_RCUTREE_DYING ); +WARN_ON (st->state !=CPUHP_AP_CPU_PM_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 6/47 cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
Here none of these states have teardown callbacks.
Move these teardown callbacks to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CPU_PM_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_ARMADA_XP_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_CPU_PM_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_ARMADA_XP_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 7/47 irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here just masks the per-cpu IRQ in the chip and shouldn't race with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_ARMADA_XP_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_BCM2836_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_ARMADA_XP_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_BCM2836_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 8/47 cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
None of these states have teardown callback.
Move them to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_BCM2836_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_EIOINTC_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_BCM2836_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_EIOINTC_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 9/47 irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
avecintc_cpu_offline() can run concurrently with other CPUs because loongarch_avec.vector_matrix protects the internal structures.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_EIOINTC_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_AVECINTC_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_EIOINTC_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_AVECINTC_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 10/47 irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The callback here simply disables a per-cpu IRQ, which internally locks the irq desc. Therefore it can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_AVECINTC_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_AVECINTC_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 11/47 irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The callback here simply disables the IPI in the per-CPU region, which nobody should touch concurrently because all other CPUs see the current one as offline at this stage. It also disables the per-CPU IRQ, which is internally protected by the IRQ desc lock. Therefore it can safely run concurrently with other CPUs.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_ACLINT_SSWI_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_ACLINT_SSWI_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 12/47 irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The callback here disables the current CPU IPI, which nobody should touch concurrently since it is seen offline by other CPUs.
The sync protects internal datas with &lpriv->lock and the IRQ matrix offline is protected by &imsic->matrix_lock. Therfore it can run concurrently with other CPUs.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_ACLINT_SSWI_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_RISCV_IMSIC_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_ACLINT_SSWI_STARTING ); +WARN_ON (st->state !=CPUHP_AP_IRQ_RISCV_IMSIC_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 13/47 cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
None of the states here have teardown callback.
Move them to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_IRQ_RISCV_IMSIC_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_IRQ_RISCV_IMSIC_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 14/47 perf/x86: Move CPUHP_AP_PERF_X86_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
Here only intel has a dying callback (intel_pmu_cpu_dying()) which does:
* Deallocate the per CPU DS structure on the MSR_IA32_DS_AREA. This is already racy against offlining CPUs because all possible CPUs's MSR are written on a hardware event initialization, which still can happen before the CPU actually goes off.
* Deallocate PEBS buffer. This is already well synchronized against hotplug up callback.
Therefore the related teardwown callback can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_X86_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 14/47] perf/x86: Move CPUHP_AP_PERF_X86_STARTING post stop_machine()
Sashiko has reviewed this patch and found no issues.
Quoted 20 lines
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().Here only intel has a dying callback (
intel_pmu_cpu_dying()) which does:* Deallocate the per CPU DS structure on the
MSR_IA32_DS_AREA. This is already racy against offlining CPUs because all possible CPUs's MSR are written on a hardware event initialization, which still can happen before the CPU actually goes off.* Deallocate PEBS buffer. This is already well synchronized against hotplug up callback.
Quoted 6 lines
Therefore the related teardwown callback can run concurrently with other CPUs.
Move it to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=14
Frederic Weisbecker
maintainerPATCH v2 15/47 perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
Here the callback only restores the IBS interrupt to the normal priority on the local APIC and running it concurrently against other CPUs shouldn't expose any kind of race.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_AMD_IBS_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_X86_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_X86_AMD_IBS_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 15/47] perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING post stop_machine()
Sashiko has reviewed this patch and found no issues.
Quoted 10 lines
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().
Quoted 7 lines
Here the callback only restores the IBS interrupt to the normal priority on the local APIC and running it concurrently against other CPUs shouldn't expose any kind of race.
Move this teardown callback to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=15
Frederic Weisbecker
maintainerPATCH v2 16/47 cpu: Move CPUHP_AP_PERF_XTENSA_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
This state doesn't have a teardown callback.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_X86_AMD_IBS_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_XTENSA_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_X86_AMD_IBS_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_XTENSA_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 16/47] cpu: Move CPUHP_AP_PERF_XTENSA_STARTING post stop_machine()
Sashiko has reviewed this patch and found no issues.
Quoted 10 lines
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().
Quoted 5 lines
This state doesn't have a teardown callback.
Move it to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=16
Frederic Weisbecker
maintainerPATCH v2 17/47 ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here only removes the local VFP state which is never accessed remotely. As such it can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_XTENSA_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_VFP_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_XTENSA_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_VFP_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 18/47 cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
None of the states here have a teardown callback.
Move them to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_VFP_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_ARM_ACPI_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_VFP_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_ARM_ACPI_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 19/47 perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here just disables the IRQs for each PMUs, which shouldn't expose any specific race while other CPUs are running.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_ARM_ACPI_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_ARM_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_ARM_ACPI_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_ARM_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 19/47] perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING post stop_machine()
Sashiko has reviewed this patch and found no issues.
Quoted 10 lines
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().
Quoted 6 lines
The teardown callback here just disables the IRQs for each PMUs, which shouldn't expose any specific race while other CPUs are running.
Move it to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=19
Frederic Weisbecker
maintainerPATCH v2 20/47 perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here:
* Disables the per-cpu IRQ
* Disables user-mode access to the CPU counter
* Disables the shared memory snapshot of the CPU PMU.
All these operations are local to the CPU and should be able to execute concurrently with other CPUs.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_ARM_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_RISCV_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_ARM_STARTING ); +WARN_ON (st->state !=CPUHP_AP_PERF_RISCV_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
[email protected]
AI reviewRe: [PATCH 20/47] perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING post stop_machine()
Sashiko has reviewed this patch and found no issues.
Quoted 16 lines
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().The teardown callback here:
* Disables the per-cpu IRQ
* Disables user-mode access to the CPU counter
* Disables the shared memory snapshot of the CPU PMU.
Quoted 6 lines
All these operations are local to the CPU and should be able to execute concurrently with other CPUs.
Move this teardown callback to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>
Sashiko has reviewed this patch and found no issues.
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=20
Frederic Weisbecker
maintainerPATCH v2 21/47 ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here disables the L1/L2 cache prefetch and the write full line of zeros mode. These operations should only impact the outgoing CPU and can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_PERF_RISCV_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_L2X0_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_PERF_RISCV_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_L2X0_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 22/47 clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply disables the IRQ and clears/ack the interrupt bit on the local device. All these operations can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_L2X0_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_L2X0_STARTING ); +WARN_ON (st->state !=CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 23/47 clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQs disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_ARCH_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_ARCH_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 24/47 clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here only clears the CPU from the evtstrm_available cpumask, which is only ever checked locally for the current CPU. And set/clear from other CPUs are atomic.
Therefore this callback is safe to run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_ARCH_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_ARCH_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 25/47 clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_GLOBAL_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_GLOBAL_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 26/47 clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_GLOBAL_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_JCORE_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_GLOBAL_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_JCORE_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 27/47 ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_JCORE_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_TWD_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_JCORE_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_TWD_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 28/47 clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_TWD_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_QCOM_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_TWD_STARTING ); +WARN_ON (st->state !=CPUHP_AP_QCOM_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 29/47 clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_QCOM_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TEGRA_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_QCOM_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_TEGRA_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 30/47 clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TEGRA_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARMADA_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_TEGRA_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARMADA_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 31/47 LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply clears the interrupt on the CSR, operation that can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARMADA_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARMADA_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 32/47 clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_MIPS_GIC_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_MIPS_GIC_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 33/47 clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_MIPS_GIC_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARC_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_MIPS_GIC_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARC_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 34/47 clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The state here has no teardown callback.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARC_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_REALTEK_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARC_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_REALTEK_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 35/47 clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs timer and IRQ disablement, both of which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_REALTEK_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_RISCV_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_REALTEK_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_RISCV_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 36/47 clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_RISCV_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CLINT_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_RISCV_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_CLINT_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 37/47 clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CLINT_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CSKY_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_CLINT_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_CSKY_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 38/47 clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
This state doesn't have a teardown callback.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_CSKY_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TI_GP_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_CSKY_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_TI_GP_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 39/47 clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs timer and IRQ disablement, both of which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TI_GP_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_HYPERV_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_TI_GP_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_HYPERV_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Re: [PATCH 39/47] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING post stop_machine()
kernel/cpu.c
Quoted 22 lines · Frederic Weisbecker
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().The teardown callback here simply performs timer and IRQ disablement, both of which can run concurrently with other CPUs.
Move it to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)kernel/cpu.c +0
-0
I am unable to correlate the commit message with the change and could not find the rest of the series on lore to get more context.
Regards,
Naman
Quoted 20 lines
kernel/cpu.c +2
-2@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TI_GP_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_HYPERV_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */ @@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_TI_GP_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_HYPERV_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Frederic Weisbecker
maintainerRe: [PATCH 39/47] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING post stop_machine()
Quoted 23 lines · Naman Jain
Quoted 20 lines · Frederic Weisbecker
Between
CPUHP_TEARDOWN_CPUandCPUHP_AP_OFFLINE,stop_machineexecutes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.In order to transition smoothly from global
stop_machineto finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exitstop_machine().The teardown callback here simply performs timer and IRQ disablement, both of which can run concurrently with other CPUs.
Move it to post
stop_machine()accordingly.Signed-off-by Frederic Weisbecker <[email protected]>--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Quoted 5 lines
kernel/cpu.c
Quoted 2 lines
kernel/cpu.c +0
-0I am unable to correlate the commit message with the change and could not find the rest of the series on lore to get more context.
Sorry about that. I couldn't CC everyone to the motherpatch so I tried to bring as much context as I could to each individual follow-up's changelog. Probably that wasn't enough.
So here is the cover letter that explains the whole intent:
https://lore.kernel.org/lkml/[email protected]/
And the patch that does the initial infrastructure change to stop machine:
https://lore.kernel.org/lkml/[email protected]/
Thanks.
Signature · 2 lines
Frederic Weisbecker SUSE Labs
Frederic Weisbecker
maintainerPATCH v2 40/47 clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The state here doesn't have a teardown callback.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_HYPERV_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_DUMMY_TIMER_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_HYPERV_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_DUMMY_TIMER_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 41/47 ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here simply performs IRQ disablement, which can run concurrently with other CPUs.
Move it to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_DUMMY_TIMER_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_XEN_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_DUMMY_TIMER_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM_XEN_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 42/47 ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
None of the states here have a teardown callback.
Move them to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM_XEN_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM64_ISNDEP_STARTING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM_XEN_STARTING ); +WARN_ON (st->state !=CPUHP_AP_ARM64_ISNDEP_STARTING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 43/47 smp: Move CPUHP_AP_SMPCFD_DYING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The outgoing CPU is observed as offline by other CPUs so no new IPI are supposed to be queued at this stage and the remaining callbacks can be executed while other CPUs are running, just like any online IPI handling.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ARM64_ISNDEP_STARTING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_SMPCFD_DYING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_ARM64_ISNDEP_STARTING ); +WARN_ON (st->state !=CPUHP_AP_SMPCFD_DYING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 44/47 hrtimer: Move CPUHP_AP_HRTIMERS_DYING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The migration of timers can happen while other CPUs are running because everything is serialized with the base locks. Also those locks only nest on the outgoing CPU during hotplug so no locking inversion should happen.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_SMPCFD_DYING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_HRTIMERS_DYING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_SMPCFD_DYING ); +WARN_ON (st->state !=CPUHP_AP_HRTIMERS_DYING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 45/47 tick: Move CPUHP_AP_TICK_DYING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The teardown callback here can run concurrently with other CPUs:
* The cancelled local tick doesn't interact with other CPUs.
* The local clockevents are removed under the clockevents_lock
* The CPU is removed from broadcasting under the tick_broadcast_lock
The only needed change is to send an IPI to the new timekeeper because outside stop machine, other CPUs may be in dynticks mode.
Then the teardown callback can be moved to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- kernel/time/tick-common.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_HRTIMERS_DYING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TICK_DYING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_HRTIMERS_DYING ); +WARN_ON (st->state !=CPUHP_AP_TICK_DYING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
kernel/time/tick-common.c +9 -6
@@ -16,6 +16,8 @@#include <linux/percpu.h> #include <linux/profile.h> #include <linux/sched.h> +#include <linux/sched/isolation.h> +#include <linux/sched/nohz.h> #include <linux/module.h> #include <trace/events/power.h>
@@ -394,13 +396,14 @@ void tick_assert_timekeeping_handover(void)int tick_cpu_dying (unsigned int dying_cpu) {/* -* If the current CPU is the timekeeper, it's the only one that can -* safely hand over its duty. Also all online CPUs are in stop -* machine, guaranteed not to be idle, therefore there is no -* concurrency and it's safe to pick any online successor. +* If the current CPU is the timekeeper, hand over to any online +* CPU and kick it out of nohz if needed */ -if (tick_do_timer_cpu == dying_cpu) - tick_do_timer_cpu =cpumask_first (cpu_online_mask); +if (tick_do_timer_cpu == dying_cpu) { +int timekeeper =cpumask_any_and (housekeeping_cpumask (HK_TYPE_KERNEL_NOISE ), cpu_online_mask); +WRITE_ONCE (tick_do_timer_cpu, timekeeper); +wake_up_nohz_cpu (timekeeper); + }/* Make sure the CPU won't try to retake the timekeeping duty */ tick_sched_timer_dying (dying_cpu);
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 46/47 x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
tboot waits for all previously outgoing CPUs to be in Wait-For-SIPI mode when the last secondary CPU goes down.
Although the expectation looks strange because the number in ap_wfs_count should only match tboot->num_in_wfs + 1 at this hotplug stage, anyway the CPU can run this wait loop while the other online CPU is running concurrently.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_TICK_DYING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_X86_TBOOT_DYING );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_TICK_DYING ); +WARN_ON (st->state !=CPUHP_AP_X86_TBOOT_DYING );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0
Frederic Weisbecker
maintainerPATCH v2 47/47 ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING post stop_machine()
In reply to Frederic WeisbeckerBetween CPUHP_TEARDOWN_CPU and CPUHP_AP_OFFLINE, stop_machine executes all the teardown callbacks while stopping all CPUs in the system. This doesn't mix-up well with running RT or isolated tasks.
In order to transition smoothly from global stop_machine to finer grained synchronization between teardown callbacks and the other CPUs, a new stop machine post function has been introduced to be executed after the main one with IRQs still disabled while other CPUs can exit stop_machine().
The cache readahead can be globally disabled while the other CPUs are running.
Move this teardown callback to post stop_machine() accordingly.
--- kernel/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/cpu.c +2 -2
@@ -1275,7 +1275,7 @@ void clear_tasks_mm_cpumask(int cpu)static int take_cpu_down (void *_param) {struct cpuhp_cpu_state *st =this_cpu_ptr (&cpuhp_state); -enum cpuhp_state target =max ((int )st->target,CPUHP_AP_X86_TBOOT_DYING ); +enum cpuhp_state target =max ((int )st->target,CPUHP_AP_ONLINE );int err, cpu =smp_processor_id ();/* Ensure this CPU doesn't handle any more interrupts. */
@@ -1303,7 +1303,7 @@ static int take_cpu_down_post(void *_param)enum cpuhp_state target =max ((int )st->target,CPUHP_AP_OFFLINE );int cpu =smp_processor_id (); -WARN_ON (st->state !=CPUHP_AP_X86_TBOOT_DYING ); +WARN_ON (st->state !=CPUHP_AP_ONLINE );/* * Invoke the former CPU_DYING callbacks. DYING must not fail! */
Signature · 1 line
2.53.0