* [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI
@ 2011-01-07 0:41 Rafael J. Wysocki
2011-01-07 0:42 ` [PATCH 1/5] PM: Fix oops in suspend/hibernate code related to failing ioremap() Rafael J. Wysocki
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:41 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
Hi,
The following series of patches makes the NVS save/restore code work correctly
if ioremap_cache() is used by ACPI.
[1/5] - Fix Oops in the NVS saving code related to failing ioremap()
(patch from Jiri).
[2/5] - Move the NVS save/restore code to drivers/acpi.
[3/5] - Update file information and the list of includes in nvs.c.
[4/5] - Make suspend_nvs_save() use acpi_os_map_memory().
[5/5] - Make ACPI use ioremap_cache() internally.
Please review/test.
Do you want me to take these patches to my tree or are you going to push them
to Linus?
Rafael
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/5] PM: Fix oops in suspend/hibernate code related to failing ioremap()
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
@ 2011-01-07 0:42 ` Rafael J. Wysocki
2011-01-07 0:43 ` [PATCH 2/5] PM / ACPI: Move NVS saving and restoring code to drivers/acpi Rafael J. Wysocki
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:42 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
From: Jiri Slaby <jslaby@suse.cz>
When ioremap() fails (which might happen for some reason), we nicely
oops in suspend_nvs_save() due to NULL dereference by memcpy() in there.
Fail gracefully instead.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/acpi/sleep.c | 5 ++---
include/linux/suspend.h | 4 ++--
kernel/power/nvs.c | 8 +++++++-
3 files changed, 11 insertions(+), 6 deletions(-)
Index: linux-2.6/drivers/acpi/sleep.c
===================================================================
--- linux-2.6.orig/drivers/acpi/sleep.c
+++ linux-2.6/drivers/acpi/sleep.c
@@ -124,8 +124,7 @@ static int acpi_pm_freeze(void)
static int acpi_pm_pre_suspend(void)
{
acpi_pm_freeze();
- suspend_nvs_save();
- return 0;
+ return suspend_nvs_save();
}
/**
@@ -151,7 +150,7 @@ static int acpi_pm_prepare(void)
{
int error = __acpi_pm_prepare();
if (!error)
- acpi_pm_pre_suspend();
+ error = acpi_pm_pre_suspend();
return error;
}
Index: linux-2.6/include/linux/suspend.h
===================================================================
--- linux-2.6.orig/include/linux/suspend.h
+++ linux-2.6/include/linux/suspend.h
@@ -262,7 +262,7 @@ static inline bool system_entering_hiber
extern int suspend_nvs_register(unsigned long start, unsigned long size);
extern int suspend_nvs_alloc(void);
extern void suspend_nvs_free(void);
-extern void suspend_nvs_save(void);
+extern int suspend_nvs_save(void);
extern void suspend_nvs_restore(void);
#else /* CONFIG_SUSPEND_NVS */
static inline int suspend_nvs_register(unsigned long a, unsigned long b)
@@ -271,7 +271,7 @@ static inline int suspend_nvs_register(u
}
static inline int suspend_nvs_alloc(void) { return 0; }
static inline void suspend_nvs_free(void) {}
-static inline void suspend_nvs_save(void) {}
+static inline int suspend_nvs_save(void) {}
static inline void suspend_nvs_restore(void) {}
#endif /* CONFIG_SUSPEND_NVS */
Index: linux-2.6/kernel/power/nvs.c
===================================================================
--- linux-2.6.orig/kernel/power/nvs.c
+++ linux-2.6/kernel/power/nvs.c
@@ -105,7 +105,7 @@ int suspend_nvs_alloc(void)
/**
* suspend_nvs_save - save NVS memory regions
*/
-void suspend_nvs_save(void)
+int suspend_nvs_save(void)
{
struct nvs_page *entry;
@@ -114,8 +114,14 @@ void suspend_nvs_save(void)
list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
entry->kaddr = ioremap(entry->phys_start, entry->size);
+ if (!entry->kaddr) {
+ suspend_nvs_free();
+ return -ENOMEM;
+ }
memcpy(entry->data, entry->kaddr, entry->size);
}
+
+ return 0;
}
/**
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] PM / ACPI: Move NVS saving and restoring code to drivers/acpi
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
2011-01-07 0:42 ` [PATCH 1/5] PM: Fix oops in suspend/hibernate code related to failing ioremap() Rafael J. Wysocki
@ 2011-01-07 0:43 ` Rafael J. Wysocki
2011-01-07 0:44 ` [PATCH 3/5] ACPI / PM: Update file information and the list of includes in nvs.c Rafael J. Wysocki
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:43 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
From: Rafael J. Wysocki <rjw@sisk.pl>
The saving of the ACPI NVS area during hibernation and suspend and
restoring it during the subsequent resume is entirely specific to
ACPI, so move it to drivers/acpi and drop the CONFIG_SUSPEND_NVS
configuration option which is redundant.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
arch/x86/kernel/e820.c | 1
drivers/acpi/Makefile | 2
drivers/acpi/internal.h | 8 ++
drivers/acpi/nvs.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 9 +++
include/linux/suspend.h | 17 -----
kernel/power/Kconfig | 5 -
kernel/power/Makefile | 1
kernel/power/nvs.c | 142 ------------------------------------------------
9 files changed, 161 insertions(+), 166 deletions(-)
Index: linux-2.6/drivers/acpi/nvs.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/acpi/nvs.c
@@ -0,0 +1,142 @@
+/*
+ * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
+ *
+ * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+
+/*
+ * Platforms, like ACPI, may want us to save some memory used by them during
+ * suspend and to restore the contents of this memory during the subsequent
+ * resume. The code below implements a mechanism allowing us to do that.
+ */
+
+struct nvs_page {
+ unsigned long phys_start;
+ unsigned int size;
+ void *kaddr;
+ void *data;
+ struct list_head node;
+};
+
+static LIST_HEAD(nvs_list);
+
+/**
+ * suspend_nvs_register - register platform NVS memory region to save
+ * @start - physical address of the region
+ * @size - size of the region
+ *
+ * The NVS region need not be page-aligned (both ends) and we arrange
+ * things so that the data from page-aligned addresses in this region will
+ * be copied into separate RAM pages.
+ */
+int suspend_nvs_register(unsigned long start, unsigned long size)
+{
+ struct nvs_page *entry, *next;
+
+ while (size > 0) {
+ unsigned int nr_bytes;
+
+ entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
+ if (!entry)
+ goto Error;
+
+ list_add_tail(&entry->node, &nvs_list);
+ entry->phys_start = start;
+ nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
+ entry->size = (size < nr_bytes) ? size : nr_bytes;
+
+ start += entry->size;
+ size -= entry->size;
+ }
+ return 0;
+
+ Error:
+ list_for_each_entry_safe(entry, next, &nvs_list, node) {
+ list_del(&entry->node);
+ kfree(entry);
+ }
+ return -ENOMEM;
+}
+
+/**
+ * suspend_nvs_free - free data pages allocated for saving NVS regions
+ */
+void suspend_nvs_free(void)
+{
+ struct nvs_page *entry;
+
+ list_for_each_entry(entry, &nvs_list, node)
+ if (entry->data) {
+ free_page((unsigned long)entry->data);
+ entry->data = NULL;
+ if (entry->kaddr) {
+ iounmap(entry->kaddr);
+ entry->kaddr = NULL;
+ }
+ }
+}
+
+/**
+ * suspend_nvs_alloc - allocate memory necessary for saving NVS regions
+ */
+int suspend_nvs_alloc(void)
+{
+ struct nvs_page *entry;
+
+ list_for_each_entry(entry, &nvs_list, node) {
+ entry->data = (void *)__get_free_page(GFP_KERNEL);
+ if (!entry->data) {
+ suspend_nvs_free();
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+/**
+ * suspend_nvs_save - save NVS memory regions
+ */
+int suspend_nvs_save(void)
+{
+ struct nvs_page *entry;
+
+ printk(KERN_INFO "PM: Saving platform NVS memory\n");
+
+ list_for_each_entry(entry, &nvs_list, node)
+ if (entry->data) {
+ entry->kaddr = ioremap(entry->phys_start, entry->size);
+ if (!entry->kaddr) {
+ suspend_nvs_free();
+ return -ENOMEM;
+ }
+ memcpy(entry->data, entry->kaddr, entry->size);
+ }
+
+ return 0;
+}
+
+/**
+ * suspend_nvs_restore - restore NVS memory regions
+ *
+ * This function is going to be called with interrupts disabled, so it
+ * cannot iounmap the virtual addresses used to access the NVS region.
+ */
+void suspend_nvs_restore(void)
+{
+ struct nvs_page *entry;
+
+ printk(KERN_INFO "PM: Restoring platform NVS memory\n");
+
+ list_for_each_entry(entry, &nvs_list, node)
+ if (entry->data)
+ memcpy(entry->kaddr, entry->data, entry->size);
+}
Index: linux-2.6/kernel/power/nvs.c
===================================================================
--- linux-2.6.orig/kernel/power/nvs.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
- *
- * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is released under the GPLv2.
- */
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/suspend.h>
-
-/*
- * Platforms, like ACPI, may want us to save some memory used by them during
- * suspend and to restore the contents of this memory during the subsequent
- * resume. The code below implements a mechanism allowing us to do that.
- */
-
-struct nvs_page {
- unsigned long phys_start;
- unsigned int size;
- void *kaddr;
- void *data;
- struct list_head node;
-};
-
-static LIST_HEAD(nvs_list);
-
-/**
- * suspend_nvs_register - register platform NVS memory region to save
- * @start - physical address of the region
- * @size - size of the region
- *
- * The NVS region need not be page-aligned (both ends) and we arrange
- * things so that the data from page-aligned addresses in this region will
- * be copied into separate RAM pages.
- */
-int suspend_nvs_register(unsigned long start, unsigned long size)
-{
- struct nvs_page *entry, *next;
-
- while (size > 0) {
- unsigned int nr_bytes;
-
- entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
- if (!entry)
- goto Error;
-
- list_add_tail(&entry->node, &nvs_list);
- entry->phys_start = start;
- nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
- entry->size = (size < nr_bytes) ? size : nr_bytes;
-
- start += entry->size;
- size -= entry->size;
- }
- return 0;
-
- Error:
- list_for_each_entry_safe(entry, next, &nvs_list, node) {
- list_del(&entry->node);
- kfree(entry);
- }
- return -ENOMEM;
-}
-
-/**
- * suspend_nvs_free - free data pages allocated for saving NVS regions
- */
-void suspend_nvs_free(void)
-{
- struct nvs_page *entry;
-
- list_for_each_entry(entry, &nvs_list, node)
- if (entry->data) {
- free_page((unsigned long)entry->data);
- entry->data = NULL;
- if (entry->kaddr) {
- iounmap(entry->kaddr);
- entry->kaddr = NULL;
- }
- }
-}
-
-/**
- * suspend_nvs_alloc - allocate memory necessary for saving NVS regions
- */
-int suspend_nvs_alloc(void)
-{
- struct nvs_page *entry;
-
- list_for_each_entry(entry, &nvs_list, node) {
- entry->data = (void *)__get_free_page(GFP_KERNEL);
- if (!entry->data) {
- suspend_nvs_free();
- return -ENOMEM;
- }
- }
- return 0;
-}
-
-/**
- * suspend_nvs_save - save NVS memory regions
- */
-int suspend_nvs_save(void)
-{
- struct nvs_page *entry;
-
- printk(KERN_INFO "PM: Saving platform NVS memory\n");
-
- list_for_each_entry(entry, &nvs_list, node)
- if (entry->data) {
- entry->kaddr = ioremap(entry->phys_start, entry->size);
- if (!entry->kaddr) {
- suspend_nvs_free();
- return -ENOMEM;
- }
- memcpy(entry->data, entry->kaddr, entry->size);
- }
-
- return 0;
-}
-
-/**
- * suspend_nvs_restore - restore NVS memory regions
- *
- * This function is going to be called with interrupts disabled, so it
- * cannot iounmap the virtual addresses used to access the NVS region.
- */
-void suspend_nvs_restore(void)
-{
- struct nvs_page *entry;
-
- printk(KERN_INFO "PM: Restoring platform NVS memory\n");
-
- list_for_each_entry(entry, &nvs_list, node)
- if (entry->data)
- memcpy(entry->kaddr, entry->data, entry->size);
-}
Index: linux-2.6/include/linux/suspend.h
===================================================================
--- linux-2.6.orig/include/linux/suspend.h
+++ linux-2.6/include/linux/suspend.h
@@ -258,23 +258,6 @@ static inline int hibernate(void) { retu
static inline bool system_entering_hibernation(void) { return false; }
#endif /* CONFIG_HIBERNATION */
-#ifdef CONFIG_SUSPEND_NVS
-extern int suspend_nvs_register(unsigned long start, unsigned long size);
-extern int suspend_nvs_alloc(void);
-extern void suspend_nvs_free(void);
-extern int suspend_nvs_save(void);
-extern void suspend_nvs_restore(void);
-#else /* CONFIG_SUSPEND_NVS */
-static inline int suspend_nvs_register(unsigned long a, unsigned long b)
-{
- return 0;
-}
-static inline int suspend_nvs_alloc(void) { return 0; }
-static inline void suspend_nvs_free(void) {}
-static inline int suspend_nvs_save(void) {}
-static inline void suspend_nvs_restore(void) {}
-#endif /* CONFIG_SUSPEND_NVS */
-
#ifdef CONFIG_PM_SLEEP
void save_processor_state(void);
void restore_processor_state(void);
Index: linux-2.6/drivers/acpi/Makefile
===================================================================
--- linux-2.6.orig/drivers/acpi/Makefile
+++ linux-2.6/drivers/acpi/Makefile
@@ -24,7 +24,7 @@ acpi-y += atomicio.o
# sleep related files
acpi-y += wakeup.o
acpi-y += sleep.o
-acpi-$(CONFIG_ACPI_SLEEP) += proc.o
+acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o
#
Index: linux-2.6/drivers/acpi/internal.h
===================================================================
--- linux-2.6.orig/drivers/acpi/internal.h
+++ linux-2.6/drivers/acpi/internal.h
@@ -83,8 +83,16 @@ extern int acpi_sleep_init(void);
#ifdef CONFIG_ACPI_SLEEP
int acpi_sleep_proc_init(void);
+int suspend_nvs_alloc(void);
+void suspend_nvs_free(void);
+int suspend_nvs_save(void);
+void suspend_nvs_restore(void);
#else
static inline int acpi_sleep_proc_init(void) { return 0; }
+static inline int suspend_nvs_alloc(void) { return 0; }
+static inline void suspend_nvs_free(void) {}
+static inline int suspend_nvs_save(void) {}
+static inline void suspend_nvs_restore(void) {}
#endif
#endif /* _ACPI_INTERNAL_H_ */
Index: linux-2.6/include/linux/acpi.h
===================================================================
--- linux-2.6.orig/include/linux/acpi.h
+++ linux-2.6/include/linux/acpi.h
@@ -254,6 +254,15 @@ void __init acpi_old_suspend_ordering(vo
void __init acpi_nvs_nosave(void);
#endif /* CONFIG_PM_SLEEP */
+#ifdef CONFIG_ACPI_SLEEP
+int suspend_nvs_register(unsigned long start, unsigned long size);
+#else
+static inline int suspend_nvs_register(unsigned long a, unsigned long b)
+{
+ return 0;
+}
+#endif
+
struct acpi_osc_context {
char *uuid_str; /* uuid string */
int rev;
Index: linux-2.6/arch/x86/kernel/e820.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/e820.c
+++ linux-2.6/arch/x86/kernel/e820.c
@@ -14,6 +14,7 @@
#include <linux/bootmem.h>
#include <linux/pfn.h>
#include <linux/suspend.h>
+#include <linux/acpi.h>
#include <linux/firmware-map.h>
#include <linux/memblock.h>
Index: linux-2.6/kernel/power/Kconfig
===================================================================
--- linux-2.6.orig/kernel/power/Kconfig
+++ linux-2.6/kernel/power/Kconfig
@@ -100,13 +100,9 @@ config PM_SLEEP_ADVANCED_DEBUG
depends on PM_ADVANCED_DEBUG
default n
-config SUSPEND_NVS
- bool
-
config SUSPEND
bool "Suspend to RAM and standby"
depends on PM && ARCH_SUSPEND_POSSIBLE
- select SUSPEND_NVS if HAS_IOMEM
default y
---help---
Allow the system to enter sleep states in which main memory is
@@ -140,7 +136,6 @@ config HIBERNATION
depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
select LZO_COMPRESS
select LZO_DECOMPRESS
- select SUSPEND_NVS if HAS_IOMEM
---help---
Enable the suspend to disk (STD) functionality, which is usually
called "hibernation" in user interfaces. STD checkpoints the
Index: linux-2.6/kernel/power/Makefile
===================================================================
--- linux-2.6.orig/kernel/power/Makefile
+++ linux-2.6/kernel/power/Makefile
@@ -7,6 +7,5 @@ obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \
block_io.o
-obj-$(CONFIG_SUSPEND_NVS) += nvs.o
obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/5] ACPI / PM: Update file information and the list of includes in nvs.c
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
2011-01-07 0:42 ` [PATCH 1/5] PM: Fix oops in suspend/hibernate code related to failing ioremap() Rafael J. Wysocki
2011-01-07 0:43 ` [PATCH 2/5] PM / ACPI: Move NVS saving and restoring code to drivers/acpi Rafael J. Wysocki
@ 2011-01-07 0:44 ` Rafael J. Wysocki
2011-01-07 0:45 ` [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory() Rafael J. Wysocki
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:44 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
From: Rafael J. Wysocki <rjw@sisk.pl>
The file information and the list of include in drivers/acpi/nvs.c
are outdated, so update them.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/acpi/nvs.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: linux-2.6/drivers/acpi/nvs.c
===================================================================
--- linux-2.6.orig/drivers/acpi/nvs.c
+++ linux-2.6/drivers/acpi/nvs.c
@@ -1,7 +1,7 @@
/*
- * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
+ * nvs.c - Routines for saving and restoring ACPI NVS memory region
*
- * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*
* This file is released under the GPLv2.
*/
@@ -11,7 +11,7 @@
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/suspend.h>
+#include <linux/acpi.h>
/*
* Platforms, like ACPI, may want us to save some memory used by them during
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory()
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
` (2 preceding siblings ...)
2011-01-07 0:44 ` [PATCH 3/5] ACPI / PM: Update file information and the list of includes in nvs.c Rafael J. Wysocki
@ 2011-01-07 0:45 ` Rafael J. Wysocki
2011-01-07 5:52 ` Len Brown
2011-01-07 0:46 ` [PATCH 5/5] ACPI: Use ioremap_cache() Rafael J. Wysocki
2011-01-07 6:08 ` [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Len Brown
5 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:45 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
From: Rafael J. Wysocki <rjw@sisk.pl>
It turns out that the NVS memory region that suspend_nvs_save()
attempts to map has been already mapped by acpi_os_map_memory(), so
suspend_nvs_save() should better use acpi_os_map_memory() for mapping
memory to avoid conflicts.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/acpi/nvs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: linux-2.6/drivers/acpi/nvs.c
===================================================================
--- linux-2.6.orig/drivers/acpi/nvs.c
+++ linux-2.6/drivers/acpi/nvs.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/acpi.h>
+#include <acpi/acpiosxf.h>
/*
* Platforms, like ACPI, may want us to save some memory used by them during
@@ -113,7 +114,8 @@ int suspend_nvs_save(void)
list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
- entry->kaddr = ioremap(entry->phys_start, entry->size);
+ entry->kaddr = acpi_os_map_memory(entry->phys_start,
+ entry->size);
if (!entry->kaddr) {
suspend_nvs_free();
return -ENOMEM;
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/5] ACPI: Use ioremap_cache()
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
` (3 preceding siblings ...)
2011-01-07 0:45 ` [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory() Rafael J. Wysocki
@ 2011-01-07 0:46 ` Rafael J. Wysocki
2011-01-07 6:08 ` [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Len Brown
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2011-01-07 0:46 UTC (permalink / raw)
To: Len Brown; +Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
From: Len Brown <len.brown@intel.com>
Although the temporary boot-time ACPI table mappings
were set up with CPU caching enabled, the permanent table
mappings and AML run-time region memory accesses were
set up with ioremap(), which on x86 is a synonym for
ioremap_nocache().
Changing this to ioremap_cache() improves performance as
seen when accessing the tables via acpidump,
or /sys/firmware/acpi/tables. It should also improve
AML run-time performance.
No change on ia64.
Reported-by: Jack Steiner <steiner@sgi.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
arch/ia64/include/asm/io.h | 5 +++++
drivers/acpi/osl.c | 6 +++---
2 files changed, 8 insertions(+), 3 deletions(-)
Index: linux-2.6/arch/ia64/include/asm/io.h
===================================================================
--- linux-2.6.orig/arch/ia64/include/asm/io.h
+++ linux-2.6/arch/ia64/include/asm/io.h
@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (u
extern void iounmap (volatile void __iomem *addr);
extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
+static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
+{
+ return ioremap(phys_addr, size);
+}
+
/*
* String version of IO memory access ops:
Index: linux-2.6/drivers/acpi/osl.c
===================================================================
--- linux-2.6.orig/drivers/acpi/osl.c
+++ linux-2.6/drivers/acpi/osl.c
@@ -320,7 +320,7 @@ acpi_os_map_memory(acpi_physical_address
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = ioremap(pg_off, pg_sz);
+ virt = ioremap_cache(pg_off, pg_sz);
if (!virt) {
kfree(map);
return NULL;
@@ -642,7 +642,7 @@ acpi_os_read_memory(acpi_physical_addres
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
- virt_addr = ioremap(phys_addr, size);
+ virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
if (!value)
@@ -678,7 +678,7 @@ acpi_os_write_memory(acpi_physical_addre
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
- virt_addr = ioremap(phys_addr, size);
+ virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory()
2011-01-07 0:45 ` [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory() Rafael J. Wysocki
@ 2011-01-07 5:52 ` Len Brown
2011-01-07 6:02 ` Len Brown
0 siblings, 1 reply; 9+ messages in thread
From: Len Brown @ 2011-01-07 5:52 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
my arrandale laptop took multiple OOPS on resume after this patch.
...
[ 62.718661] PM: resume of devices complete after 515.721 msecs
[ 62.719761] PM: Finishing wakeup.
[ 62.719764] Restarting tasks ... done.
[ 62.721490] video LNXVIDEO:00: Restoring backlight state
[ 62.721681] BUG: unable to handle kernel paging request at
ffffc90000024320
[ 62.723443] IP: [<ffffffff81233e0e>]
acpi_ex_system_memory_space_handler+0x1b2/0x22a
[ 62.725357] PGD 7481c067 PUD 7481d067 PMD 7481e067 PTE 0
[ 62.726818] Oops: 0000 [#1] SMP
[ 62.727683] last sysfs file:
/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/PNP0C0A:00/power_supply/BAT0/charge_full
[ 62.730167] CPU 2
[ 62.730649] Modules linked in: fbcon font bitblit softcursor
acpi_cpufreq mperf snd_hda_codec_realtek i915 snd_hda_intel snd_hda_codec
drm_kms_helper snd_seq snd_seq_device snd_pcm drm atl1e i2c_algo_bit
snd_timer ehci_hcd cfbcopyarea cfbimgblt cfbfillrect snd_page_alloc wmi
rtc_cmos classmate_laptop video ac [last unloaded: scsi_wait_scan]
[ 62.739301]
[ 62.739670] Pid: 2589, comm: bash Not tainted
2.6.37-00004-gb4a017b-dirty #89 To be filled by O.E.M./Spring Peak
[ 62.742119] RIP: 0010:[<ffffffff81233e0e>] [<ffffffff81233e0e>]
acpi_ex_system_memory_space_handler+0x1b2/0x22a
[ 62.744626] RSP: 0018:ffff8800681ef638 EFLAGS: 00010246
[ 62.745910] RAX: 000000000000000c RBX: ffff8800736d4718 RCX:
ffffffff81473f00
[ 62.747629] RDX: ffffffff81473f60 RSI: 00000000000000c7 RDI:
0000000000000004
[ 62.749341] RBP: ffff8800681ef698 R08: 0000000000000080 R09:
ffffffff815f4847
[ 62.751047] R10: ffff8800748ac928 R11: 000000000000002d R12:
ffffc90000024320
[ 62.752759] R13: ffff8800681ef8a0 R14: 0000000000000000 R15:
0000000000000008
[ 62.754472] FS: 00007f827dae5700(0000) GS:ffff880077300000(0000)
knlGS:0000000000000000
[ 62.756412] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 62.757792] CR2: ffffc90000024320 CR3: 00000000742ec000 CR4:
00000000000006e0
[ 62.759501] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 62.761210] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[ 62.762924] Process bash (pid: 2589, threadinfo ffff8800681ee000, task
ffff8800673ce550)
[ 62.764861] Stack:
[ 62.765345] ffff880000000008 0000000000000000 0000000000000000
0000000077611320
[ 62.767293] ffff8800681ef6c8 00000000812311d3 ffffffff00000000
ffff8800748aaf78
[ 62.769237] ffff8800748d19d8 0000000000000308 ffff8800748aaf18
ffffffff81233c5c
[ 62.771184] Call Trace:
[ 62.771779] [<ffffffff81233c5c>] ?
acpi_ex_system_memory_space_handler+0x0/0x22a
[ 62.773577] [<ffffffff8122b012>]
acpi_ev_address_space_dispatch+0x1d2/0x221
[ 62.775270] [<ffffffff81233c5c>] ?
acpi_ex_system_memory_space_handler+0x0/0x22a
[ 62.777068] [<ffffffff81231508>] ?
acpi_ex_write_with_update_rule+0x12c/0x13c
[ 62.778802] [<ffffffff81230c8f>] acpi_ex_access_region+0x28b/0x316
[ 62.780309] [<ffffffff8123101d>] acpi_ex_field_datum_io+0xfa/0x2bd
[ 62.781817] [<ffffffff810bc21f>] ? kmem_cache_alloc+0xb3/0x139
[ 62.783240] [<ffffffff812312b0>] acpi_ex_extract_from_field+0xd0/0x1fc
[ 62.784829] [<ffffffff8122f3a0>]
acpi_ex_read_data_from_field+0x1b8/0x1ed
[ 62.786483] [<ffffffff81235b33>]
acpi_ex_resolve_node_to_value+0x223/0x2b4
[ 62.788155] [<ffffffff8122a3dd>] ? acpi_ds_obj_stack_push+0xae/0xb9
[ 62.789679] [<ffffffff81230081>] acpi_ex_resolve_to_value+0x275/0x2ba
[ 62.791247] [<ffffffff81228ff7>] acpi_ds_evaluate_name_path+0x7b/0xf8
[ 62.792816] [<ffffffff8123d7e6>] ?
acpi_ps_get_next_namepath+0x73/0x24a
[ 62.794423] [<ffffffff81227137>] acpi_ds_exec_end_op+0x9b/0x578
[ 62.795866] [<ffffffff8123ef2b>] acpi_ps_parse_loop+0x88a/0xa53
[ 62.797308] [<ffffffff81227fc3>] ?
acpi_ds_call_control_method+0x207/0x254
[ 62.798979] [<ffffffff8123e110>] acpi_ps_parse_aml+0x104/0x3c4
[ 62.800401] [<ffffffff8123f8bc>] acpi_ps_execute_method+0x20f/0x2f3
[ 62.862303] [<ffffffff8123981f>] acpi_ns_evaluate+0x18b/0x2d2
[ 62.923160] [<ffffffff812390d4>] acpi_evaluate_object+0x1fc/0x33e
[ 62.983240] [<ffffffff811efda1>] ? vsnprintf+0x83/0x44c
[ 63.043088] [<ffffffffa0006977>]
acpi_video_device_lcd_set_level+0x53/0xe2 [video]
[ 63.102572] [<ffffffffa0006b03>] acpi_video_set_brightness+0x2d/0x31
[video]
[ 63.160697] [<ffffffffa0006b6a>] acpi_video_resume+0x63/0x79 [video]
[ 63.216439] [<ffffffff8142943c>] notifier_call_chain+0x32/0x5e
[ 63.269749] [<ffffffff81056dd1>]
__blocking_notifier_call_chain+0x46/0x5b
[ 63.321147] [<ffffffff81056df5>] blocking_notifier_call_chain+0xf/0x11
[ 63.373135] [<ffffffff810692e7>] pm_notifier_call_chain+0x15/0x2e
[ 63.424093] [<ffffffff81069aea>] enter_state+0xfd/0x129
[ 63.473546] [<ffffffff81069202>] state_store+0xa9/0xc6
[ 63.521483] [<ffffffff811e9a9b>] kobj_attr_store+0x17/0x19
[ 63.568993] [<ffffffff8110c02d>] sysfs_write_file+0x10f/0x14b
[ 63.616221] [<ffffffff810bf4b3>] vfs_write+0xb0/0x12f
[ 63.663246] [<ffffffff810bf70f>] sys_write+0x45/0x6c
[ 63.709920] [<ffffffff8100203b>] system_call_fastpath+0x16/0x1b
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory()
2011-01-07 5:52 ` Len Brown
@ 2011-01-07 6:02 ` Len Brown
0 siblings, 0 replies; 9+ messages in thread
From: Len Brown @ 2011-01-07 6:02 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
> my arrandale laptop took multiple OOPS on resume after this patch.
This bit makes my laptop happy, so I'll add it to this patch.
thanks,
-Len
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index 8e7ab5e..54b6ab8 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -80,7 +80,7 @@ void suspend_nvs_free(void)
free_page((unsigned long)entry->data);
entry->data = NULL;
if (entry->kaddr) {
- iounmap(entry->kaddr);
+ acpi_os_unmap_memory(entry->kaddr, entry->size);
entry->kaddr = NULL;
}
}
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
` (4 preceding siblings ...)
2011-01-07 0:46 ` [PATCH 5/5] ACPI: Use ioremap_cache() Rafael J. Wysocki
@ 2011-01-07 6:08 ` Len Brown
5 siblings, 0 replies; 9+ messages in thread
From: Len Brown @ 2011-01-07 6:08 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: ACPI Devel Maling List, LKML, Linux-pm mailing list, Jiri Slaby
> Do you want me to take these patches to my tree or are you going to push them
I've included them in acpi-test, and will include in my .38 push.
thanks,
-Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-01-07 6:08 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-07 0:41 [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Rafael J. Wysocki
2011-01-07 0:42 ` [PATCH 1/5] PM: Fix oops in suspend/hibernate code related to failing ioremap() Rafael J. Wysocki
2011-01-07 0:43 ` [PATCH 2/5] PM / ACPI: Move NVS saving and restoring code to drivers/acpi Rafael J. Wysocki
2011-01-07 0:44 ` [PATCH 3/5] ACPI / PM: Update file information and the list of includes in nvs.c Rafael J. Wysocki
2011-01-07 0:45 ` [PATCH 4/5] ACPI / PM: Make suspend_nvs_save() use acpi_os_map_memory() Rafael J. Wysocki
2011-01-07 5:52 ` Len Brown
2011-01-07 6:02 ` Len Brown
2011-01-07 0:46 ` [PATCH 5/5] ACPI: Use ioremap_cache() Rafael J. Wysocki
2011-01-07 6:08 ` [PATCH 0/5] PM / ACPI: Fix problems with ACPI NVS saving related to using ioremap_cache() by ACPI Len Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox