linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] MM: virtual address debug
@ 2008-06-12 11:56 Jiri Slaby
  2008-06-18 12:12 ` Ingo Molnar
  2008-06-18 12:51 ` [PATCH 1/1] " Nick Piggin
  0 siblings, 2 replies; 10+ messages in thread
From: Jiri Slaby @ 2008-06-12 11:56 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: tglx, hpa, linux-kernel, linux-mm, Jiri Slaby, Andi Kleen

Add some (configurable) expensive sanity checking to catch wrong address
translations on x86.

- create linux/mmdebug.h file to be able include this file in
  asm headers to not get unsolvable loops in header files
- __phys_addr on x86_32 became a function in ioremap.c since
  PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
  if declared in page_32.h
- add __phys_addr_const for initializing doublefault_tss.__cr3

Tested on 386, 386pae, x86_64 and x86_64 numa=fake=2.

Contains Andi's enable numa virtual address debug patch.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
---
 arch/x86/kernel/doublefault_32.c |    2 +-
 arch/x86/mm/ioremap.c            |   31 ++++++++++++++++++++++++-------
 include/asm-x86/mmzone_64.h      |    2 +-
 include/asm-x86/page_32.h        |    3 ++-
 include/linux/mm.h               |    7 +------
 include/linux/mmdebug.h          |   18 ++++++++++++++++++
 lib/Kconfig.debug                |    9 +++++++++
 mm/vmalloc.c                     |    5 +++++
 8 files changed, 61 insertions(+), 16 deletions(-)
 create mode 100644 include/linux/mmdebug.h

diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index a47798b..395acb1 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cacheline_aligned = {
 		.ds		= __USER_DS,
 		.fs		= __KERNEL_PERCPU,
 
-		.__cr3		= __pa(swapper_pg_dir)
+		.__cr3		= __phys_addr_const((unsigned long)swapper_pg_dir)
 	}
 };
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c0d4958..bd130d4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -24,18 +24,26 @@
 
 #ifdef CONFIG_X86_64
 
-unsigned long __phys_addr(unsigned long x)
+static inline int phys_addr_valid(unsigned long addr)
 {
-	if (x >= __START_KERNEL_map)
-		return x - __START_KERNEL_map + phys_base;
-	return x - PAGE_OFFSET;
+	return addr < (1UL << boot_cpu_data.x86_phys_bits);
 }
-EXPORT_SYMBOL(__phys_addr);
 
-static inline int phys_addr_valid(unsigned long addr)
+unsigned long __phys_addr(unsigned long x)
 {
-	return addr < (1UL << boot_cpu_data.x86_phys_bits);
+	if (x >= __START_KERNEL_map) {
+		x -= __START_KERNEL_map;
+		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
+		x += phys_base;
+	} else {
+		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+		x -= PAGE_OFFSET;
+		VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :
+					!phys_addr_valid(x));
+	}
+	return x;
 }
+EXPORT_SYMBOL(__phys_addr);
 
 #else
 
@@ -44,6 +52,15 @@ static inline int phys_addr_valid(unsigned long addr)
 	return 1;
 }
 
+unsigned long __phys_addr(unsigned long x)
+{
+	/* VMALLOC_* aren't constants; not available at the boot time */
+	VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING &&
+					is_vmalloc_addr((void *)x)));
+	return x - PAGE_OFFSET;
+}
+EXPORT_SYMBOL(__phys_addr);
+
 #endif
 
 int page_is_ram(unsigned long pagenr)
diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h
index 594bd0d..facde3e 100644
--- a/include/asm-x86/mmzone_64.h
+++ b/include/asm-x86/mmzone_64.h
@@ -7,7 +7,7 @@
 
 #ifdef CONFIG_NUMA
 
-#define VIRTUAL_BUG_ON(x)
+#include <linux/mmdebug.h>
 
 #include <asm/smp.h>
 
diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
index 50b33eb..bd9001b 100644
--- a/include/asm-x86/page_32.h
+++ b/include/asm-x86/page_32.h
@@ -72,7 +72,8 @@ typedef struct page *pgtable_t;
 #endif
 
 #ifndef __ASSEMBLY__
-#define __phys_addr(x)		((x) - PAGE_OFFSET)
+#define __phys_addr_const(x)	((x) - PAGE_OFFSET)
+extern unsigned long __phys_addr(unsigned long);
 #define __phys_reloc_hide(x)	RELOC_HIDE((x), 0)
 
 #ifdef CONFIG_FLATMEM
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 460128d..b898b49 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -7,6 +7,7 @@
 
 #include <linux/gfp.h>
 #include <linux/list.h>
+#include <linux/mmdebug.h>
 #include <linux/mmzone.h>
 #include <linux/rbtree.h>
 #include <linux/prio_tree.h>
@@ -220,12 +221,6 @@ struct inode;
  */
 #include <linux/page-flags.h>
 
-#ifdef CONFIG_DEBUG_VM
-#define VM_BUG_ON(cond) BUG_ON(cond)
-#else
-#define VM_BUG_ON(condition) do { } while(0)
-#endif
-
 /*
  * Methods to modify the page usage count.
  *
diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
new file mode 100644
index 0000000..860ed1a
--- /dev/null
+++ b/include/linux/mmdebug.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_MM_DEBUG_H
+#define LINUX_MM_DEBUG_H 1
+
+#include <linux/autoconf.h>
+
+#ifdef CONFIG_DEBUG_VM
+#define VM_BUG_ON(cond) BUG_ON(cond)
+#else
+#define VM_BUG_ON(cond) do { } while(0)
+#endif
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+#define VIRTUAL_BUG_ON(cond) BUG_ON(cond)
+#else
+#define VIRTUAL_BUG_ON(cond) do { } while(0)
+#endif
+
+#endif
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f9f210d..5f15fb8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -470,6 +470,15 @@ config DEBUG_VM
 
 	  If unsure, say N.
 
+config DEBUG_VIRTUAL
+	bool "Debug VM translations"
+	depends on DEBUG_KERNEL && X86
+	help
+	  Enable some costly sanity checks in virtual to page code. This can
+	  catch mistakes with virt_to_page() and friends.
+
+	  If unsure, say N.
+
 config DEBUG_WRITECOUNT
 	bool "Debug filesystem writers count"
 	depends on DEBUG_KERNEL
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 35f2938..cba7d27 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -180,6 +180,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 
+	/* XXX we might need to change this if we add VIRTUAL_BUG_ON for
+	 * architectures that do not vmalloc module space */
+	VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) &&
+			!is_module_address(addr));
+
 	if (!pgd_none(*pgd)) {
 		pud = pud_offset(pgd, addr);
 		if (!pud_none(*pud)) {
-- 
1.5.5.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-12 11:56 [PATCH 1/1] MM: virtual address debug Jiri Slaby
@ 2008-06-18 12:12 ` Ingo Molnar
  2008-06-18 13:59   ` Ingo Molnar
  2008-06-18 12:51 ` [PATCH 1/1] " Nick Piggin
  1 sibling, 1 reply; 10+ messages in thread
From: Ingo Molnar @ 2008-06-18 12:12 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen,
	the arch/x86 maintainers

* Jiri Slaby <jirislaby@gmail.com> wrote:

> Add some (configurable) expensive sanity checking to catch wrong address
> translations on x86.
> 
> - create linux/mmdebug.h file to be able include this file in
>   asm headers to not get unsolvable loops in header files
> - __phys_addr on x86_32 became a function in ioremap.c since
>   PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
>   if declared in page_32.h
> - add __phys_addr_const for initializing doublefault_tss.__cr3

applied, thanks Jiri. I have created a new tip/x86/mm-debug topic for 
this because the patch touches mm/vmalloc.c and other MM bits.

Andrew, is that fine for you, can we push it into linux-next via 
auto-x86-next if it passes testing?

	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-12 11:56 [PATCH 1/1] MM: virtual address debug Jiri Slaby
  2008-06-18 12:12 ` Ingo Molnar
@ 2008-06-18 12:51 ` Nick Piggin
  2008-06-18 13:41   ` Jiri Slaby
  1 sibling, 1 reply; 10+ messages in thread
From: Nick Piggin @ 2008-06-18 12:51 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen

On Thursday 12 June 2008 21:56, Jiri Slaby wrote:
> Add some (configurable) expensive sanity checking to catch wrong address
> translations on x86.
>
> - create linux/mmdebug.h file to be able include this file in
>   asm headers to not get unsolvable loops in header files
> - __phys_addr on x86_32 became a function in ioremap.c since
>   PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
>   if declared in page_32.h

Uh, I have to disagree with this. __phys_addr is used in some really
performance critical parts of the kernel, and the function calls are
free mindset is just wrong. Even for modern x86 CPUs, the function
call return might take 10 cycles or more when you include all costs.

And for something like this

#define __phys_addr(x)         ((x) - PAGE_OFFSET)

the code to call the function is probably bigger than inline generated
code anyway.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-18 12:51 ` [PATCH 1/1] " Nick Piggin
@ 2008-06-18 13:41   ` Jiri Slaby
  2008-06-18 14:01     ` Nick Piggin
  0 siblings, 1 reply; 10+ messages in thread
From: Jiri Slaby @ 2008-06-18 13:41 UTC (permalink / raw)
  To: Nick Piggin; +Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen

Nick Piggin napsal(a):
> On Thursday 12 June 2008 21:56, Jiri Slaby wrote:
>> Add some (configurable) expensive sanity checking to catch wrong address
>> translations on x86.
>>
>> - create linux/mmdebug.h file to be able include this file in
>>   asm headers to not get unsolvable loops in header files
>> - __phys_addr on x86_32 became a function in ioremap.c since
>>   PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
>>   if declared in page_32.h
> 
> Uh, I have to disagree with this. __phys_addr is used in some really
> performance critical parts of the kernel, and the function calls are
> free mindset is just wrong. Even for modern x86 CPUs, the function
> call return might take 10 cycles or more when you include all costs.
> 
> And for something like this
> 
> #define __phys_addr(x)         ((x) - PAGE_OFFSET)
> 
> the code to call the function is probably bigger than inline generated
> code anyway.

Thanks for comments, well, are you OK with __phys_addr being a function only 
on CONFIG_VIRTUAL_DEBUG?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-18 12:12 ` Ingo Molnar
@ 2008-06-18 13:59   ` Ingo Molnar
  2008-06-18 14:11     ` Jiri Slaby
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Ingo Molnar @ 2008-06-18 13:59 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen,
	the arch/x86 maintainers, Mike Travis

* Ingo Molnar <mingo@elte.hu> wrote:

> 
> * Jiri Slaby <jirislaby@gmail.com> wrote:
> 
> > Add some (configurable) expensive sanity checking to catch wrong address
> > translations on x86.
> > 
> > - create linux/mmdebug.h file to be able include this file in
> >   asm headers to not get unsolvable loops in header files
> > - __phys_addr on x86_32 became a function in ioremap.c since
> >   PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
> >   if declared in page_32.h
> > - add __phys_addr_const for initializing doublefault_tss.__cr3
> 
> applied, thanks Jiri. I have created a new tip/x86/mm-debug topic for 
> this because the patch touches mm/vmalloc.c and other MM bits.

-tip testing triggered an early boot crash and i have bisected it down 
to your patch. The crash:

No NUMA configuration found
Faking a node at 0000000000000000-000000003fff0000
Entering add_active_range(0, 0, 159) 0 entries of 25600 used
Entering add_active_range(0, 256, 262128) 1 entries of 25600 used
Bootmem setup node 0 0000000000000000-000000003fff0000
  NODE_DATA [000000000000a000 - 000000000003dfff]
PANIC: early exception 06 rip 10:ffffffff80ba7531 error 0 cr2 f06f53
Pid: 0, comm: swapper Not tainted 2.6.26-rc6 #7709

Call Trace:
 [<ffffffff80b9c196>] early_idt_handler+0x56/0x6a
 [<ffffffff80ba7531>] setup_node_bootmem+0x12a/0x2d4
 [<ffffffff80ba7505>] setup_node_bootmem+0xfe/0x2d4
 [<ffffffff80b9dd73>] setup_arch+0x2a2/0x3e7
 [<ffffffff8024e858>] clockevents_register_notifier+0x2d/0x31
 [<ffffffff80b9cb5d>] start_kernel+0x8d/0x30a
 [<ffffffff80b9f87d>] reserve_early+0x16/0xad
 [<ffffffff80b9c35f>] x86_64_start_kernel+0x16d/0x174

RIP 0x10

the config is at:

  http://redhat.com/~mingo/misc/config-Wed_Jun_18_14_51_18_CEST_2008.bad

	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-18 13:41   ` Jiri Slaby
@ 2008-06-18 14:01     ` Nick Piggin
  0 siblings, 0 replies; 10+ messages in thread
From: Nick Piggin @ 2008-06-18 14:01 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen

On Wednesday 18 June 2008 23:41, Jiri Slaby wrote:

> Thanks for comments, well, are you OK with __phys_addr being a function
> only on CONFIG_VIRTUAL_DEBUG?

Yes

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-18 13:59   ` Ingo Molnar
@ 2008-06-18 14:11     ` Jiri Slaby
  2008-06-18 16:11     ` Jiri Slaby
  2008-06-18 18:35     ` [PATCH v2] " Jiri Slaby
  2 siblings, 0 replies; 10+ messages in thread
From: Jiri Slaby @ 2008-06-18 14:11 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen,
	the arch/x86 maintainers, Mike Travis

Ingo Molnar napsal(a):
> * Ingo Molnar <mingo@elte.hu> wrote:
> 
>> * Jiri Slaby <jirislaby@gmail.com> wrote:
>>
>>> Add some (configurable) expensive sanity checking to catch wrong address
>>> translations on x86.
>>>
>>> - create linux/mmdebug.h file to be able include this file in
>>>   asm headers to not get unsolvable loops in header files
>>> - __phys_addr on x86_32 became a function in ioremap.c since
>>>   PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined
>>>   if declared in page_32.h
>>> - add __phys_addr_const for initializing doublefault_tss.__cr3
>> applied, thanks Jiri. I have created a new tip/x86/mm-debug topic for 
>> this because the patch touches mm/vmalloc.c and other MM bits.
> 
> -tip testing triggered an early boot crash and i have bisected it down 
> to your patch. The crash:
> 
> No NUMA configuration found
> Faking a node at 0000000000000000-000000003fff0000
> Entering add_active_range(0, 0, 159) 0 entries of 25600 used
> Entering add_active_range(0, 256, 262128) 1 entries of 25600 used
> Bootmem setup node 0 0000000000000000-000000003fff0000
>   NODE_DATA [000000000000a000 - 000000000003dfff]
> PANIC: early exception 06 rip 10:ffffffff80ba7531 error 0 cr2 f06f53

Expception 06 is an invalid opcode. This is maybe a false positive, probably 
a mistake in phys_to_nid, I'll look into that, thanks.

> Pid: 0, comm: swapper Not tainted 2.6.26-rc6 #7709
> 
> Call Trace:
>  [<ffffffff80b9c196>] early_idt_handler+0x56/0x6a
>  [<ffffffff80ba7531>] setup_node_bootmem+0x12a/0x2d4
>  [<ffffffff80ba7505>] setup_node_bootmem+0xfe/0x2d4
>  [<ffffffff80b9dd73>] setup_arch+0x2a2/0x3e7
>  [<ffffffff8024e858>] clockevents_register_notifier+0x2d/0x31
>  [<ffffffff80b9cb5d>] start_kernel+0x8d/0x30a
>  [<ffffffff80b9f87d>] reserve_early+0x16/0xad
>  [<ffffffff80b9c35f>] x86_64_start_kernel+0x16d/0x174
> 
> RIP 0x10

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/1] MM: virtual address debug
  2008-06-18 13:59   ` Ingo Molnar
  2008-06-18 14:11     ` Jiri Slaby
@ 2008-06-18 16:11     ` Jiri Slaby
  2008-06-18 18:35     ` [PATCH v2] " Jiri Slaby
  2 siblings, 0 replies; 10+ messages in thread
From: Jiri Slaby @ 2008-06-18 16:11 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Ingo Molnar, tglx, hpa, linux-kernel, linux-mm, Andi Kleen,
	the arch/x86 maintainers, Mike Travis, nickpiggin

Ingo Molnar napsal(a):
> No NUMA configuration found
> Faking a node at 0000000000000000-000000003fff0000
> Entering add_active_range(0, 0, 159) 0 entries of 25600 used
> Entering add_active_range(0, 256, 262128) 1 entries of 25600 used
> Bootmem setup node 0 0000000000000000-000000003fff0000
>   NODE_DATA [000000000000a000 - 000000000003dfff]
> PANIC: early exception 06 rip 10:ffffffff80ba7531 error 0 cr2 f06f53
> Pid: 0, comm: swapper Not tainted 2.6.26-rc6 #7709
> 
> Call Trace:
>  [<ffffffff80b9c196>] early_idt_handler+0x56/0x6a
>  [<ffffffff80ba7531>] setup_node_bootmem+0x12a/0x2d4

Hmm, it's at
nid = phys_to_nid(nodedata_phys);
and
VIRTUAL_BUG_ON((addr >> memnode_shift) >= memnodemapsize);
triggers. Apparently memnodemapsize is not available for real numas. Going 
to remove the test and respin the patch with Nick's comment applied.

Thanks.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] MM: virtual address debug
  2008-06-18 13:59   ` Ingo Molnar
  2008-06-18 14:11     ` Jiri Slaby
  2008-06-18 16:11     ` Jiri Slaby
@ 2008-06-18 18:35     ` Jiri Slaby
  2008-06-19 11:34       ` Ingo Molnar
  2 siblings, 1 reply; 10+ messages in thread
From: Jiri Slaby @ 2008-06-18 18:35 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: tglx, hpa, Mike Travis, Nick Piggin, x86, linux-kernel, linux-mm,
	Jiri Slaby, Andi Kleen

I've removed the test from phys_to_nid and made a function from __phys_addr
only when the debugging is enabled (on x86_32).
--

Add some (configurable) expensive sanity checking to catch wrong address
translations on x86.

- create linux/mmdebug.h file to be able include this file in
  asm headers to not get unsolvable loops in header files
- __phys_addr on x86_32 became a function (on DEBUG_VIRTUAL) in
  ioremap.c since PAGE_OFFSET, is_vmalloc_addr and VMALLOC_*
  non-constasts are undefined if declared in page_32.h
- add __phys_addr_const for initializing doublefault_tss.__cr3 (x86_32)
- remove "(addr >> memnode_shift) >= memnodemapsize" test from phys_to_nid
  since the memnodemapsize is not available on non-fake numas

Tested on 386, 386pae, x86_64 and x86_64 numa=fake=2.

Contains Andi's enable numa virtual address debug patch.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
---
 arch/x86/kernel/doublefault_32.c |    2 +-
 arch/x86/mm/ioremap.c            |   33 ++++++++++++++++++++++++++-------
 include/asm-x86/mmzone_64.h      |    3 +--
 include/asm-x86/page_32.h        |    5 +++++
 include/linux/mm.h               |    7 +------
 include/linux/mmdebug.h          |   18 ++++++++++++++++++
 lib/Kconfig.debug                |    9 +++++++++
 mm/vmalloc.c                     |    5 +++++
 8 files changed, 66 insertions(+), 16 deletions(-)
 create mode 100644 include/linux/mmdebug.h

diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index a47798b..395acb1 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -66,6 +66,6 @@ struct tss_struct doublefault_tss __cacheline_aligned = {
 		.ds		= __USER_DS,
 		.fs		= __KERNEL_PERCPU,
 
-		.__cr3		= __pa(swapper_pg_dir)
+		.__cr3		= __phys_addr_const((unsigned long)swapper_pg_dir)
 	}
 };
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index c0d4958..f673121 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -24,18 +24,26 @@
 
 #ifdef CONFIG_X86_64
 
-unsigned long __phys_addr(unsigned long x)
+static inline int phys_addr_valid(unsigned long addr)
 {
-	if (x >= __START_KERNEL_map)
-		return x - __START_KERNEL_map + phys_base;
-	return x - PAGE_OFFSET;
+	return addr < (1UL << boot_cpu_data.x86_phys_bits);
 }
-EXPORT_SYMBOL(__phys_addr);
 
-static inline int phys_addr_valid(unsigned long addr)
+unsigned long __phys_addr(unsigned long x)
 {
-	return addr < (1UL << boot_cpu_data.x86_phys_bits);
+	if (x >= __START_KERNEL_map) {
+		x -= __START_KERNEL_map;
+		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
+		x += phys_base;
+	} else {
+		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+		x -= PAGE_OFFSET;
+		VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :
+					!phys_addr_valid(x));
+	}
+	return x;
 }
+EXPORT_SYMBOL(__phys_addr);
 
 #else
 
@@ -44,6 +52,17 @@ static inline int phys_addr_valid(unsigned long addr)
 	return 1;
 }
 
+#ifdef CONFIG_DEBUG_VIRTUAL
+unsigned long __phys_addr(unsigned long x)
+{
+	/* VMALLOC_* aren't constants; not available at the boot time */
+	VIRTUAL_BUG_ON(x < PAGE_OFFSET || (system_state != SYSTEM_BOOTING &&
+					is_vmalloc_addr((void *)x)));
+	return x - PAGE_OFFSET;
+}
+EXPORT_SYMBOL(__phys_addr);
+#endif
+
 #endif
 
 int page_is_ram(unsigned long pagenr)
diff --git a/include/asm-x86/mmzone_64.h b/include/asm-x86/mmzone_64.h
index 594bd0d..5e3a6cb 100644
--- a/include/asm-x86/mmzone_64.h
+++ b/include/asm-x86/mmzone_64.h
@@ -7,7 +7,7 @@
 
 #ifdef CONFIG_NUMA
 
-#define VIRTUAL_BUG_ON(x)
+#include <linux/mmdebug.h>
 
 #include <asm/smp.h>
 
@@ -29,7 +29,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
 {
 	unsigned nid;
 	VIRTUAL_BUG_ON(!memnodemap);
-	VIRTUAL_BUG_ON((addr >> memnode_shift) >= memnodemapsize);
 	nid = memnodemap[addr >> memnode_shift];
 	VIRTUAL_BUG_ON(nid >= MAX_NUMNODES || !node_data[nid]);
 	return nid;
diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
index 50b33eb..4510f21 100644
--- a/include/asm-x86/page_32.h
+++ b/include/asm-x86/page_32.h
@@ -72,7 +72,12 @@ typedef struct page *pgtable_t;
 #endif
 
 #ifndef __ASSEMBLY__
+#define __phys_addr_const(x)	((x) - PAGE_OFFSET)
+#ifdef CONFIG_DEBUG_VIRTUAL
+extern unsigned long __phys_addr(unsigned long);
+#else
 #define __phys_addr(x)		((x) - PAGE_OFFSET)
+#endif
 #define __phys_reloc_hide(x)	RELOC_HIDE((x), 0)
 
 #ifdef CONFIG_FLATMEM
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 460128d..b898b49 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -7,6 +7,7 @@
 
 #include <linux/gfp.h>
 #include <linux/list.h>
+#include <linux/mmdebug.h>
 #include <linux/mmzone.h>
 #include <linux/rbtree.h>
 #include <linux/prio_tree.h>
@@ -220,12 +221,6 @@ struct inode;
  */
 #include <linux/page-flags.h>
 
-#ifdef CONFIG_DEBUG_VM
-#define VM_BUG_ON(cond) BUG_ON(cond)
-#else
-#define VM_BUG_ON(condition) do { } while(0)
-#endif
-
 /*
  * Methods to modify the page usage count.
  *
diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
new file mode 100644
index 0000000..860ed1a
--- /dev/null
+++ b/include/linux/mmdebug.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_MM_DEBUG_H
+#define LINUX_MM_DEBUG_H 1
+
+#include <linux/autoconf.h>
+
+#ifdef CONFIG_DEBUG_VM
+#define VM_BUG_ON(cond) BUG_ON(cond)
+#else
+#define VM_BUG_ON(cond) do { } while(0)
+#endif
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+#define VIRTUAL_BUG_ON(cond) BUG_ON(cond)
+#else
+#define VIRTUAL_BUG_ON(cond) do { } while(0)
+#endif
+
+#endif
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f9f210d..5f15fb8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -470,6 +470,15 @@ config DEBUG_VM
 
 	  If unsure, say N.
 
+config DEBUG_VIRTUAL
+	bool "Debug VM translations"
+	depends on DEBUG_KERNEL && X86
+	help
+	  Enable some costly sanity checks in virtual to page code. This can
+	  catch mistakes with virt_to_page() and friends.
+
+	  If unsure, say N.
+
 config DEBUG_WRITECOUNT
 	bool "Debug filesystem writers count"
 	depends on DEBUG_KERNEL
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 35f2938..cba7d27 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -180,6 +180,11 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 
+	/* XXX we might need to change this if we add VIRTUAL_BUG_ON for
+	 * architectures that do not vmalloc module space */
+	VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) &&
+			!is_module_address(addr));
+
 	if (!pgd_none(*pgd)) {
 		pud = pud_offset(pgd, addr);
 		if (!pud_none(*pud)) {
-- 
1.5.5.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] MM: virtual address debug
  2008-06-18 18:35     ` [PATCH v2] " Jiri Slaby
