[tip:kmemcheck] kmemcheck: fix split_page() of the page allocator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  b542b8f29ca47d0b4174ae2f13d5567181f59d5e
Gitweb:     http://git.kernel.org/tip/b542b8f29ca47d0b4174ae2f13d5567181f59d5e
Author:     Vegard Nossum <vegard.nossum@xxxxxxxxx>
AuthorDate: Sat, 28 Feb 2009 08:48:28 +0100
Commit:     Vegard Nossum <vegard.nossum@xxxxxxxxx>
CommitDate: Sat, 28 Feb 2009 08:48:28 +0100

kmemcheck: fix split_page() of the page allocator

I'd overlooked this API detail: a split_page() that turns a single
order-n page allocation into n order-1 page allocations. We need a
hook for kmemcheck here, because we need to split the shadow pages
too.

It fixes this oops:

kernel BUG at include/linux/mm.h:253!
invalid opcode: 0000 [#1] SMP
last sysfs file:
CPU 0
Pid: 1, comm: swapper Tainted: G        W  2.6.29-rc6-00888-g42f6e3e-dirty #340 945P-A
RIP: 0010:[<ffffffff802c2201>]  [<ffffffff802c2201>] __free_pages+0x31/0x70
RSP: 0018:ffff88003f87fae0  EFLAGS: 00010202
RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000060
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff819c8c20
RBP: ffff88003f87fb00 R08: ffff880000000000 R09: 0000000000000000
R10: ffff88003dfff000 R11: 0000000000001000 R12: ffffe2000173d000
R13: 0000000000000000 R14: 0000000000380000 R15: 4000000000000000
FS:  0000000000000000(0000) GS:ffff880002701000(0000) knlGS:0000000000000000
CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: ffff88003ea66c00 CR3: 0000000000201000 CR4: 00000000000006a0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff4ff0 DR7: 0000000000000400
Process swapper (pid: 1, threadinfo ffff88003f87e000, task ffff88003f880000)
Stack:
 ffff88003f87fb00 ffffe20001755000 0000000000000001 0000000000000000
 ffff88003f87fb30 ffffffff802eebb3 ffff88003f880000 0000000000000000
 ffffe20001755000 0000000000000000 ffff88003f87fb80 ffffffff802c06dc
Call Trace:
 [<ffffffff802eebb3>] kmemcheck_free_shadow+0xb3/0xc0
 [<ffffffff802c06dc>] free_hot_cold_page+0x2c/0x2a0
 [<ffffffff802c09bb>] free_hot_page+0xb/0x10
 [<ffffffff802c223a>] __free_pages+0x6a/0x70
 [<ffffffff802c22b7>] free_pages+0x77/0x80
 [<ffffffff81aecadb>] alloc_large_system_hash+0x19b/0x29a
 [<ffffffff81b21f72>] tcp_init+0x196/0x379
 [<ffffffff81b2257d>] inet_init+0x14d/0x287
 [<ffffffff81b22430>] ? inet_init+0x0/0x287
 [<ffffffff8020904a>] do_one_initcall+0x3a/0x1c0
 [<ffffffff80238f76>] ? kmemcheck_show_addr+0xf6/0x100
 [<ffffffff80238fba>] ? kmemcheck_show_all+0x3a/0x60
 [<ffffffff802391d1>] ? kmemcheck_show+0x71/0xd0
 [<ffffffff80239742>] ? kmemcheck_fault+0x72/0x90
 [<ffffffff81006231>] ? pc87360_probe+0x7d1/0xe83
 [<ffffffff8103930e>] ? trace_hardirqs_off_thunk+0x3a/0x3c
 [<ffffffff8103a1a0>] ? error_exit+0x30/0xb0
 [<ffffffff802a86b3>] ? register_irq_proc+0xd3/0xe0
 [<ffffffff80340000>] ? pagemap_pte_range+0xf0/0x250
 [<ffffffff81ad074b>] kernel_init+0x158/0x1b0

Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxx>


---
 mm/page_alloc.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2fdc4bb..5b0e676 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1058,6 +1058,14 @@ void split_page(struct page *page, unsigned int order)
 
 	VM_BUG_ON(PageCompound(page));
 	VM_BUG_ON(!page_count(page));
+
+	/*
+	 * Split shadow pages too, because free(page[0]) would
+	 * otherwise free the whole shadow.
+	 */
+	if (kmemcheck_page_is_tracked(page))
+		split_page(virt_to_page(page[0].shadow), order);
+
 	for (i = 1; i < (1 << order); i++)
 		set_page_refcounted(page + i);
 }
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux