Skip to content

Commit 787047e

Browse files
bebarinoRussell King
authored andcommitted
ARM: 8392/3: smp: Only expose /sys/.../cpuX/online if hotpluggable
Writes to /sys/.../cpuX/online fail if we determine the platform doesn't support hotplug for that CPU. Furthermore, if the cpu_die op isn't specified the system hangs when we try to offline a CPU and it comes right back online unexpectedly. Let's figure this stuff out before we make the sysfs nodes so that the online file doesn't even exist if it isn't (at least sometimes) possible to hotplug the CPU. Add a new 'cpu_can_disable' op and repoint all 'cpu_disable' implementations at it because all implementers use the op to indicate if a CPU can be hotplugged or not in a static fashion. With PSCI we may need to add a 'cpu_disable' op so that the secure OS can be migrated off the CPU we're trying to hotplug. In this case, the 'cpu_can_disable' op will indicate that all CPUs are hotpluggable by returning true, but the 'cpu_disable' op will make a PSCI migration call and occasionally fail, denying the hotplug of a CPU. This shouldn't be any worse than x86 where we may indicate that all CPUs are hotpluggable but occasionally we can't offline a CPU due to check_irq_vectors_for_cpu_disable() failing to find a CPU to move vectors to. Cc: Mark Rutland <mark.rutland@arm.com> Cc: Nicolas Pitre <nico@linaro.org> Cc: Dave Martin <Dave.Martin@arm.com> Acked-by: Simon Horman <horms@verge.net.au> [shmobile portion] Tested-by: Simon Horman <horms@verge.net.au> Cc: Magnus Damm <magnus.damm@gmail.com> Cc: <linux-sh@vger.kernel.org> Tested-by: Tyler Baker <tyler.baker@linaro.org> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
1 parent 57853e8 commit 787047e

File tree

10 files changed

+35
-16
lines changed

10 files changed

+35
-16
lines changed

arch/arm/common/mcpm_platsmp.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,10 @@ static int mcpm_cpu_kill(unsigned int cpu)
6565
return !mcpm_wait_for_cpu_powerdown(pcpu, pcluster);
6666
}
6767

68-
static int mcpm_cpu_disable(unsigned int cpu)
68+
static bool mcpm_cpu_can_disable(unsigned int cpu)
6969
{
70-
/*
71-
* We assume all CPUs may be shut down.
72-
* This would be the hook to use for eventual Secure
73-
* OS migration requests as described in the PSCI spec.
74-
*/
75-
return 0;
70+
/* We assume all CPUs may be shut down. */
71+
return true;
7672
}
7773

7874
static void mcpm_cpu_die(unsigned int cpu)
@@ -92,7 +88,7 @@ static struct smp_operations __initdata mcpm_smp_ops = {
9288
.smp_secondary_init = mcpm_secondary_init,
9389
#ifdef CONFIG_HOTPLUG_CPU
9490
.cpu_kill = mcpm_cpu_kill,
95-
.cpu_disable = mcpm_cpu_disable,
91+
.cpu_can_disable = mcpm_cpu_can_disable,
9692
.cpu_die = mcpm_cpu_die,
9793
#endif
9894
};