@ 2008-06-19 11:34       ` Ingo Molnar
  0 siblings, 0 replies; 10+ messages in thread
From: Ingo Molnar @ 2008-06-19 11:34 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Ingo Molnar, tglx, hpa, Mike Travis, Nick Piggin, x86,
	linux-kernel, linux-mm, Andi Kleen

* Jiri Slaby <jirislaby@gmail.com> wrote:

> I've removed the test from phys_to_nid and made a function from __phys_addr
> only when the debugging is enabled (on x86_32).

applied to tip/x86/mm-debug for more testing. Please send future updates 
as a delta against that branch, it includes a cleanup patch as well. 
Thanks,

	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-06-19 11:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-12 11:56 [PATCH 1/1] MM: virtual address debug Jiri Slaby
2008-06-18 12:12 ` Ingo Molnar
2008-06-18 13:59   ` Ingo Molnar
2008-06-18 14:11     ` Jiri Slaby
2008-06-18 16:11     ` Jiri Slaby
2008-06-18 18:35     ` [PATCH v2] " Jiri Slaby
2008-06-19 11:34       ` Ingo Molnar
2008-06-18 12:51 ` [PATCH 1/1] " Nick Piggin
2008-06-18 13:41   ` Jiri Slaby
2008-06-18 14:01     ` Nick Piggin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox