mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself
@ 2026-10-19 13:08 Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 01/49] stop_machine: Add post function to execute while other CPUs can exit Frederic Weisbecker
                   ` (48 more replies)
  0 siblings, 49 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Phil Auld, Peter Zijlstra, Waiman Long,
	Marco Crivellari, Thomas Gleixner, Paul E. McKenney

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.

There are two states for which I'm not too confident, please double
check CPUHP_AP_CPU_PM_STARTING and CPUHP_AP_ARM_CACHE_B15_RAC_DYING.

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.

git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git
	core/hotplug

HEAD: 8ff5f866a7c2825213c6aa525a88840cbccf1211

Thanks,
	Frederic
---

Frederic Weisbecker (49):
      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()
      irq_work: Introduce irq_work_kick_cpu()
      tick-sched: Convert ad-hoc implementation of irq_work_kick_cpu()
      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/irq_work.h                 |  1 +
 include/linux/stop_machine.h             | 10 +++++++---
 kernel/cpu.c                             | 21 +++++++++++++++++++--
 kernel/irq_work.c                        | 16 ++++++++++++++++
 kernel/sched/core.c                      |  1 -
 kernel/stop_machine.c                    | 14 +++++++++++---
 kernel/time/tick-common.c                | 14 ++++++++------
 kernel/time/tick-sched.c                 | 12 ++----------
 24 files changed, 91 insertions(+), 46 deletions(-)

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 01/49] stop_machine: Add post function to execute while other CPUs can exit
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 02/49] x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine Frederic Weisbecker
                   ` (47 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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)

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 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             | 10 +++++++---
 kernel/cpu.c                             |  3 ++-
 kernel/stop_machine.c                    | 14 +++++++++++---
 19 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 4d45e60cd46d..c49db43c69a4 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -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);
 }
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
index 9fd877c87a38..3f6520c12d29 100644
--- a/arch/arm/probes/kprobes/core.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -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);
 }
 
diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index 09f019c6547a..43a8d545f050 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -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);
 }
diff --git a/arch/csky/kernel/probes/kprobes.c b/arch/csky/kernel/probes/kprobes.c
index 3c6e5c725d81..3bbd44d21ca3 100644
--- a/arch/csky/kernel/probes/kprobes.c
+++ b/arch/csky/kernel/probes/kprobes.c
@@ -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, &param, cpu_online_mask);
+	return stop_machine_cpuslocked(patch_text_cb, NULL, &param,
+				       cpu_online_mask);
 }
 
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
index 0b9228b7c13a..f0f04406909c 100644
--- a/arch/loongarch/kernel/inst.c
+++ b/arch/loongarch/kernel/inst.c
@@ -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, &copy, cpu_online_mask);
+	ret = stop_machine_cpuslocked(text_copy_cb, NULL, &copy,
+				      cpu_online_mask);
 
 	err = set_memory_rox(start, (end - start) / PAGE_SIZE);
 	if (err) {
diff --git a/arch/parisc/kernel/patch.c b/arch/parisc/kernel/patch.c
index 35dd764b871e..097d7fde833c 100644
--- a/arch/parisc/kernel/patch.c
+++ b/arch/parisc/kernel/patch.c
@@ -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);
 }
diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c
index d9b5b751d7b7..d7fddc93a1aa 100644
--- a/arch/powerpc/mm/book3s64/hash_pgtable.c
+++ b/arch/powerpc/mm/book3s64/hash_pgtable.c
@@ -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);
diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c
index f7668ef1ac1f..ac9c7685141b 100644
--- a/arch/powerpc/platforms/powernv/subcore.c
+++ b/arch/powerpc/platforms/powernv/subcore.c
@@ -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();
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 6a415febc53b..c847b81bdeb3 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -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();
diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
index 2239c28981bc..dc7c544e9f62 100644
--- a/arch/riscv/kernel/patch.c
+++ b/arch/riscv/kernel/patch.c
@@ -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;
 }
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index c450120b4474..3dcedcad9fd6 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -158,7 +158,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);
@@ -171,7 +171,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);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2b989bebd220..352bb9dc3e13 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -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();
 	}
 
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 0dd0c7241c57..8a54c419fc28 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -620,7 +620,8 @@ static int load_late_stop_cpus(bool is_safe)
 	if (microcode_ops->use_nmi)
 		static_branch_enable_cpuslocked(&microcode_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(&microcode_nmi_handler_enable);
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c
index 468c53b20acf..497e95fb275c 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.c
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.c
@@ -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();
 }
diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
index b1137ca6150d..3fd03d552f18 100644
--- a/arch/x86/virt/vmx/tdx/seamldr.c
+++ b/arch/x86/virt/vmx/tdx/seamldr.c
@@ -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();
 
diff --git a/arch/xtensa/kernel/jump_label.c b/arch/xtensa/kernel/jump_label.c
index ad1841cecdfb..2278db2af2a4 100644
--- a/arch/xtensa/kernel/jump_label.c
+++ b/arch/xtensa/kernel/jump_label.c
@@ -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;
 
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h
index 84e7fb627ba4..f8c1f2e2371b 100644
--- a/include/linux/stop_machine.h
+++ b/include/linux/stop_machine.h
@@ -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;
 }
diff --git a/kernel/cpu.c b/kernel/cpu.c
index b3c8553d7bd6..064c1072ad50 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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();
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index d085ba1f4b44..d9db763a969a 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -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 (postfn)
+			(*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;
 }
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 02/49] x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 01/49] stop_machine: Add post function to execute while other CPUs can exit Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 03/49] sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine() Frederic Weisbecker
                   ` (46 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, H. Peter Anvin, Borislav Petkov,
	Dave Hansen, Ingo Molnar, Marco Crivellari, Nikolay Borisov,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long, x86

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c        | 21 +++++++++++++++++++--
 kernel/sched/core.c |  1 -
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 064c1072ad50..da07c804ff53 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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 */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 1fe40de6ebe3..c1ed3ba39092 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5953,7 +5953,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. */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 03/49] sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 01/49] stop_machine: Add post function to execute while other CPUs can exit Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 02/49] x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 04/49] rcu: Move CPUHP_AP_RCUTREE_DYING " Frederic Weisbecker
                   ` (45 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Ben Segall, Dietmar Eggemann, Ingo Molnar,
	Juri Lelli, K Prateek Nayak, Marco Crivellari, Mel Gorman,
	Peter Zijlstra, Phil Auld, Steven Rostedt, Thomas Gleixner,
	Valentin Schneider, Vincent Guittot, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index da07c804ff53..4f3f0ae36893 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 04/49] rcu: Move CPUHP_AP_RCUTREE_DYING to post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (2 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 03/49] sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine() Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 05/49] cpuidle: Move CPUHP_AP_CPU_PM_STARTING " Frederic Weisbecker
                   ` (44 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long, Paul E. McKenney, Neeraj Upadhyay,
	Joel Fernandes, Boqun Feng, Uladzislau Rezki

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 4f3f0ae36893..f22afb213d6f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 05/49] cpuidle: Move CPUHP_AP_CPU_PM_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (3 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 04/49] rcu: Move CPUHP_AP_RCUTREE_DYING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 06/49] cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range " Frederic Weisbecker
                   ` (43 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Rafael J. Wysocki, Christian Loehle,
	Daniel Lezcano, Lorenzo Pieralisi, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Sudeep Holla, Thomas Gleixner,
	Ulf Hansson, Waiman Long, linux-arm-kernel, linux-pm

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index f22afb213d6f..68eb8de820d5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 06/49] cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (4 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 05/49] cpuidle: Move CPUHP_AP_CPU_PM_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 07/49] irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING " Frederic Weisbecker
                   ` (42 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 68eb8de820d5..293dbb73d940 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 07/49] irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (5 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 06/49] cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 08/49] cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range " Frederic Weisbecker
                   ` (41 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Broadcom internal kernel review list,
	Florian Fainelli, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Radu Rendec, Ray Jui, Scott Branden, Thomas Gleixner,
	Waiman Long, linux-arm-kernel, linux-rpi-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 293dbb73d940..db73cdfbf1d0 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 08/49] cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (6 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 07/49] irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 09/49] irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING " Frederic Weisbecker
                   ` (40 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index db73cdfbf1d0..126896b2c970 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 09/49] irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (7 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 08/49] cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 10/49] irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING " Frederic Weisbecker
                   ` (39 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Huacai Chen, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Radu Rendec, Thomas Gleixner,
	WANG Xuerui, Waiman Long, loongarch

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 126896b2c970..f32404821731 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 10/49] irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (8 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 09/49] irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 11/49] irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING " Frederic Weisbecker
                   ` (38 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Paul Walmsley,
	Peter Zijlstra, Phil Auld, Radu Rendec, Samuel Holland,
	Thomas Gleixner, Waiman Long, linux-riscv

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index f32404821731..661648ada894 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 11/49] irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (9 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 10/49] irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 12/49] irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING " Frederic Weisbecker
                   ` (37 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Radu Rendec, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 661648ada894..6acf07afbaf5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 12/49] irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (10 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 11/49] irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 13/49] cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range " Frederic Weisbecker
                   ` (36 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Albert Ou, Alexandre Ghiti, Anup Patel,
	Marco Crivellari, Palmer Dabbelt, Paul Walmsley, Peter Zijlstra,
	Phil Auld, Radu Rendec, Thomas Gleixner, Waiman Long,
	linux-riscv

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6acf07afbaf5..ce4e2ece371f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 13/49] cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (11 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 12/49] irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 14/49] perf/x86: Move CPUHP_AP_PERF_X86_STARTING " Frederic Weisbecker
                   ` (35 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index ce4e2ece371f..5ac2a925f7d6 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 14/49] perf/x86: Move CPUHP_AP_PERF_X86_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (12 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 13/49] cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 15/49] perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING " Frederic Weisbecker
                   ` (34 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, H. Peter Anvin, Adrian Hunter,
	Alexander Shishkin, Arnaldo Carvalho de Melo, Borislav Petkov,
	Dave Hansen, Ian Rogers, Ingo Molnar, James Clark, Jiri Olsa,
	Marco Crivellari, Mark Rutland, Namhyung Kim, Peter Zijlstra,
	Phil Auld, Thomas Gleixner, Waiman Long, linux-perf-users, x86

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 5ac2a925f7d6..c37fa1272d57 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 15/49] perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (13 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 14/49] perf/x86: Move CPUHP_AP_PERF_X86_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 16/49] cpu: Move CPUHP_AP_PERF_XTENSA_STARTING " Frederic Weisbecker
                   ` (33 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, H. Peter Anvin, Adrian Hunter,
	Alexander Shishkin, Arnaldo Carvalho de Melo, Borislav Petkov,
	Dave Hansen, Ian Rogers, Ingo Molnar, James Clark, Jiri Olsa,
	Marco Crivellari, Mark Rutland, Namhyung Kim, Peter Zijlstra,
	Phil Auld, Thomas Gleixner, Waiman Long, linux-perf-users, x86

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c37fa1272d57..5a46372a8501 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 16/49] cpu: Move CPUHP_AP_PERF_XTENSA_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (14 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 15/49] perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 17/49] ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING " Frederic Weisbecker
                   ` (32 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Adrian Hunter, Alexander Shishkin,
	Arnaldo Carvalho de Melo, Chris Zankel, Ian Rogers, Ingo Molnar,
	James Clark, Jiri Olsa, Marco Crivellari, Mark Rutland,
	Max Filippov, Namhyung Kim, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long, linux-perf-users

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 5a46372a8501..c20a822df803 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 17/49] ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (15 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 16/49] cpu: Move CPUHP_AP_PERF_XTENSA_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 18/49] cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range " Frederic Weisbecker
                   ` (31 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Russell King, Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c20a822df803..b7f5d0683ff7 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 18/49] cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (16 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 17/49] ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 19/49] perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING " Frederic Weisbecker
                   ` (30 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index b7f5d0683ff7..7d7e2d1eda9b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 19/49] perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (17 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 18/49] cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 20/49] perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING " Frederic Weisbecker
                   ` (29 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Mark Rutland,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long,
	Will Deacon, linux-arm-kernel, linux-perf-users

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 7d7e2d1eda9b..95cc6655cf7b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 20/49] perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (18 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 19/49] perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 21/49] ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING " Frederic Weisbecker
                   ` (28 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Albert Ou, Alexandre Ghiti, Anup Patel,
	Atish Patra, Marco Crivellari, Mark Rutland, Palmer Dabbelt,
	Paul Walmsley, Peter Zijlstra, Phil Auld, Thomas Gleixner,
	Waiman Long, Will Deacon, linux-arm-kernel, linux-perf-users,
	linux-riscv

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 95cc6655cf7b..c69a265e4383 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 21/49] ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (19 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 20/49] perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 22/49] clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING " Frederic Weisbecker
                   ` (27 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Russell King, Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c69a265e4383..c08ef67e3499 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 22/49] clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (20 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 21/49] ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 23/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING " Frederic Weisbecker
                   ` (26 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Alim Akhtar, Daniel Lezcano,
	Krzysztof Kozlowski, Marco Crivellari, Peter Griffin,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long,
	linux-arm-kernel, linux-samsung-soc

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c08ef67e3499..27e6542fb6c4 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 23/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (21 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 22/49] clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 24/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING " Frederic Weisbecker
                   ` (25 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marc Zyngier,
	Marco Crivellari, Mark Rutland, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 27e6542fb6c4..90d37ee0f282 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 24/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (22 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 23/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 25/49] clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING " Frederic Weisbecker
                   ` (24 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marc Zyngier,
	Marco Crivellari, Mark Rutland, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 90d37ee0f282..ca335111abb2 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 25/49] clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (23 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 24/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 26/49] clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING " Frederic Weisbecker
                   ` (23 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Patrice Chotard, Peter Zijlstra, Phil Auld, Thomas Gleixner,
	Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index ca335111abb2..7bc94829b68c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 26/49] clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (24 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 25/49] clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 27/49] ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING " Frederic Weisbecker
                   ` (22 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 7bc94829b68c..1b3942012f2d 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 27/49] ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (25 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 26/49] clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 28/49] clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING " Frederic Weisbecker
                   ` (21 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Russell King, Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 1b3942012f2d..1a98d05c7f55 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 28/49] clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (26 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 27/49] ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 29/49] clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING " Frederic Weisbecker
                   ` (20 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long,
	linux-arm-msm

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 1a98d05c7f55..ba90e385d31f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 29/49] clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (27 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 28/49] clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 30/49] clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING " Frederic Weisbecker
                   ` (19 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Jonathan Hunter,
	Marco Crivellari, Peter Zijlstra, Phil Auld, Thierry Reding,
	Thomas Gleixner, Waiman Long, linux-tegra

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index ba90e385d31f..6377149f6a5e 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 30/49] clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (28 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 29/49] clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 31/49] LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING " Frederic Weisbecker
                   ` (18 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 6377149f6a5e..daad3b496854 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 31/49] LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (29 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 30/49] clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 32/49] clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING " Frederic Weisbecker
                   ` (17 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Thomas Weißschuh, Arnd Bergmann,
	Huacai Chen, Jiaxun Yang, Marco Crivellari, Peter Zijlstra,
	Phil Auld, Thomas Gleixner, WANG Xuerui, Waiman Long, loongarch

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index daad3b496854..664831c50f0b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 32/49] clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (30 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 31/49] LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 33/49] clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING " Frederic Weisbecker
                   ` (16 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Bogendoerfer, Thomas Gleixner,
	Waiman Long, linux-mips

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 664831c50f0b..e648df00c6c1 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 33/49] clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (31 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 32/49] clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 34/49] clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING " Frederic Weisbecker
                   ` (15 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Vineet Gupta,
	Waiman Long, linux-snps-arc

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index e648df00c6c1..75f4cae8971e 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 34/49] clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (32 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 33/49] clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 35/49] clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING " Frederic Weisbecker
                   ` (14 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 75f4cae8971e..374e7599baae 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 35/49] clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (33 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 34/49] clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 36/49] clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING " Frederic Weisbecker
                   ` (13 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Albert Ou, Alexandre Ghiti, Daniel Lezcano,
	Marco Crivellari, Palmer Dabbelt, Paul Walmsley, Peter Zijlstra,
	Phil Auld, Thomas Gleixner, Waiman Long, linux-riscv

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 374e7599baae..c2f25b6f72a4 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 36/49] clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (34 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 35/49] clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 37/49] clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING " Frederic Weisbecker
                   ` (12 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c2f25b6f72a4..9735d6cd01d8 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 37/49] clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (35 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 36/49] clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 38/49] clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING " Frederic Weisbecker
                   ` (11 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Guo Ren, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long,
	linux-csky

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 9735d6cd01d8..f8c8fbbd0628 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 38/49] clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (36 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 37/49] clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 39/49] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING " Frederic Weisbecker
                   ` (10 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index f8c8fbbd0628..c2356a36d345 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 39/49] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (37 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 38/49] clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 40/49] clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING " Frederic Weisbecker
                   ` (9 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, K. Y. Srinivasan, Daniel Lezcano,
	Dexuan Cui, Haiyang Zhang, Long Li, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long, Wei Liu,
	linux-hyperv

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c2356a36d345..c37fe84baaa8 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 40/49] clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (38 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 39/49] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 41/49] ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING " Frederic Weisbecker
                   ` (8 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Daniel Lezcano, Marco Crivellari,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c37fe84baaa8..bc06cb1f0282 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 41/49] ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (39 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 40/49] clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 42/49] ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING " Frederic Weisbecker
                   ` (7 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Russell King, Stefano Stabellini, Thomas Gleixner, Waiman Long,
	linux-arm-kernel, xen-devel

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index bc06cb1f0282..8509c6377a61 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 42/49] ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (40 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 41/49] ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 43/49] smp: Move CPUHP_AP_SMPCFD_DYING " Frederic Weisbecker
                   ` (6 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8509c6377a61..c27e4aa109ba 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 43/49] smp: Move CPUHP_AP_SMPCFD_DYING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (41 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 42/49] ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 44/49] hrtimer: Move CPUHP_AP_HRTIMERS_DYING " Frederic Weisbecker
                   ` (5 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index c27e4aa109ba..4b3fcab1575c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 44/49] hrtimer: Move CPUHP_AP_HRTIMERS_DYING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (42 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 43/49] smp: Move CPUHP_AP_SMPCFD_DYING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 45/49] irq_work: Introduce irq_work_kick_cpu() Frederic Weisbecker
                   ` (4 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 4b3fcab1575c..1da41620a583 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 45/49] irq_work: Introduce irq_work_kick_cpu()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (43 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 44/49] hrtimer: Move CPUHP_AP_HRTIMERS_DYING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 46/49] tick-sched: Convert ad-hoc implementation of irq_work_kick_cpu() Frederic Weisbecker
                   ` (3 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

CPUs in nohz mode need to be kicked in the following situations:

* A tick dependency has been added to a CPU that must exit the nohz_full
  mode. The tick infrastructure has its own ad-hoc implementation of
  such a "kick".

* A timekeeper going offline needs to handover its timekeeping duty
  to another CPU. This is currently assigned directly in stop_machine()
  with the assumption that the new timekeeper is not in dynticks-idle
  mode. But since teardown callbacks are being converted to execute
  concurrently with other CPUs, the new timekeeper may now be idle.
  It so, it must get an IRQ so that the next tick is reevaluated.

Provide a generic empty irq work callback to implement this "kick".

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 include/linux/irq_work.h |  1 +
 kernel/irq_work.c        | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h
index c5afd053ae32..3873f4ff5be4 100644
--- a/include/linux/irq_work.h
+++ b/include/linux/irq_work.h
@@ -51,6 +51,7 @@ static inline bool irq_work_is_hard(struct irq_work *work)
 
 bool irq_work_queue(struct irq_work *work);
 bool irq_work_queue_on(struct irq_work *work, int cpu);
+bool irq_work_kick_cpu(int cpu);
 
 void irq_work_tick(void);
 void irq_work_sync(struct irq_work *work);
diff --git a/kernel/irq_work.c b/kernel/irq_work.c
index f7e2dc2c30c6..a1569266ec35 100644
--- a/kernel/irq_work.c
+++ b/kernel/irq_work.c
@@ -181,6 +181,22 @@ bool irq_work_queue_on(struct irq_work *work, int cpu)
 #endif /* CONFIG_SMP */
 }
 
+static void irq_work_kick(struct irq_work *unused)
+{
+	/*
+	 * Kick the CPU, typically so that it takes action:
+	 * * On IRQ exit (nohz_full dependency changed and tick must be restarted)
+	 * * On the idle path so that the next tick is re-evaluated.
+	 */
+}
+
+static DEFINE_PER_CPU(struct irq_work, irq_work_kick_work) = IRQ_WORK_INIT_HARD(irq_work_kick);
+
+bool irq_work_kick_cpu(int cpu)
+{
+	return irq_work_queue_on(&per_cpu(irq_work_kick_work, cpu), cpu);
+}
+
 bool irq_work_needs_cpu(void)
 {
 	struct llist_head *raised, *lazy;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 46/49] tick-sched: Convert ad-hoc implementation of irq_work_kick_cpu()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (44 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 45/49] irq_work: Introduce irq_work_kick_cpu() Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 47/49] tick: Move CPUHP_AP_TICK_DYING post stop_machine() Frederic Weisbecker
                   ` (2 subsequent siblings)
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/time/tick-sched.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 6c3fea386713..0d6330334eae 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -400,14 +400,6 @@ static bool can_stop_full_tick(int cpu, struct tick_sched *ts)
 	return true;
 }
 
-static void nohz_full_kick_func(struct irq_work *work)
-{
-	/* Empty, the tick restart happens on tick_nohz_irq_exit() */
-}
-
-static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) =
-	IRQ_WORK_INIT_HARD(nohz_full_kick_func);
-
 /*
  * Kick this CPU if it's full dynticks in order to force it to
  * re-evaluate its dependency on the tick and restart it if necessary.
@@ -419,7 +411,7 @@ static void tick_nohz_full_kick(void)
 	if (!tick_nohz_full_cpu(smp_processor_id()))
 		return;
 
-	irq_work_queue(this_cpu_ptr(&nohz_full_kick_work));
+	irq_work_kick_cpu(smp_processor_id());
 }
 
 /*
@@ -431,7 +423,7 @@ void tick_nohz_full_kick_cpu(int cpu)
 	if (!tick_nohz_full_cpu(cpu))
 		return;
 
-	irq_work_queue_on(&per_cpu(nohz_full_kick_work, cpu), cpu);
+	irq_work_kick_cpu(cpu);
 }
 
 static void tick_nohz_kick_task(struct task_struct *tsk)
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 47/49] tick: Move CPUHP_AP_TICK_DYING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (45 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 46/49] tick-sched: Convert ad-hoc implementation of irq_work_kick_cpu() Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 48/49] x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING " Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 49/49] ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING " Frederic Weisbecker
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Thomas Gleixner, Waiman Long

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c              |  4 ++--
 kernel/time/tick-common.c | 14 ++++++++------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 1da41620a583..59ffcd4534c8 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 6a9198a4279b..39b8cb3e3484 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -16,6 +16,7 @@
 #include <linux/percpu.h>
 #include <linux/profile.h>
 #include <linux/sched.h>
+#include <linux/sched/isolation.h>
 #include <linux/module.h>
 #include <trace/events/power.h>
 
@@ -394,13 +395,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);
+		irq_work_kick_cpu(timekeeper);
+	}
 
 	/* Make sure the CPU won't try to retake the timekeeping duty */
 	tick_sched_timer_dying(dying_cpu);
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 48/49] x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (46 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 47/49] tick: Move CPUHP_AP_TICK_DYING post stop_machine() Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  2026-10-19 13:08 ` [RFC PATCH 49/49] ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING " Frederic Weisbecker
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, H. Peter Anvin, Borislav Petkov,
	Dave Hansen, Ingo Molnar, Marco Crivellari, Ning Sun,
	Peter Zijlstra, Phil Auld, Thomas Gleixner, Waiman Long,
	tboot-devel, x86

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,
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.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 59ffcd4534c8..87680f7c6493 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [RFC PATCH 49/49] ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING post stop_machine()
  2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
                   ` (47 preceding siblings ...)
  2026-10-19 13:08 ` [RFC PATCH 48/49] x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING " Frederic Weisbecker
