mm: fix crash when using XFS on loopback
Commit
8456a648cf44 ("slab: use struct page for slab management") causes
a crash in the LVM2 testsuite on PA-RISC (the crashing test is
fsadm.sh). The testsuite doesn't crash on 3.12, crashes on 3.13-rc1 and
later.
Bad Address (null pointer deref?): Code=15 regs=
000000413edd89a0 (Addr=
000006202224647d)
CPU: 3 PID: 24008 Comm: loop0 Not tainted 3.13.0-rc6 #5
task:
00000001bf3c0048 ti:
000000413edd8000 task.ti:
000000413edd8000
YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
PSW:
00001000000001101111100100001110 Not tainted
r00-03
000000ff0806f90e 00000000405c8de0 000000004013e6c0 000000413edd83f0
r04-07
00000000405a95e0 0000000000000200 00000001414735f0 00000001bf349e40
r08-11
0000000010fe3d10 0000000000000001 00000040829c7778 000000413efd9000
r12-15
0000000000000000 000000004060d800 0000000010fe3000 0000000010fe3000
r16-19
000000413edd82a0 00000041078ddbc0 0000000000000010 0000000000000001
r20-23
0008f3d0d83a8000 0000000000000000 00000040829c7778 0000000000000080
r24-27
00000001bf349e40 00000001bf349e40 202d66202224640d 00000000405a95e0
r28-31
202d662022246465 000000413edd88f0 000000413edd89a0 0000000000000001
sr00-03
000000000532c000 0000000000000000 0000000000000000 000000000532c000
sr04-07
0000000000000000 0000000000000000 0000000000000000 0000000000000000
IASQ:
0000000000000000 0000000000000000 IAOQ:
00000000401fe42c 00000000401fe430
IIR:
539c0030 ISR:
00000000202d6000 IOR:
000006202224647d
CPU: 3 CR30:
000000413edd8000 CR31:
0000000000000000
ORIG_R28:
00000000405a95e0
IAOQ[0]: vma_interval_tree_iter_first+0x14/0x48
IAOQ[1]: vma_interval_tree_iter_first+0x18/0x48
RP(r2): flush_dcache_page+0x128/0x388
Backtrace:
flush_dcache_page+0x128/0x388
lo_splice_actor+0x90/0x148 [loop]
splice_from_pipe_feed+0xc0/0x1d0
__splice_from_pipe+0xac/0xc0
lo_direct_splice_actor+0x1c/0x70 [loop]
splice_direct_to_actor+0xec/0x228
lo_receive+0xe4/0x298 [loop]
loop_thread+0x478/0x640 [loop]
kthread+0x134/0x168
end_fault_vector+0x20/0x28
xfs_setsize_buftarg+0x0/0x90 [xfs]
Kernel panic - not syncing: Bad Address (null pointer deref?)
Commit
8456a648cf44 changes the page structure so that the slab
subsystem reuses the page->mapping field.
The crash happens in the following way:
* XFS allocates some memory from slab and issues a bio to read data
into it.
* the bio is sent to the loopback device.
* lo_receive creates an actor and calls splice_direct_to_actor.
* lo_splice_actor copies data to the target page.
* lo_splice_actor calls flush_dcache_page because the page may be
mapped by userspace. In that case we need to flush the kernel cache.
* flush_dcache_page asks for the list of userspace mappings, however
that page->mapping field is reused by the slab subsystem for a
different purpose. This causes the crash.
Note that other architectures without coherent caches (sparc, arm, mips)
also call page_mapping from flush_dcache_page, so they may crash in the
same way.
This patch fixes this bug by testing if the page is a slab page in
page_mapping and returning NULL if it is.
The patch also fixes VM_BUG_ON(PageSlab(page)) that could happen in
earlier kernels in the same scenario on architectures without cache
coherence when CONFIG_DEBUG_VM is enabled - so it should be backported
to stable kernels.
In the old kernels, the function page_mapping is placed in
include/linux/mm.h, so you should modify the patch accordingly when
backporting it.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: John David Anglin <dave.anglin@bell.net>]
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Christoph Lameter <cl@linux.com>
Acked-by: Pekka Enberg <penberg@kernel.org>
Reviewed-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Helge Deller <deller@gmx.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>