public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [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