Hi, repeated mapping of the same file on tmpfs using remap_file_pages sometimes triggers a "BUG at mm/filemap.c:202" when the process exits, log message below. The system is an x86_64 VirtualBox machine with 2GB of RAM running Debian, but it could also be reproduced on a non-virtualized laptop. The bug can be triggered in Linux 3.16-rc5, bisecting has located d7c17551 as the first failing commit (mm: implement ->map_pages for shmem/tmpfs). A test program for this has been attached (I don't trust this webmailer to not mangle it). With the parameters set in the source code, the BUG message should be triggered within a small number of tries (usually the first or second). Changing the size of the memory map sometimes delays the bug ("while true; do ./remap-demo; done" should still trigger it within a few seconds) or avoids it completely - I don't see any patterns yet. Using (at least) two different mappings for the file, each of which has been remapped seem to be a requirement for triggering it. Implementing the same mappings using mmap() does not appear to cause any problems, but I assume that someone might care about this problem while remap_file_pages() is still in the kernel. -ik ------------[ cut here ]------------ kernel BUG at mm/filemap.c:202! invalid opcode: 0000 [#1] SMP Modules linked in: uinput nfsd auth_rpcgss oid_registry nfs_acl nfs lockd fscache sunrpc ext3 jbd loop joydev hid_generic usbhid hid psmouse parport_pc ohci_pci ohci_hcd ehci_hcd usbcore ac i2c_piix4 pcspkr serio_raw evdev parport battery button processor i2c_core usb_common microcode thermal_sys ext4 crc16 jbd2 mbcache sr_mod cdrom sg sd_mod crc_t10dif crct10dif_common ata_generic e1000 ahci libahci ata_piix libata scsi_mod CPU: 3 PID: 2992 Comm: test Not tainted 3.16.0-rc5ik1 #37 Hardware name: innotek GmbH VirtualBox, BIOS VirtualBox 12/01/2006 task: ffff88005a9363d0 ti: ffff880037968000 task.ti: ffff880037968000 RIP: 0010:[<ffffffff810db4d3>] [<ffffffff810db4d3>] __delete_from_page_cache+0x16f/0x1f6 RSP: 0018:ffff88003796bba8 EFLAGS: 00010046 RAX: 0000000000000000 RBX: ffffea00012ee220 RCX: 00000000ffffffe2 RDX: 0000000000000018 RSI: 0000000000000018 RDI: ffff88005dbeb700 RBP: ffff8800378d1c10 R08: ffff88005dbeb700 R09: 0000000000000013 R10: 0000000000000013 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000003 R14: ffff8800378d1c18 R15: 000000000000000f FS: 0000000000000000(0000) GS:ffff88005d980000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f69ad38fa30 CR3: 0000000001611000 CR4: 00000000000006e0 Stack: 0000000000000002 000000000000000f ffff880059899008 ffff8800598990a8 ffff8800378d1c10 ffffea00012ee220 ffff8800378d1c28 0000000000000000 ffff8800378d1ac0 ffff8800374d0600 0000000000000001 ffffffff810db65b Call Trace: [<ffffffff810db65b>] ? delete_from_page_cache+0x32/0x56 [<ffffffff810e621d>] ? truncate_inode_page+0x62/0x69 [<ffffffff810edf29>] ? shmem_undo_range+0x13f/0x3f3 [<ffffffff810df855>] ? get_pfnblock_flags_mask+0x1d/0x4d [<ffffffff810e0bcb>] ? free_hot_cold_page+0x76/0x134 [<ffffffff810e528a>] ? release_pages+0x171/0x180 [<ffffffff810e4aa2>] ? hpage_nr_pages+0x1b/0x1b [<ffffffff811418df>] ? __inode_wait_for_writeback+0x67/0xae [<ffffffff810ee1e8>] ? shmem_truncate_range+0xb/0x25 [<ffffffff810ee76d>] ? shmem_evict_inode+0x4f/0xed [<ffffffff810ee71e>] ? shmem_file_setup+0x7/0x7 [<ffffffff81136947>] ? evict+0xa3/0x147 [<ffffffff81133576>] ? __dentry_kill+0x103/0x173 [<ffffffff81133983>] ? dput+0x133/0x150 [<ffffffff8112489d>] ? __fput+0x163/0x184 [<ffffffff8105f10c>] ? task_work_run+0x7b/0x8f [<ffffffff81049c69>] ? do_exit+0x3f6/0x904 [<ffffffff8104a282>] ? do_group_exit+0x68/0x9a [<ffffffff8104a2c4>] ? SyS_exit_group+0x10/0x10 [<ffffffff8138fb69>] ? system_call_fastpath+0x16/0x1b Code: be 0a 00 00 00 48 89 df e8 96 5b 01 00 48 8b 03 a9 00 00 08 00 74 0d be 18 00 00 00 48 89 df e8 7f 5b 01 00 8b 43 18 85 c0 78 02 <0f> 0b 48 8b 03 a8 10 74 6f 48 8b 85 88 00 00 00 f6 40 20 01 75 RIP [<ffffffff810db4d3>] __delete_from_page_cache+0x16f/0x1f6 RSP <ffff88003796bba8> ---[ end trace 79ae5bd27fcedca9 ]--- Fixing recursive fault but reboot is needed! BUG: Bad rss-counter state mm:ffff88005aae60c0 idx:0 val:1
#define _GNU_SOURCE #include <sys/mman.h> #include <sys/resource.h> #include <errno.h> #include <limits.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define PAGE_SIZE 4096 // NOTE: DATA=MAP2=16 seems to trigger in the first few tries // NOTE: 9/9 needs a loop and a few seconds to trigger // NOTE: DATA=9, MAP2=8 does not trigger #define DATA_SIZE 16 #define MAP2_SIZE 16 int shmfd; char shmpath[] = "/dev/shm/mmaptest-XXXXXX"; unsigned char *map1, *map2; unsigned int i; int main(int argc, char *argv[]) { /* create a data file on tmpfs */ shmfd = mkstemp(shmpath); if (shmfd < 0) { perror("mkstemp"); exit(2); } if (unlink(shmpath)) { perror("unlink"); exit(2); } if (ftruncate(shmfd, DATA_SIZE * PAGE_SIZE)) { perror("ftruncate"); exit(2); } /* map a single page from the file */ map1 = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); if (map1 == MAP_FAILED) { perror("mmap 1"); exit(2); } /* remap it to another page in the file */ // NOTE: Does not trigger without remapping // NOTE: Does not trigger for 7, but does trigger for 8 if both sizes are 16 // (DATA_SIZE-2 is sufficiently generic here) if (remap_file_pages(map1, PAGE_SIZE, 0, DATA_SIZE - 2, MAP_SHARED)) { perror("remap_file_pages 1"); exit(2); } /* create a second mapping */ map2 = mmap(NULL, MAP2_SIZE * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); if (map2 == MAP_FAILED) { perror("mmap 2"); exit(2); } /* map all of its pages to page 0 */ // NOTE: Remapping only the last page does not trigger for (i = 0; i < MAP2_SIZE; i++) { if (remap_file_pages(map2 + PAGE_SIZE * i, PAGE_SIZE, 0, 0, MAP_SHARED)) { perror("remap_file_pages 3"); exit(2); } } close(shmfd); exit(0); }