arch/arm/include/asm/smp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ struct smp_operations {
105105
#ifdef CONFIG_HOTPLUG_CPU
106106
int (*cpu_kill)(unsigned int cpu);
107107
void (*cpu_die)(unsigned int cpu);
108+
bool (*cpu_can_disable)(unsigned int cpu);
108109
int (*cpu_disable)(unsigned int cpu);
109110
#endif
110111
#endif

arch/arm/include/asm/smp_plat.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,13 @@ static inline u32 mpidr_hash_size(void)
107107
extern int platform_can_secondary_boot(void);
108108
extern int platform_can_cpu_hotplug(void);
109109

110+
#ifdef CONFIG_HOTPLUG_CPU
111+
extern int platform_can_hotplug_cpu(unsigned int cpu);
112+
#else
113+
static inline int platform_can_hotplug_cpu(unsigned int cpu)
114+
{
115+
return 0;
116+
}
117+
#endif
118+
110119
#endif

arch/arm/kernel/setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ static int __init topology_init(void)
10151015

10161016
for_each_possible_cpu(cpu) {
10171017
struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
1018-
cpuinfo->cpu.hotpluggable = 1;
1018+
cpuinfo->cpu.hotpluggable = platform_can_hotplug_cpu(cpu);
10191019
register_cpu(&cpuinfo->cpu, cpu);
10201020
}
10211021

arch/arm/kernel/smp.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,26 @@ static int platform_cpu_disable(unsigned int cpu)
175175
if (smp_ops.cpu_disable)
176176
return smp_ops.cpu_disable(cpu);
177177

178+
return 0;
179+
}
180+
181+
int platform_can_hotplug_cpu(unsigned int cpu)
182+
{
183+
/* cpu_die must be specified to support hotplug */
184+
if (!smp_ops.cpu_die)
185+
return 0;
186+
187+
if (smp_ops.cpu_can_disable)
188+
return smp_ops.cpu_can_disable(cpu);
189+
178190
/*
179191
* By default, allow disabling all CPUs except the first one,
180192
* since this is special on a lot of platforms, e.g. because
181193
* of clock tick interrupts.
182194
*/
183-
return cpu == 0 ? -EPERM : 0;
195+
return cpu != 0;
184196
}
197+
185198
/*
186199
* __cpu_disable runs on the processor to be shutdown.
187200
*/

arch/arm/mach-shmobile/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extern void shmobile_smp_boot(void);
1313
extern void shmobile_smp_sleep(void);
1414
extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
1515
unsigned long arg);
16-
extern int shmobile_smp_cpu_disable(unsigned int cpu);
16+
extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
1717
extern void shmobile_boot_scu(void);
1818
extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus);
1919
extern void shmobile_smp_scu_cpu_die(unsigned int cpu);

arch/arm/mach-shmobile/platsmp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg)
3131
}
3232

3333
#ifdef CONFIG_HOTPLUG_CPU
34-
int shmobile_smp_cpu_disable(unsigned int cpu)
34+
bool shmobile_smp_cpu_can_disable(unsigned int cpu)
3535
{
36-
return 0; /* Hotplug of any CPU is supported */
36+
return true; /* Hotplug of any CPU is supported */
3737
}
3838
#endif

arch/arm/mach-shmobile/smp-r8a7790.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct smp_operations r8a7790_smp_ops __initdata = {
6464
.smp_prepare_cpus = r8a7790_smp_prepare_cpus,
6565
.smp_boot_secondary = shmobile_smp_apmu_boot_secondary,
6666
#ifdef CONFIG_HOTPLUG_CPU
67-
.cpu_disable = shmobile_smp_cpu_disable,
67+
.cpu_can_disable = shmobile_smp_cpu_can_disable,
6868
.cpu_die = shmobile_smp_apmu_cpu_die,
6969
.cpu_kill = shmobile_smp_apmu_cpu_kill,
7070
#endif

arch/arm/mach-shmobile/smp-r8a7791.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct smp_operations r8a7791_smp_ops __initdata = {
5858
.smp_prepare_cpus = r8a7791_smp_prepare_cpus,
5959
.smp_boot_secondary = r8a7791_smp_boot_secondary,
6060
#ifdef CONFIG_HOTPLUG_CPU
61-
.cpu_disable = shmobile_smp_cpu_disable,
61+
.cpu_can_disable = shmobile_smp_cpu_can_disable,
6262
.cpu_die = shmobile_smp_apmu_cpu_die,
6363
.cpu_kill = shmobile_smp_apmu_cpu_kill,
6464
#endif

arch/arm/mach-shmobile/smp-sh73a0.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct smp_operations sh73a0_smp_ops __initdata = {
6868
.smp_prepare_cpus = sh73a0_smp_prepare_cpus,
6969
.smp_boot_secondary = sh73a0_boot_secondary,
7070
#ifdef CONFIG_HOTPLUG_CPU
71-
.cpu_disable = shmobile_smp_cpu_disable,
71+
.cpu_can_disable = shmobile_smp_cpu_can_disable,
7272
.cpu_die = shmobile_smp_scu_cpu_die,
7373
.cpu_kill = shmobile_smp_scu_cpu_kill,
7474
#endif

0 commit comments

Comments
 (0)