powerpc/pseries: Initialise CPU hotplug callbacks earlier
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 d70a54e2d0
("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 <mpe@ellerman.id.au>
Link: https://msgid.link/20230705145143.40545-9-ldufour@linux.ibm.com
This commit is contained in:
parent
d82e6762b0
commit
3b3a4d0fe5
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue