[PATCH] don't use flush_tlb_all in suspend time

flush_tlb_all uses on_each_cpu, which will disable/enable interrupt.
In suspend/resume time, this will make interrupt wrongly enabled.

Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Shaohua Li 2006-06-23 02:04:49 -07:00 committed by Linus Torvalds
parent 968808b895
commit 55b2355eef
4 changed files with 10 additions and 21 deletions

View File

@ -8,30 +8,17 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/cpumask.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/tlbflush.h>
/* address in low memory of the wakeup routine. */ /* address in low memory of the wakeup routine. */
unsigned long acpi_wakeup_address = 0; unsigned long acpi_wakeup_address = 0;
unsigned long acpi_video_flags; unsigned long acpi_video_flags;
extern char wakeup_start, wakeup_end; extern char wakeup_start, wakeup_end;
extern void zap_low_mappings(void);
extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
static void init_low_mapping(pgd_t * pgd, int pgd_limit)
{
int pgd_ofs = 0;
while ((pgd_ofs < pgd_limit)
&& (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD));
pgd_ofs++, pgd++;
}
flush_tlb_all();
}
/** /**
* acpi_save_state_mem - save kernel state * acpi_save_state_mem - save kernel state
* *
@ -42,7 +29,6 @@ int acpi_save_state_mem(void)
{ {
if (!acpi_wakeup_address) if (!acpi_wakeup_address)
return 1; return 1;
init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
memcpy((void *)acpi_wakeup_address, &wakeup_start, memcpy((void *)acpi_wakeup_address, &wakeup_start,
&wakeup_end - &wakeup_start); &wakeup_end - &wakeup_start);
acpi_copy_wakeup_routine(acpi_wakeup_address); acpi_copy_wakeup_routine(acpi_wakeup_address);
@ -55,7 +41,6 @@ int acpi_save_state_mem(void)
*/ */
void acpi_restore_state_mem(void) void acpi_restore_state_mem(void)
{ {
zap_low_mappings();
} }
/** /**

View File

@ -56,7 +56,7 @@ wakeup_code:
1: 1:
# set up page table # set up page table
movl $swapper_pg_dir-__PAGE_OFFSET, %eax movl $swsusp_pg_dir-__PAGE_OFFSET, %eax
movl %eax, %cr3 movl %eax, %cr3
testl $1, real_efer_save_restore - wakeup_code testl $1, real_efer_save_restore - wakeup_code

View File

@ -29,6 +29,7 @@
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/memory_hotplug.h> #include <linux/memory_hotplug.h>
#include <linux/initrd.h> #include <linux/initrd.h>
#include <linux/cpumask.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/system.h> #include <asm/system.h>
@ -384,7 +385,7 @@ static void __init pagetable_init (void)
#endif #endif
} }
#ifdef CONFIG_SOFTWARE_SUSPEND #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
/* /*
* Swap suspend & friends need this for resume because things like the intel-agp * Swap suspend & friends need this for resume because things like the intel-agp
* driver might have split up a kernel 4MB mapping. * driver might have split up a kernel 4MB mapping.

View File

@ -35,6 +35,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/bootmem.h> #include <linux/bootmem.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/cpumask.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/apic.h> #include <asm/apic.h>
@ -66,7 +68,8 @@ static void init_low_mapping(void)
pgd_t *slot0 = pgd_offset(current->mm, 0UL); pgd_t *slot0 = pgd_offset(current->mm, 0UL);
low_ptr = *slot0; low_ptr = *slot0;
set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET));
flush_tlb_all(); WARN_ON(num_online_cpus() != 1);
local_flush_tlb();
} }
/** /**
@ -92,7 +95,7 @@ int acpi_save_state_mem(void)
void acpi_restore_state_mem(void) void acpi_restore_state_mem(void)
{ {
set_pgd(pgd_offset(current->mm, 0UL), low_ptr); set_pgd(pgd_offset(current->mm, 0UL), low_ptr);
flush_tlb_all(); local_flush_tlb();
} }
/** /**