Hugh Dickins
486cf46f3f
mm: fix race between mremap and removing migration entry
...
I don't usually pay much attention to the stale "? " addresses in
stack backtraces, but this lucky report from Pawel Sikora hints that
mremap's move_ptes() has inadequate locking against page migration.
3.0 BUG_ON(!PageLocked(p)) in migration_entry_to_page():
kernel BUG at include/linux/swapops.h:105!
RIP: 0010:[<ffffffff81127b76>] [<ffffffff81127b76>]
migration_entry_wait+0x156/0x160
[<ffffffff811016a1>] handle_pte_fault+0xae1/0xaf0
[<ffffffff810feee2>] ? __pte_alloc+0x42/0x120
[<ffffffff8112c26b>] ? do_huge_pmd_anonymous_page+0xab/0x310
[<ffffffff81102a31>] handle_mm_fault+0x181/0x310
[<ffffffff81106097>] ? vma_adjust+0x537/0x570
[<ffffffff81424bed>] do_page_fault+0x11d/0x4e0
[<ffffffff81109a05>] ? do_mremap+0x2d5/0x570
[<ffffffff81421d5f>] page_fault+0x1f/0x30
mremap's down_write of mmap_sem, together with i_mmap_mutex or lock,
and pagetable locks, were good enough before page migration (with its
requirement that every migration entry be found) came in, and enough
while migration always held mmap_sem; but not enough nowadays, when
there's memory hotremove and compaction.
The danger is that move_ptes() lets a migration entry dodge around
behind remove_migration_pte()'s back, so it's in the old location when
looking at the new, then in the new location when looking at the old.
Either mremap's move_ptes() must additionally take anon_vma lock(), or
migration's remove_migration_pte() must stop peeking for is_swap_entry()
before it takes pagetable lock.
Consensus chooses the latter: we prefer to add overhead to migration
than to mremapping, which gets used by JVMs and by exec stack setup.
Reported-and-tested-by: Paweł Sikora <pluto@agmk.net>
Signed-off-by: Hugh Dickins <hughd@google.com>
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Mel Gorman <mgorman@suse.de>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2011-10-19 23:42:58 -07:00
..
backing-dev.c
mm: Add comment explaining task state setting in bdi_forker_thread()
2011-09-02 17:17:02 -06:00
bootmem.c
crash_dump: export is_kdump_kernel to modules, consolidate elfcorehdr_addr, setup_elfcorehdr and saved_max_pfn
2011-03-23 19:47:19 -07:00
bounce.c
cleancache.c
mm: cleancache core ops functions and config
2011-05-26 10:01:36 -06:00
compaction.c
mm: compaction: abort compaction if too many pages are isolated and caller is asynchronous V2
2011-06-15 20:04:02 -07:00
debug-pagealloc.c
dmapool.c
devres: fix possible use after free
2011-07-25 20:57:14 -07:00
fadvise.c
failslab.c
fault-injection: add ability to export fault_attr in arbitrary directory
2011-08-03 14:25:20 -10:00
filemap.c
mm: account skipped entries to avoid looping in find_get_pages
2011-09-14 18:17:56 -07:00
filemap_xip.c
mm: Convert i_mmap_lock to a mutex
2011-05-25 08:39:18 -07:00
fremap.c
mm: don't access vm_flags as 'int'
2011-05-26 09:20:31 -07:00
highmem.c
mm: make HASHED_PAGE_VIRTUAL page_address' struct page argument const.
2011-08-17 13:00:20 -07:00
huge_memory.c
mm/huge_memory.c: minor lock simplification in __khugepaged_exit
2011-07-25 20:57:09 -07:00
hugetlb.c
mm: hugetlb: fix coding style issues
2011-07-25 20:57:09 -07:00
hwpoison-inject.c
Fix common misspellings
2011-03-31 11:26:23 -03:00
init-mm.c
atomic: use <linux/atomic.h>
2011-07-26 16:49:47 -07:00
internal.h
mm: nommu: sort mm->mmap list properly
2011-05-25 08:39:05 -07:00
Kconfig
mm Kconfig typo: cleancacne -> cleancache
2011-06-10 14:47:52 +02:00
Kconfig.debug
mm: debug-pagealloc: fix kconfig dependency warning
2011-03-22 17:44:02 -07:00
kmemcheck.c
kmemleak-test.c
kmemleak: remove memset by using kzalloc
2011-01-27 18:31:51 +00:00
kmemleak.c
atomic: use <linux/atomic.h>
2011-07-26 16:49:47 -07:00
ksm.c
ksm: fix NULL pointer dereference in scan_get_next_rmap_item()
2011-06-15 20:04:02 -07:00
maccess.c
maccess,probe_kernel: Make write/read src const void *
2011-05-25 19:56:23 -04:00
madvise.c
fs: kill i_alloc_sem
2011-07-20 20:47:46 -04:00
Makefile
mm: cleancache core ops functions and config
2011-05-26 10:01:36 -06:00
memblock.c
mm/memblock.c: avoid abuse of RED_INACTIVE
2011-07-25 20:57:09 -07:00
memcontrol.c
memcg: Revert "memcg: add memory.vmscan_stat"
2011-09-14 18:09:38 -07:00
memory-failure.c
HWPoison: add memory_failure_queue()
2011-08-03 11:15:58 -04:00
memory.c
mm/futex: fix futex writes on archs with SW tracking of dirty & young
2011-07-25 20:57:11 -07:00
memory_hotplug.c
mm: extend memory hotplug API to allow memory hotplug in virtual machines
2011-07-25 20:57:08 -07:00
mempolicy.c
mm/mempolicy.c: make copy_from_user() provably correct
2011-09-14 18:09:36 -07:00
mempool.c
migrate.c
mm: fix race between mremap and removing migration entry
2011-10-19 23:42:58 -07:00
mincore.c
mm: clarify the radix_tree exceptional cases
2011-08-03 14:25:24 -10:00
mlock.c
mm: don't access vm_flags as 'int'
2011-05-26 09:20:31 -07:00
mm_init.c
mmap.c
mmap: fix and tidy up overcommit page arithmetic
2011-07-25 20:57:09 -07:00
mmu_context.c
mmu_notifier.c
thp: mmu_notifier_test_young
2011-01-13 17:32:46 -08:00
mmzone.c
mprotect.c
thp: mprotect: transparent huge page support
2011-01-13 17:32:44 -08:00
mremap.c
mm: Convert i_mmap_lock to a mutex
2011-05-25 08:39:18 -07:00
msync.c
nobootmem.c
memblock/nobootmem: remove unneeded code from alloc_bootmem_node_high()
2011-05-25 08:39:31 -07:00
nommu.c
mmap: fix and tidy up overcommit page arithmetic
2011-07-25 20:57:09 -07:00
oom_kill.c
oom: task->mm == NULL doesn't mean the memory was freed
2011-08-01 15:24:12 -10:00
page-writeback.c
squeeze max-pause area and drop pass-good area
2011-08-19 22:42:07 +08:00
page_alloc.c
fault-injection: add ability to export fault_attr in arbitrary directory
2011-08-03 14:25:20 -10:00
page_cgroup.c
mm/page_cgroup.c: simplify code by using SECTION_ALIGN_UP() and SECTION_ALIGN_DOWN() macros
2011-07-25 20:57:09 -07:00
page_io.c
block: kill off REQ_UNPLUG
2011-03-10 08:52:27 +01:00
page_isolation.c
pagewalk.c
pagewalk: fix code comment for THP
2011-07-25 20:57:09 -07:00
percpu-km.c
percpu-vm.c
percpu.c
Merge branch 'for-2.6.40' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
2011-05-24 11:53:42 -07:00
pgtable-generic.c
mm/pgtable-generic.c: fix CONFIG_SWAP=n build
2011-01-26 10:49:58 +10:00
prio_tree.c
sanitize <linux/prefetch.h> usage
2011-05-20 12:50:29 -07:00
quicklist.c
readahead.c
readahead: readahead page allocations are OK to fail
2011-05-25 08:39:25 -07:00
rmap.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/writeback
2011-07-26 10:39:54 -07:00
shmem.c
mm: clarify the radix_tree exceptional cases
2011-08-03 14:25:24 -10:00
slab.c
slab, lockdep: Annotate the locks before using them
2011-08-04 10:18:00 +02:00
slob.c
atomic: use <linux/atomic.h>
2011-07-26 16:49:47 -07:00
slub.c
slub: add slab with one free object to partial list tail
2011-08-27 11:58:59 +03:00
sparse-vmemmap.c
sparse.c
mm: make some struct page's const
2011-07-25 20:57:07 -07:00
swap.c
mm: batch activate_page() to reduce lock contention
2011-05-25 08:39:37 -07:00
swap_state.c
block: remove per-queue plugging
2011-03-10 08:52:07 +01:00
swapfile.c
mm: let swap use exceptional entries
2011-08-03 14:25:22 -10:00
thrash.c
mm: swap-token: add a comment for priority aging
2011-07-25 20:57:08 -07:00
truncate.c
mm: a few small updates for radix-swap
2011-08-03 14:25:24 -10:00
util.c
mm: nommu: sort mm->mmap list properly
2011-05-25 08:39:05 -07:00
vmalloc.c
mm: sync vmalloc address space page tables in alloc_vm_area()
2011-09-14 18:09:38 -07:00
vmscan.c
memcg: Revert "memcg: add memory.vmscan_stat"
2011-09-14 18:09:38 -07:00
vmstat.c
numa: fix NUMA compile error when sysfs and procfs are disabled
2011-09-14 18:09:37 -07:00