@ 2026-10-19 13:08 ` Frederic Weisbecker
  48 siblings, 0 replies; 50+ messages in thread
From: Frederic Weisbecker @ 2026-10-19 13:08 UTC (permalink / raw)
  To: LKML
  Cc: Frederic Weisbecker, Broadcom internal kernel review list,
	Florian Fainelli, Marco Crivellari, Peter Zijlstra, Phil Auld,
	Russell King, Thomas Gleixner, Waiman Long, linux-arm-kernel

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,
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().

It *looks ok* to disable the cache readahead globally while the other
CPUs are running.

Move this teardown callback to post stop_machine() accordingly.

But please double check.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
---
 kernel/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 87680f7c6493..36f8e6588196 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -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!
 	 */
-- 
2.53.0


^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2026-10-19 13:11 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 13:08 [RFC PATCH 00/49] cpu/hotplug: Remove cpu_down() global stop_machine() except for CPUHP_TEARDOWN_CPU itself Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 01/49] stop_machine: Add post function to execute while other CPUs can exit Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 02/49] x86/cpu/cacheinfo: Move CPUHP_AP_CACHECTRL_STARTING to post stop machine Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 03/49] sched: Move CPUHP_AP_SCHED_STARTING to post stop_machine() Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 04/49] rcu: Move CPUHP_AP_RCUTREE_DYING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 05/49] cpuidle: Move CPUHP_AP_CPU_PM_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 06/49] cpu: Move CPUHP_AP_IRQ_ARMADA_XP_STARTING..CPUHP_AP_IRQ_GIC_STARTING range " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 07/49] irqchip/bcm2836: Move CPUHP_AP_IRQ_BCM2836_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 08/49] cpu: Move [CPUHP_AP_IRQ_EIOINTC_STARTING..CPUHP_AP_IRQ_MIPS_GIC_STARTING] range " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 09/49] irqchip/loongarch-avec: Move CPUHP_AP_IRQ_AVECINTC_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 10/49] irqchip/sifive-plic: Move CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 11/49] irqchip/aslint-sswi: Move CPUHP_AP_IRQ_ACLINT_SSWI_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 12/49] irqchip/irq-riscv-imsic-early: Move CPUHP_AP_IRQ_RISCV_IMSIC_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 13/49] cpu: Move [CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING..CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING] range " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 14/49] perf/x86: Move CPUHP_AP_PERF_X86_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 15/49] perf/amd/ibs: Move CPUHP_AP_PERF_X86_AMD_IBS_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 16/49] cpu: Move CPUHP_AP_PERF_XTENSA_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 17/49] ARM: vfp: Move CPUHP_AP_ARM_VFP_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 18/49] cpu: Move [CPUHP_AP_PERF_ARM_ACPI_STARTING..CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING] range " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 19/49] perf/arm_pmu: Move CPUHP_AP_PERF_ARM_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 20/49] perf: RISC-V: Move CPUHP_AP_PERF_RISCV_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 21/49] ARM: l2c: Move CPUHP_AP_ARM_L2X0_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 22/49] clocksource/drivers/exynos_mct: Move CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 23/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 24/49] clocksource/drivers/arm_arch_timer: Move CPUHP_AP_ARM_ARCH_TIMER_EVTSTRM_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 25/49] clocksource/drivers/arm_global_timer: Move CPUHP_AP_ARM_GLOBAL_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 26/49] clocksource/drivers/jcore: Move CPUHP_AP_JCORE_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 27/49] ARM: smp_twd: Move CPUHP_AP_ARM_TWD_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 28/49] clocksource/drivers/qcom: Move CPUHP_AP_QCOM_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 29/49] clocksource/drivers/timer-tegra: Move CPUHP_AP_TEGRA_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 30/49] clocksource/drivers/armada: Move CPUHP_AP_ARMADA_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 31/49] LoongArch: Move CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 32/49] clocksource/drivers/mips-gic-timer: Move CPUHP_AP_MIPS_GIC_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 33/49] clocksource/drivers/arc_timer: Move CPUHP_AP_ARC_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 34/49] clocksource/drivers/rtl-otto: Move CPUHP_AP_REALTEK_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 35/49] clocksource/drivers/timer-riscv: Move CPUHP_AP_RISCV_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 36/49] clocksource: clint: Move CPUHP_AP_CLINT_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 37/49] clocksource/drivers/c-sky: Move CPUHP_AP_CSKY_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 38/49] clocksource/drivers/timer-ti-dm: Move CPUHP_AP_TI_GP_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 39/49] clocksource: hyper-v: Move CPUHP_AP_HYPERV_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 40/49] clocksource/dummy_timer: Move CPUHP_AP_DUMMY_TIMER_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 41/49] ARM: xen: Move CPUHP_AP_ARM_XEN_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 42/49] ARM: xen: Move CPUHP_AP_ARM_XEN_RUNSTATE_STARTING and CPUHP_AP_ARM64_ISNDEP_STARTING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 43/49] smp: Move CPUHP_AP_SMPCFD_DYING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 44/49] hrtimer: Move CPUHP_AP_HRTIMERS_DYING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 45/49] irq_work: Introduce irq_work_kick_cpu() Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 46/49] tick-sched: Convert ad-hoc implementation of irq_work_kick_cpu() Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 47/49] tick: Move CPUHP_AP_TICK_DYING post stop_machine() Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 48/49] x86/boot/tboot: Move CPUHP_AP_X86_TBOOT_DYING " Frederic Weisbecker
2026-10-19 13:08 ` [RFC PATCH 49/49] ARM: mm: Move CPUHP_AP_ARM_CACHE_B15_RAC_DYING " Frederic Weisbecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®