Naoya Horiguchi
a3e0f9e47d
mm/memory-failure.c: transfer page count from head page to tail page after split thp
...
Memory failures on thp tail pages cause kernel panic like below:
mce: [Hardware Error]: Machine check events logged
MCE exception done on CPU 7
BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
IP: [<ffffffff811b7cd1>] dequeue_hwpoisoned_huge_page+0x131/0x1e0
PGD bae42067 PUD ba47d067 PMD 0
Oops: 0000 [#1 ] SMP
...
CPU: 7 PID: 128 Comm: kworker/7:2 Tainted: G M O 3.13.0-rc4-131217-1558-00003-g83b7df08e462 #25
...
Call Trace:
me_huge_page+0x3e/0x50
memory_failure+0x4bb/0xc20
mce_process_work+0x3e/0x70
process_one_work+0x171/0x420
worker_thread+0x11b/0x3a0
? manage_workers.isra.25+0x2b0/0x2b0
kthread+0xe4/0x100
? kthread_create_on_node+0x190/0x190
ret_from_fork+0x7c/0xb0
? kthread_create_on_node+0x190/0x190
...
RIP dequeue_hwpoisoned_huge_page+0x131/0x1e0
CR2: 0000000000000058
The reasoning of this problem is shown below:
- when we have a memory error on a thp tail page, the memory error
handler grabs a refcount of the head page to keep the thp under us.
- Before unmapping the error page from processes, we split the thp,
where page refcounts of both of head/tail pages don't change.
- Then we call try_to_unmap() over the error page (which was a tail
page before). We didn't pin the error page to handle the memory error,
this error page is freed and removed from LRU list.
- We never have the error page on LRU list, so the first page state
check returns "unknown page," then we move to the second check
with the saved page flag.
- The saved page flag have PG_tail set, so the second page state check
returns "hugepage."
- We call me_huge_page() for freed error page, then we hit the above panic.
The root cause is that we didn't move refcount from the head page to the
tail page after split thp. So this patch suggests to do this.
This panic was introduced by commit 524fca1e73 ("HWPOISON: fix
misjudgement of page_action() for errors on mlocked pages"). Note that we
did have the same refcount problem before this commit, but it was just
ignored because we had only first page state check which returned "unknown
page." The commit changed the refcount problem from "doesn't work" to
"kernel panic."
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Reviewed-by: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: <stable@vger.kernel.org> [3.9+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-01-02 14:40:30 -08:00
..
backing-dev.c
mm/backing-dev.c: check user buffer length before copying data to the related user buffer
2013-09-11 15:58:03 -07:00
balloon_compaction.c
mm: introduce a common interface for balloon pages mobility
2012-12-11 17:22:26 -08:00
bootmem.c
mm/bootmem.c: remove unused local `map'
2013-11-13 12:09:09 +09:00
bounce.c
mm/bounce.c: fix a regression where MS_SNAP_STABLE (stable pages snapshotting) was ignored
2013-09-30 14:31:02 -07:00
cleancache.c
mm: cleancache: clean up cleancache_enabled
2013-04-30 17:04:01 -07:00
compaction.c
mm/compaction: respect ignore_skip_hint in update_pageblock_skip
2013-12-18 19:04:52 -08:00
debug-pagealloc.c
dmapool.c
dmapool: make DMAPOOL_DEBUG detect corruption of free marker
2012-12-11 17:22:24 -08:00
fadvise.c
teach SYSCALL_DEFINE<n> how to deal with long long/unsigned long long
2013-03-03 22:46:22 -05:00
failslab.c
filemap.c
mm: drop actor argument of do_generic_file_read()
2013-11-15 09:32:13 +09:00
filemap_xip.c
seqcount: Add lockdep functionality to seqcount/seqlock structures
2013-11-06 12:40:26 +01:00
fremap.c
mm: fix use-after-free in sys_remap_file_pages
2014-01-02 14:40:30 -08:00
frontswap.c
frontswap: fix incorrect zeroing and allocation size for frontswap_map
2013-06-12 16:29:46 -07:00
highmem.c
Some nice cleanups, and even a patch my wife did as a "live" demo for
2012-12-20 08:37:05 -08:00
huge_memory.c
mm: remove bogus warning in copy_huge_pmd()
2014-01-02 14:40:30 -08:00
hugetlb.c
mm: hugetlbfs: fix hugetlbfs optimization
2013-11-21 16:42:27 -08:00
hugetlb_cgroup.c
cgroup: pass around cgroup_subsys_state instead of cgroup in file methods
2013-08-08 20:11:24 -04:00
hwpoison-inject.c
mm/hwpoison: fix the lack of one reference count against poisoned page
2013-09-30 14:31:03 -07:00
init-mm.c
internal.h
mm: vmscan: fix do_try_to_free_pages() livelock
2013-09-11 15:58:01 -07:00
interval_tree.c
mm: add CONFIG_DEBUG_VM_RB build option
2012-10-09 16:22:42 +09:00
Kconfig
mm: add missing dependency in Kconfig
2013-12-18 19:04:52 -08:00
Kconfig.debug
kmemcheck.c
kmemleak-test.c
kmemleak.c
mm: kmemleak: avoid false negatives on vmalloc'ed objects
2013-11-13 12:09:07 +09:00
ksm.c
ksm: remove redundant __GFP_ZERO from kcalloc
2013-11-13 12:09:02 +09:00
list_lru.c
mm: list_lru: fix almost infinite loop causing effective livelock
2013-10-30 12:57:46 -07:00
maccess.c
madvise.c
mm/hwpoison: fix traversal of hugetlbfs pages to avoid printk flood
2013-09-30 14:31:02 -07:00
Makefile
list: add a new LRU list type
2013-09-10 18:56:30 -04:00
memblock.c
mm/memblock.c: introduce bottom-up allocation mode
2013-11-13 12:09:08 +09:00
memcontrol.c
memcg: fix memcg_size() calculation
2014-01-02 14:40:30 -08:00
memory-failure.c
mm/memory-failure.c: transfer page count from head page to tail page after split thp
2014-01-02 14:40:30 -08:00
memory.c
mm: fix build of split ptlock code
2013-12-20 15:41:27 -08:00
memory_hotplug.c
mem-hotplug: introduce movable_node boot option
2013-11-13 12:09:09 +09:00
mempolicy.c
mm/mempolicy: fix !vma in new_vma_page()
2013-12-18 19:04:52 -08:00
mempool.c
mm/mempool.c: convert kmalloc_node(...GFP_ZERO...) to kzalloc_node(...)
2013-09-11 15:58:14 -07:00
migrate.c
aio/migratepages: make aio migrate pages sane
2013-12-21 17:56:08 -05:00
mincore.c
swap: make each swap partition have one address_space
2013-02-23 17:50:17 -08:00
mlock.c
mm: munlock: fix deadlock in __munlock_pagevec()
2014-01-02 14:40:30 -08:00
mm_init.c
mm: numa: Change page last {nid,pid} into {cpu,pid}
2013-10-09 14:47:45 +02:00
mmap.c
mm: convert mm->nr_ptes to atomic_long_t
2013-11-15 09:32:14 +09:00
mmu_context.c
mm: remove old aio use_mm() comment
2013-05-07 18:38:27 -07:00
mmu_notifier.c
treewide: relase -> release
2013-06-28 14:34:33 +02:00
mmzone.c
mm: numa: Change page last {nid,pid} into {cpu,pid}
2013-10-09 14:47:45 +02:00
mprotect.c
mm: fix TLB flush race between migration, and change_protection_range
2013-12-18 19:04:51 -08:00
mremap.c
mm: revert mremap pud_free anti-fix
2013-10-16 21:35:53 -07:00
msync.c
nobootmem.c
mm/nobootmem.c: have __free_pages_memory() free in larger chunks.
2013-11-13 12:09:04 +09:00
nommu.c
Merge branch 'akpm' (patches from Andrew Morton)
2013-11-13 15:45:43 +09:00
oom_kill.c
mm: convert mm->nr_ptes to atomic_long_t
2013-11-15 09:32:14 +09:00
page-writeback.c
writeback: fix negative bdi max pause
2013-10-16 21:35:53 -07:00
page_alloc.c
mm: page_alloc: revert NUMA aspect of fair allocation policy
2013-12-20 12:19:18 -08:00
page_cgroup.c
memcontrol: use N_MEMORY instead N_HIGH_MEMORY
2012-12-12 17:38:32 -08:00
page_io.c
aio: Kill aio_rw_vect_retry()
2013-07-30 11:53:12 -04:00
page_isolation.c
mm: memory-hotplug: enable memory hotplug to handle hugepage
2013-09-11 15:57:48 -07:00
pagewalk.c
mm/pagewalk.c: fix walk_page_range() access of wrong PTEs
2013-10-30 14:27:03 -07:00
percpu-km.c
percpu-vm.c
percpu.c
percpu: fix bootmem error handling in pcpu_page_first_chunk()
2013-09-23 10:51:45 -04:00
pgtable-generic.c
mm: fix TLB flush race between migration, and change_protection_range
2013-12-18 19:04:51 -08:00
process_vm_access.c
Fix: compat_rw_copy_check_uvector() misuse in aio, readv, writev, and security keys
2013-03-12 11:05:45 -07:00
quicklist.c
readahead.c
readahead: fix sequential read cache miss detection
2013-11-13 12:09:09 +09:00
rmap.c
mm/hugetlb: check for pte NULL pointer in __page_check_address()
2013-12-18 19:04:52 -08:00
shmem.c
security: shmem: implement kernel private shmem inodes
2013-12-02 11:24:19 +00:00
slab.c
Merge branch 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/linux
2013-11-22 08:10:34 -08:00
slab.h
memcg, kmem: rename cache_from_memcg to cache_from_memcg_idx
2013-11-13 12:09:10 +09:00
slab_common.c
memcg, kmem: rename cache_from_memcg to cache_from_memcg_idx
2013-11-13 12:09:10 +09:00
slob.c
mm/sl[aou]b: Move kmallocXXX functions to common code
2013-09-04 20:51:33 +03:00
slub.c
Merge branch 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/linux
2013-11-22 08:10:34 -08:00
sparse-vmemmap.c
sparse-vmemmap: specify vmemmap population range in bytes
2013-04-29 15:54:35 -07:00
sparse.c
mm/sparsemem: fix a bug in free_map_bootmem when CONFIG_SPARSEMEM_VMEMMAP
2013-11-13 12:09:06 +09:00
swap.c
mm: hugetlbfs: fix hugetlbfs optimization
2013-11-21 16:42:27 -08:00
swap_state.c
lib/radix-tree.c: make radix_tree_node_alloc() work correctly within interrupt
2013-09-11 15:59:36 -07:00
swapfile.c
frontswap: enable call to invalidate area on swapoff
2013-11-13 12:09:07 +09:00
truncate.c
truncate: drop 'oldsize' truncate_pagecache() parameter
2013-09-12 15:38:02 -07:00
util.c
mm: factor commit limit calculation
2013-11-13 12:09:11 +09:00
vmalloc.c
mm: kmemleak: avoid false negatives on vmalloc'ed objects
2013-11-13 12:09:07 +09:00
vmpressure.c
Merge branch 'for-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
2013-09-03 18:25:03 -07:00
vmscan.c
mm/vmscan.c: don't forget to free shrinker->nr_deferred
2013-10-16 21:35:52 -07:00
vmstat.c
mm: numa: return the number of base pages altered by protection changes
2013-11-13 12:09:11 +09:00
zbud.c
mm/zbud: fix some trivial typos in comments
2013-09-11 15:57:35 -07:00
zswap.c
mm/zswap: refactor the get/put routines
2013-11-13 12:09:11 +09:00