Skip to content

Commit 3fb82d5

Browse files
Suresh SiddhaH. Peter Anvin
authored andcommitted
x86, suspend: Avoid unnecessary smp alternatives switch during suspend/resume
During suspend, we disable all the non boot cpus. And during resume we bring them all back again. So no need to do alternatives_smp_switch() in between. On my core 2 based laptop, this speeds up the suspend path by 15msec and the resume path by 5 msec (suspend/resume speed up differences can be attributed to the different P-states that the cpu is in during suspend/resume). Signed-off-by: Suresh Siddha <[email protected]> LKML-Reference: <[email protected]> Cc: Rafael J. Wysocki <[email protected]> Signed-off-by: H. Peter Anvin <[email protected]>
1 parent cf7d7e5 commit 3fb82d5

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

arch/x86/include/asm/alternative.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ extern void alternatives_smp_module_add(struct module *mod, char *name,
6666
extern void alternatives_smp_module_del(struct module *mod);
6767
extern void alternatives_smp_switch(int smp);
6868
extern int alternatives_text_reserved(void *start, void *end);
69+
extern bool skip_smp_alternatives;
6970
#else
7071
static inline void alternatives_smp_module_add(struct module *mod, char *name,
7172
void *locks, void *locks_end,

arch/x86/kernel/alternative.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ void __init_or_module alternatives_smp_module_del(struct module *mod)
353353
mutex_unlock(&smp_alt);
354354
}
355355

356+
bool skip_smp_alternatives;
356357
void alternatives_smp_switch(int smp)
357358
{
358359
struct smp_alt_module *mod;
@@ -368,7 +369,7 @@ void alternatives_smp_switch(int smp)
368369
printk("lockdep: fixing up alternatives.\n");
369370
#endif
370371

371-
if (noreplace_smp || smp_alt_once)
372+
if (noreplace_smp || smp_alt_once || skip_smp_alternatives)
372373
return;
373374
BUG_ON(!smp && (num_online_cpus() > 1));
374375

arch/x86/kernel/smpboot.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,20 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
11661166
preempt_enable();
11671167
}
11681168

1169+
void arch_disable_nonboot_cpus_begin(void)
1170+
{
1171+
/*
1172+
* Avoid the smp alternatives switch during the disable_nonboot_cpus().
1173+
* In the suspend path, we will be back in the SMP mode shortly anyways.
1174+
*/
1175+
skip_smp_alternatives = true;
1176+
}
1177+
1178+
void arch_disable_nonboot_cpus_end(void)
1179+
{
1180+
skip_smp_alternatives = false;
1181+
}
1182+
11691183
void arch_enable_nonboot_cpus_begin(void)
11701184
{
11711185
set_mtrr_aps_delayed_init();

kernel/cpu.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,14 @@ int __cpuinit cpu_up(unsigned int cpu)
386386
#ifdef CONFIG_PM_SLEEP_SMP
387387
static cpumask_var_t frozen_cpus;
388388

389+
void __weak arch_disable_nonboot_cpus_begin(void)
390+
{
391+
}
392+
393+
void __weak arch_disable_nonboot_cpus_end(void)
394+
{
395+
}
396+
389397
int disable_nonboot_cpus(void)
390398
{
391399
int cpu, first_cpu, error = 0;
@@ -397,6 +405,7 @@ int disable_nonboot_cpus(void)
397405
* with the userspace trying to use the CPU hotplug at the same time
398406
*/
399407
cpumask_clear(frozen_cpus);
408+
arch_disable_nonboot_cpus_begin();
400409

401410
printk("Disabling non-boot CPUs ...\n");
402411
for_each_online_cpu(cpu) {
@@ -412,6 +421,8 @@ int disable_nonboot_cpus(void)
412421
}
413422
}
414423

424+
arch_disable_nonboot_cpus_end();
425+
415426
if (!error) {
416427
BUG_ON(num_online_cpus() > 1);
417428
/* Make sure the CPUs won't be enabled by someone else */

0 commit comments

Comments
 (0)