* [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