Package: linux-image-2.6.17-1-686 Version: 2.6.17-5 Severity: normal Tags: patch
Dell Latitude D420 does not resume properly from suspend-to-RAM -- this works with 2.6.16 and current git head (around 2.6.18-rc4 somewhere), but not with 2.6.17. The included patch was applied around 2.6.18-rc1, and fixes the issue. (It's still not 100% reliable, probably due to other suspend issues in the kernel since uswsusp was brand new in 2.6.17, but at least it works _usually_ instead of _never_.) -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.17-sesse Locale: LANG=nb_NO.UTF-8, LC_CTYPE=nb_NO.UTF-8 (charmap=UTF-8) Versions of packages linux-image-2.6.17-1-686 depends on: ii initramfs-tools [linux-initra 0.73c tools for generating an initramfs ii module-init-tools 3.2.2-3 tools for managing Linux kernel mo Versions of packages linux-image-2.6.17-1-686 recommends: pn libc6-i686 <none> (no description available) -- debconf information: linux-image-2.6.17-1-686/preinst/bootloader-initrd-2.6.17-1-686: true linux-image-2.6.17-1-686/postinst/old-dir-initrd-link-2.6.17-1-686: true linux-image-2.6.17-1-686/postinst/bootloader-test-error-2.6.17-1-686: linux-image-2.6.17-1-686/postinst/old-initrd-link-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/lilo-has-ramdisk: linux-image-2.6.17-1-686/postinst/depmod-error-2.6.17-1-686: false linux-image-2.6.17-1-686/prerm/removing-running-kernel-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/overwriting-modules-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/lilo-initrd-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/failed-to-move-modules-2.6.17-1-686: linux-image-2.6.17-1-686/postinst/create-kimage-link-2.6.17-1-686: true linux-image-2.6.17-1-686/postinst/kimage-is-a-directory: linux-image-2.6.17-1-686/postinst/old-system-map-link-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/elilo-initrd-2.6.17-1-686: true linux-image-2.6.17-1-686/preinst/already-running-this-2.6.17-1-686: linux-image-2.6.17-1-686/preinst/abort-overwrite-2.6.17-1-686: linux-image-2.6.17-1-686/postinst/bootloader-error-2.6.17-1-686: linux-image-2.6.17-1-686/preinst/initrd-2.6.17-1-686: linux-image-2.6.17-1-686/postinst/depmod-error-initrd-2.6.17-1-686: false linux-image-2.6.17-1-686/preinst/abort-install-2.6.17-1-686: linux-image-2.6.17-1-686/prerm/would-invalidate-boot-loader-2.6.17-1-686: true
commit 55b2355eefc2f160246226d4d69fed431173a4d5 author Shaohua Li <[EMAIL PROTECTED]> Fri, 23 Jun 2006 02:04:49 -0700 committer Linus Torvalds <[EMAIL PROTECTED]> Fri, 23 Jun 2006 07:43:00 -0700 [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 <[EMAIL PROTECTED]> Cc: Pavel Machek <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c index 1cb2b18..4ee8357 100644 --- a/arch/i386/kernel/acpi/sleep.c +++ b/arch/i386/kernel/acpi/sleep.c @@ -8,30 +8,17 @@ #include <linux/acpi.h> #include <linux/bootmem.h> #include <linux/dmi.h> +#include <linux/cpumask.h> + #include <asm/smp.h> -#include <asm/tlbflush.h> /* address in low memory of the wakeup routine. */ unsigned long acpi_wakeup_address = 0; unsigned long acpi_video_flags; extern char wakeup_start, wakeup_end; -extern void zap_low_mappings(void); - 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 * @@ -42,7 +29,6 @@ int acpi_save_state_mem(void) { if (!acpi_wakeup_address) return 1; - init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); memcpy((void *)acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); acpi_copy_wakeup_routine(acpi_wakeup_address); @@ -55,7 +41,6 @@ int acpi_save_state_mem(void) */ void acpi_restore_state_mem(void) { - zap_low_mappings(); } /** diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S index 7c74fe0..dcb4d3c 100644 --- a/arch/i386/kernel/acpi/wakeup.S +++ b/arch/i386/kernel/acpi/wakeup.S @@ -56,7 +56,7 @@ wakeup_code: 1: # set up page table - movl $swapper_pg_dir-__PAGE_OFFSET, %eax + movl $swsusp_pg_dir-__PAGE_OFFSET, %eax movl %eax, %cr3 testl $1, real_efer_save_restore - wakeup_code diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 3df1371..bf19513 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -29,6 +29,7 @@ #include <linux/proc_fs.h> #include <linux/efi.h> #include <linux/memory_hotplug.h> #include <linux/initrd.h> +#include <linux/cpumask.h> #include <asm/processor.h> #include <asm/system.h> @@ -384,7 +385,7 @@ #ifdef CONFIG_X86_PAE #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 * driver might have split up a kernel 4MB mapping. diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index 867a0eb..091bc79 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c @@ -35,6 +35,8 @@ #include <linux/slab.h> #include <linux/pci.h> #include <linux/bootmem.h> #include <linux/acpi.h> +#include <linux/cpumask.h> + #include <asm/mpspec.h> #include <asm/io.h> #include <asm/apic.h> @@ -66,7 +68,8 @@ static void init_low_mapping(void) pgd_t *slot0 = pgd_offset(current->mm, 0UL); low_ptr = *slot0; 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) { set_pgd(pgd_offset(current->mm, 0UL), low_ptr); - flush_tlb_all(); + local_flush_tlb(); } /**