Skip to content

Commit

Permalink
powerpc/pseries: Initialise CPU hotplug callbacks earlier
Browse files Browse the repository at this point in the history
As part of the generic HOTPLUG_SMT code, there is support for disabling
secondary SMT threads at boot time, by passing "nosmt" on the kernel
command line.

The way that is implemented is the secondary threads are brought partly
online, and then taken back offline again. That is done to support x86
CPUs needing certain initialisation done on all threads. However powerpc
has similar needs, see commit d70a54e ("powerpc/powernv: Ignore
smt-enabled on Power8 and later").

For that to work the powerpc CPU hotplug callbacks need to be registered
before secondary CPUs are brought online, otherwise __cpu_disable()
fails due to smp_ops->cpu_disable being NULL.

So split the basic initialisation into pseries_cpu_hotplug_init() which
can be called early from setup_arch(). The DLPAR related initialisation
can still be done later, because it needs to do allocations.

Signed-off-by: Michael Ellerman <[email protected]>
Link: https://msgid.link/[email protected]
  • Loading branch information
mpe committed Aug 2, 2023
1 parent d82e676 commit 3b3a4d0
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
22 changes: 13 additions & 9 deletions arch/powerpc/platforms/pseries/hotplug-cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,15 +845,9 @@ static struct notifier_block pseries_smp_nb = {
.notifier_call = pseries_smp_notifier,
};

static int __init pseries_cpu_hotplug_init(void)
void __init pseries_cpu_hotplug_init(void)
{
int qcss_tok;
unsigned int node;

#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ppc_md.cpu_probe = dlpar_cpu_probe;
ppc_md.cpu_release = dlpar_cpu_release;
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */

rtas_stop_self_token = rtas_function_token(RTAS_FN_STOP_SELF);
qcss_tok = rtas_function_token(RTAS_FN_QUERY_CPU_STOPPED_STATE);
Expand All @@ -862,12 +856,22 @@ static int __init pseries_cpu_hotplug_init(void)
qcss_tok == RTAS_UNKNOWN_SERVICE) {
printk(KERN_INFO "CPU Hotplug not supported by firmware "
"- disabling.\n");
return 0;
return;
}

smp_ops->cpu_offline_self = pseries_cpu_offline_self;
smp_ops->cpu_disable = pseries_cpu_disable;
smp_ops->cpu_die = pseries_cpu_die;
}

static int __init pseries_dlpar_init(void)
{
unsigned int node;

#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ppc_md.cpu_probe = dlpar_cpu_probe;
ppc_md.cpu_release = dlpar_cpu_release;
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */

/* Processors can be added/removed only on LPAR */
if (firmware_has_feature(FW_FEATURE_LPAR)) {
Expand All @@ -886,4 +890,4 @@ static int __init pseries_cpu_hotplug_init(void)

return 0;
}
machine_arch_initcall(pseries, pseries_cpu_hotplug_init);
machine_arch_initcall(pseries, pseries_dlpar_init);
2 changes: 2 additions & 0 deletions arch/powerpc/platforms/pseries/pseries.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ static inline int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)

#ifdef CONFIG_HOTPLUG_CPU
int dlpar_cpu(struct pseries_hp_errorlog *hp_elog);
void pseries_cpu_hotplug_init(void);
#else
static inline int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
{
return -EOPNOTSUPP;
}
static inline void pseries_cpu_hotplug_init(void) { }
#endif

/* PCI root bridge prepare function override for pseries */
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/platforms/pseries/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,8 @@ static void __init pSeries_setup_arch(void)
/* Discover PIC type and setup ppc_md accordingly */
smp_init_pseries();

// Setup CPU hotplug callbacks
pseries_cpu_hotplug_init();

if (radix_enabled() && !mmu_has_feature(MMU_FTR_GTSE))
if (!firmware_has_feature(FW_FEATURE_RPT_INVALIDATE))
Expand Down

0 comments on commit 3b3a4d0

Please sign in to comment.