| From dhobsong@igel.co.jp Mon Oct 29 00:53:17 2012 |
| From: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Date: Mon, 29 Oct 2012 16:50:52 +0900 |
| Subject: [PATCH v2 35/58] mm: cma: don't replace lowmem pages with highmem |
| To: greg@kroah.com, laurent.pinchart@ideasonboard.com, horms@verge.net.au |
| Cc: ltsi-dev@lists.linuxfoundation.org, dhobsong@igel.co.jp |
| Message-ID: <1351497075-32717-36-git-send-email-dhobsong@igel.co.jp> |
| |
| |
| From: Rabin Vincent <rabin@rab.in> |
| |
| The filesystem layer expects pages in the block device's mapping to not |
| be in highmem (the mapping's gfp mask is set in bdget()), but CMA can |
| currently replace lowmem pages with highmem pages, leading to crashes in |
| filesystem code such as the one below: |
| |
| Unable to handle kernel NULL pointer dereference at virtual address 00000400 |
| pgd = c0c98000 |
| [00000400] *pgd=00c91831, *pte=00000000, *ppte=00000000 |
| Internal error: Oops: 817 [#1] PREEMPT SMP ARM |
| CPU: 0 Not tainted (3.5.0-rc5+ #80) |
| PC is at __memzero+0x24/0x80 |
| ... |
| Process fsstress (pid: 323, stack limit = 0xc0cbc2f0) |
| Backtrace: |
| [<c010e3f0>] (ext4_getblk+0x0/0x180) from [<c010e58c>] (ext4_bread+0x1c/0x98) |
| [<c010e570>] (ext4_bread+0x0/0x98) from [<c0117944>] (ext4_mkdir+0x160/0x3bc) |
| r4:c15337f0 |
| [<c01177e4>] (ext4_mkdir+0x0/0x3bc) from [<c00c29e0>] (vfs_mkdir+0x8c/0x98) |
| [<c00c2954>] (vfs_mkdir+0x0/0x98) from [<c00c2a60>] (sys_mkdirat+0x74/0xac) |
| r6:00000000 r5:c152eb40 r4:000001ff r3:c14b43f0 |
| [<c00c29ec>] (sys_mkdirat+0x0/0xac) from [<c00c2ab8>] (sys_mkdir+0x20/0x24) |
| r6:beccdcf0 r5:00074000 r4:beccdbbc |
| [<c00c2a98>] (sys_mkdir+0x0/0x24) from [<c000e3c0>] (ret_fast_syscall+0x0/0x30) |
| |
| Fix this by replacing only highmem pages with highmem. |
| |
| Reported-by: Laura Abbott <lauraa@codeaurora.org> |
| Signed-off-by: Rabin Vincent <rabin@rab.in> |
| Acked-by: Michal Nazarewicz <mina86@mina86.com> |
| Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> |
| (cherry picked from commit 6a6dccba2fdc2a69f1f36b8f1c0acc8598e7221b) |
| |
| Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp> |
| Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| --- |
| mm/page_alloc.c | 7 ++++++- |
| 1 file changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/mm/page_alloc.c |
| +++ b/mm/page_alloc.c |
| @@ -5645,7 +5645,12 @@ static struct page * |
| __alloc_contig_migrate_alloc(struct page *page, unsigned long private, |
| int **resultp) |
| { |
| - return alloc_page(GFP_HIGHUSER_MOVABLE); |
| + gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE; |
| + |
| + if (PageHighMem(page)) |
| + gfp_mask |= __GFP_HIGHMEM; |
| + |
| + return alloc_page(gfp_mask); |
| } |
| |
| /* [start, end) must belong to a single zone. */ |