Re: mm: WARNING in __delete_from_page_cache
From: Jan Kara
Date: Mon Jan 25 2016 - 07:22:04 EST
On Mon 25-01-16 01:04:22, Kirill A. Shutemov wrote:
> On Sun, Jan 24, 2016 at 11:48:21AM +0100, Dmitry Vyukov wrote:
> > Hello,
> >
> > The following program triggers WARNING in __delete_from_page_cache:
> >
> > ------------[ cut here ]------------
> > WARNING: CPU: 0 PID: 7676 at mm/filemap.c:217
> > __delete_from_page_cache+0x9f6/0xb60()
> > Modules linked in:
> > CPU: 0 PID: 7676 Comm: a.out Not tainted 4.4.0+ #276
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> > 00000000ffffffff ffff88006d3f7738 ffffffff82999e2d 0000000000000000
> > ffff8800620a0000 ffffffff86473d20 ffff88006d3f7778 ffffffff81352089
> > ffffffff81658d36 ffffffff86473d20 00000000000000d9 ffffea0000009d60
> > Call Trace:
> > [< inline >] __dump_stack lib/dump_stack.c:15
> > [<ffffffff82999e2d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
> > [<ffffffff81352089>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
> > [<ffffffff813522b9>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
> > [<ffffffff81658d36>] __delete_from_page_cache+0x9f6/0xb60 mm/filemap.c:217
> > [<ffffffff81658fb2>] delete_from_page_cache+0x112/0x200 mm/filemap.c:244
> > [<ffffffff818af369>] __dax_fault+0x859/0x1800 fs/dax.c:487
> > [<ffffffff8186f4f6>] blkdev_dax_fault+0x26/0x30 fs/block_dev.c:1730
> > [< inline >] wp_pfn_shared mm/memory.c:2208
> > [<ffffffff816e9145>] do_wp_page+0xc85/0x14f0 mm/memory.c:2307
> > [< inline >] handle_pte_fault mm/memory.c:3323
> > [< inline >] __handle_mm_fault mm/memory.c:3417
> > [<ffffffff816ecec3>] handle_mm_fault+0x2483/0x4640 mm/memory.c:3446
> > [<ffffffff8127eff6>] __do_page_fault+0x376/0x960 arch/x86/mm/fault.c:1238
> > [<ffffffff8127f738>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331
> > [<ffffffff812705c4>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264
> > [<ffffffff86338f78>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986
> > [<ffffffff86336c36>] entry_SYSCALL_64_fastpath+0x16/0x7a
> > arch/x86/entry/entry_64.S:185
> > ---[ end trace dae21e0f85f1f98c ]---
> >
> >
> > // autogenerated by syzkaller (http://github.com/google/syzkaller)
> > #include <pthread.h>
> > #include <stdint.h>
> > #include <string.h>
> > #include <sys/syscall.h>
> > #include <unistd.h>
> > #include <fcntl.h>
> >
> > int main()
> > {
> > syscall(SYS_mmap, 0x20000000ul, 0x10000ul, 0x3ul, 0x32ul, -1, 0x0ul);
> > int fd = syscall(SYS_open, "/dev/ram1", O_RDWR);
> > syscall(SYS_mmap, 0x20a31000ul, 0x3000ul, 0x3ul, 0xb011ul, fd, 0x0ul);
> > *(uint64_t*)0x20003000 = 1;
> > syscall(SYS_write, fd, 0x20003000ul, 0x78ul, 0, 0, 0);
> > syscall(SYS_getresuid, 0x20000688ul, 0x200008f2ul, 0x20a31000ul, 0, 0, 0);
> > return 0;
> > }
> >
> > On commit 30f05309bde49295e02e45c7e615f73aa4e0ccc2.
>
> Reduced and human readable test case:
>
> #include <fcntl.h>
> #include <unistd.h>
> #include <sys/mman.h>
>
> int main()
> {
> int fd;
> char *p;
>
> fd = open("/dev/ram0", O_RDWR);
> p = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> write(fd, "1", 1);
> *p = 1;
> return 0;
> }
>
> Looks like DAX doesn't expect to see something except hole-page in the radix
> tree. This expectation is [probably] true for files on DAX-enabled
> filesystems, but it seems broken for ramdisks.
>
> Matthew?
Thanks. Despite the huge list of recipients the author of the changes
hasn't been CCed :) I've added Dan to CC since he wrote DAX support for
block devices. It seems somehow the write didn't go through the DAX path
but through the standard page cache write path. Ah, I see, only
file->f_mapping->host has S_DAX set but io_is_direct() which decides
whether DAX or pagecache path should be used for writes uses file->f_inode
which is something different for block devices...
Honza
--
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR