mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Ingo Molnar <mingo@elte.hu>
Cc: Pavel Machek <pavel@suse.cz>, Andi Kleen <andi@firstfloor.org>,
	kernel list <linux-kernel@vger.kernel.org>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	pm list <linux-pm@lists.linux-foundation.org>
Subject: [PATCH] x86: Hibernate: Fix breakage on x86_32 with CONFIG_NUMA set (was: Re: CONFIG_NUMA breaks hibernation on x86-32 with PAE)
Date: Wed, 12 Nov 2008 23:22:35 +0100	[thread overview]
Message-ID: <200811122322.36781.rjw@sisk.pl> (raw)
In-Reply-To: <200811122257.50998.rjw@sisk.pl>

From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: x86: Hibernate: Fix breakage on x86_32 with CONFIG_NUMA set

The NUMA code on x86_32 creates special memory mapping that allows
each node's pgdat to be located in this node's memory.  For this
purpose it allocates a memory area at the end of each node's memory
and maps this area so that it is accessible with virtual addresses
belonging to low memory.  As a result, if there is high memory,
these NUMA-allocated areas are physically located in high memory,
although they are mapped to low memory addresses.

Our hibernation code does not take that into account and for this
reason hibernation fails on all x86_32 systems with CONFIG_NUMA=y and
with high memory present.  Fix this by adding a special mapping for
the NUMA-allocated memory areas to the temporary page tables created
during the last phase of resume.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Pavel Machek <pavel@suse.cz>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
---
 arch/x86/include/asm/mmzone_32.h |    4 ++++
 arch/x86/mm/numa_32.c            |   35 +++++++++++++++++++++++++++++++++++
 arch/x86/power/hibernate_32.c    |    4 ++++
 3 files changed, 43 insertions(+)

Index: linux-2.6/arch/x86/power/hibernate_32.c
===================================================================
--- linux-2.6.orig/arch/x86/power/hibernate_32.c
+++ linux-2.6/arch/x86/power/hibernate_32.c
@@ -12,6 +12,7 @@
 #include <asm/system.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/mmzone.h>
 
 /* Defined in hibernate_asm_32.S */
 extern int restore_image(void);
@@ -127,6 +128,9 @@ static int resume_physical_mapping_init(
 			}
 		}
 	}
+
+	resume_map_numa_kva(pgd_base);
+
 	return 0;
 }
 
Index: linux-2.6/arch/x86/mm/numa_32.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/numa_32.c
+++ linux-2.6/arch/x86/mm/numa_32.c
@@ -222,6 +222,41 @@ static void __init remap_numa_kva(void)
 	}
 }
 
+#ifdef CONFIG_HIBERNATION
+/**
+ * resume_map_numa_kva - add KVA mapping to the temporary page tables created
+ *                       during resume from hibernation
+ * @pgd_base - temporary resume page directory
+ */
+void resume_map_numa_kva(pgd_t *pgd_base)
+{
+	int node;
+
+	for_each_online_node(node) {
+		unsigned long start_va, start_pfn, size, pfn;
+
+		start_va = (unsigned long)node_remap_start_vaddr[node];
+		start_pfn = node_remap_start_pfn[node];
+		size = node_remap_size[node];
+
+		printk(KERN_DEBUG "%s: node %d\n", __FUNCTION__, node);
+
+		for (pfn = 0; pfn < size; pfn += PTRS_PER_PTE) {
+			unsigned long vaddr = start_va + (pfn << PAGE_SHIFT);
+			pgd_t *pgd = pgd_base + pgd_index(vaddr);
+			pud_t *pud = pud_offset(pgd, vaddr);
+			pmd_t *pmd = pmd_offset(pud, vaddr);
+
+			set_pmd(pmd, pfn_pmd(start_pfn + pfn,
+						PAGE_KERNEL_LARGE_EXEC));
+
+			printk(KERN_DEBUG "%s: %08lx -> pfn %08lx\n",
+				__FUNCTION__, vaddr, start_pfn + pfn);
+		}
+	}
+}
+#endif
+
 static unsigned long calculate_numa_remap_pages(void)
 {
 	int nid;
Index: linux-2.6/arch/x86/include/asm/mmzone_32.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/mmzone_32.h
+++ linux-2.6/arch/x86/include/asm/mmzone_32.h
@@ -34,10 +34,14 @@ static inline void get_memcfg_numa(void)
 
 extern int early_pfn_to_nid(unsigned long pfn);
 
+extern void resume_map_numa_kva(pgd_t *pgd);
+
 #else /* !CONFIG_NUMA */
 
 #define get_memcfg_numa get_memcfg_numa_flat
 
+static inline void resume_map_numa_kva(pgd_t *pgd) {}
+
 #endif /* CONFIG_NUMA */
 
 #ifdef CONFIG_DISCONTIGMEM

  reply	other threads:[~2008-11-12 22:18 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-09 14:07 CONFIG_NUMA breaks hibernation on x86-32 with PAE Pavel Machek
2008-11-10  7:52 ` Ingo Molnar
2008-11-10  7:55   ` Pavel Machek
2008-11-10  8:04     ` Ingo Molnar
2008-11-10  8:28       ` Pavel Machek
2008-11-10 12:53         ` Ingo Molnar
2008-11-10 18:05           ` Andi Kleen
2008-11-10 18:33             ` Rafael J. Wysocki
2008-11-10 19:07               ` Andi Kleen
2008-11-10 12:55       ` Andi Kleen
2008-11-10 18:28         ` Rafael J. Wysocki
2008-11-11 10:30           ` Pavel Machek
2008-11-11 14:17             ` Rafael J. Wysocki
2008-11-11 10:45           ` Pavel Machek
2008-11-11 14:20             ` Rafael J. Wysocki
2008-11-11 15:03               ` Pavel Machek
2008-11-11 16:47                 ` Rafael J. Wysocki
2008-11-12 10:49                   ` Pavel Machek
2008-11-12 21:57                     ` Rafael J. Wysocki
2008-11-12 22:22                       ` Rafael J. Wysocki [this message]
2008-11-12 22:26                         ` [PATCH] x86: Make NUMA on 32-bit depend on EXPERIMENTAL again Rafael J. Wysocki
2008-11-12 22:29                           ` Ingo Molnar
2008-11-12 22:29                         ` [PATCH] x86: Hibernate: Fix breakage on x86_32 with CONFIG_NUMA set (was: Re: CONFIG_NUMA breaks hibernation on x86-32 with PAE) Ingo Molnar
2008-11-10  8:24     ` CONFIG_NUMA breaks hibernation on x86-32 with PAE KAMEZAWA Hiroyuki
2008-11-10  8:27       ` Pavel Machek
2008-11-10  8:28       ` Ingo Molnar
2008-11-10 18:23         ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200811122322.36781.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=mingo@elte.hu \
    --cc=pavel@suse.cz \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®