remarkable-linux/mm
Naoya Horiguchi ead07f6a86 mm/memory-failure: introduce get_hwpoison_page() for consistent refcount handling
memory_failure() can run in 2 different mode (specified by
MF_COUNT_INCREASED) in page refcount perspective.  When
MF_COUNT_INCREASED is set, memory_failure() assumes that the caller
takes a refcount of the target page.  And if cleared, memory_failure()
takes it in it's own.

In current code, however, refcounting is done differently in each caller.
For example, madvise_hwpoison() uses get_user_pages_fast() and
hwpoison_inject() uses get_page_unless_zero().  So this inconsistent
refcounting causes refcount failure especially for thp tail pages.
Typical user visible effects are like memory leak or
VM_BUG_ON_PAGE(!page_count(page)) in isolate_lru_page().

To fix this refcounting issue, this patch introduces get_hwpoison_page()
to handle thp tail pages in the same manner for each caller of hwpoison
code.

memory_failure() might fail to split thp and in such case it returns
without completing page isolation.  This is not good because PageHWPoison
on the thp is still set and there's no easy way to unpoison such thps.  So
this patch try to roll back any action to the thp in "non anonymous thp"
case and "thp split failed" case, expecting an MCE(SRAR) generated by
later access afterward will properly free such thps.

[akpm@linux-foundation.org: fix CONFIG_HWPOISON_INJECT=m]
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-06-24 17:49:42 -07:00
..
kasan mm/mempool.c: kasan: poison mempool elements 2015-04-15 16:35:20 -07:00
backing-dev.c block: discard bdi_unregister() in favour of bdi_destroy() 2015-05-28 10:12:42 -06:00
balloon_compaction.c
bootmem.c
cleancache.c cleancache: remove limit on the number of cleancache enabled filesystems 2015-04-14 16:49:03 -07:00
cma.c mm: cma: add trace events for CMA allocations and freeings 2015-04-15 16:35:19 -07:00
cma.h mm: cma: allocation trigger 2015-04-14 16:49:00 -07:00
cma_debug.c mm/cma_debug.c: remove blank lines before DEFINE_SIMPLE_ATTRIBUTE() 2015-04-15 16:35:20 -07:00
compaction.c mm/compaction.c: fix "suitable_migration_target() unused" warning 2015-04-15 16:35:20 -07:00
debug-pagealloc.c
debug.c
dmapool.c
early_ioremap.c
fadvise.c vfs: remove get_xip_mem 2015-02-16 17:56:03 -08:00
failslab.c
filemap.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-04-16 23:27:56 -04:00
frontswap.c
gup.c mm: use READ_ONCE() for non-scalar types 2015-04-15 16:35:18 -07:00
highmem.c
huge_memory.c thp: cleanup how khugepaged enters freezer 2015-06-24 17:49:41 -07:00
hugetlb.c mm/hugetlb: reduce arch dependent code about huge_pmd_unshare 2015-06-24 17:49:41 -07:00
hugetlb_cgroup.c
hwpoison-inject.c mm/memory-failure: introduce get_hwpoison_page() for consistent refcount handling 2015-06-24 17:49:42 -07:00
init-mm.c
internal.h mm: remove rest of ACCESS_ONCE() usages 2015-04-15 16:35:18 -07:00
interval_tree.c
Kconfig mm: cma: debugfs interface 2015-04-14 16:49:00 -07:00
Kconfig.debug
kmemcheck.c
kmemleak-test.c
kmemleak.c gfp: add __GFP_NOACCOUNT 2015-05-14 17:55:51 -07:00
ksm.c mm: remove rest of ACCESS_ONCE() usages 2015-04-15 16:35:18 -07:00
list_lru.c
maccess.c
madvise.c vfs: remove get_xip_mem 2015-02-16 17:56:03 -08:00
Makefile mm: move memtest under mm 2015-04-14 16:49:06 -07:00
memblock.c mm/memblock.c: add debug output for memblock_add() 2015-04-15 16:35:19 -07:00
memcontrol.c mm: memcontrol: fix false-positive VM_BUG_ON() on -rt 2015-06-10 16:43:43 -07:00
memory-failure.c mm/memory-failure: introduce get_hwpoison_page() for consistent refcount handling 2015-06-24 17:49:42 -07:00
memory.c sched/preempt, mm/fault: Trigger might_sleep() in might_fault() with disabled pagefaults 2015-05-19 08:39:14 +02:00
memory_hotplug.c mm/memory_hotplug.c: set zone->wait_table to null after freeing it 2015-06-10 16:43:43 -07:00
mempolicy.c mm, numa: really disable NUMA balancing by default on single node machines 2015-05-14 17:55:51 -07:00
mempool.c mm/mempool.c: kasan: poison mempool elements 2015-04-15 16:35:20 -07:00
memtest.c memtest: use phys_addr_t for physical addresses 2015-04-14 16:49:06 -07:00
migrate.c mm/migrate: check-before-clear PageSwapCache 2015-04-15 16:35:17 -07:00
mincore.c
mlock.c mm: move mm_populate()-related code to mm/gup.c 2015-04-14 16:49:00 -07:00
mm_init.c
mmap.c mm/mmap.c: use while instead of if+goto 2015-04-15 16:35:19 -07:00
mmu_context.c
mmu_notifier.c
mmzone.c
mprotect.c mm: fix mprotect() behaviour on VM_LOCKED VMAs 2015-06-24 17:49:41 -07:00
mremap.c mm: new arch_remap() hook 2015-06-24 17:49:41 -07:00
msync.c
nobootmem.c
nommu.c nommu: use __vfs_read() 2015-04-11 22:27:56 -04:00
oom_kill.c mm/oom_kill.c: fix typo in comment 2015-04-15 16:35:16 -07:00
page-writeback.c writeback: use |1 instead of +1 to protect against div by zero 2015-04-23 10:36:33 -06:00
page_alloc.c mm/page_alloc.c: cleanup obsolete KM_USER* 2015-06-24 17:49:42 -07:00
page_counter.c
page_ext.c
page_io.c direct_IO: remove rw from a_ops->direct_IO() 2015-04-11 22:29:45 -04:00
page_isolation.c CMA: page_isolation: check buddy before accessing it 2015-05-14 17:55:51 -07:00
page_owner.c
pagewalk.c mm/pagewalk.c: prevent positive return value of walk_page_test() from being passed to callers 2015-03-25 16:20:30 -07:00
percpu-km.c
percpu-vm.c
percpu.c percpu: Fix trivial typos in comments 2015-03-24 13:41:54 -04:00
pgtable-generic.c
process_vm_access.c process_vm_access: switch to {compat_,}import_iovec() 2015-04-11 22:27:12 -04:00
quicklist.c
readahead.c
rmap.c mm: remove rest of ACCESS_ONCE() usages 2015-04-15 16:35:18 -07:00
shmem.c Merge branch 'for-linus-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-06-22 12:51:21 -07:00
slab.c slab: correct size_index table before replacing the bootstrap kmem_cache_node 2015-06-24 17:49:41 -07:00
slab.h slab: correct size_index table before replacing the bootstrap kmem_cache_node 2015-06-24 17:49:41 -07:00
slab_common.c slab: correct size_index table before replacing the bootstrap kmem_cache_node 2015-06-24 17:49:41 -07:00
slob.c slob: make slob_alloc_node() static and remove EXPORT_SYMBOL() 2015-04-14 16:48:59 -07:00
slub.c slab: correct size_index table before replacing the bootstrap kmem_cache_node 2015-06-24 17:49:41 -07:00
sparse-vmemmap.c
sparse.c
swap.c mm: drop bogus VM_BUG_ON_PAGE assert in put_page() codepath 2015-06-24 17:49:42 -07:00
swap_cgroup.c
swap_state.c mm: remove rest of ACCESS_ONCE() usages 2015-04-15 16:35:18 -07:00
swapfile.c mm: remove rest of ACCESS_ONCE() usages 2015-04-15 16:35:18 -07:00
truncate.c mm: rename deactivate_page to deactivate_file_page 2015-04-15 16:35:17 -07:00
util.c mm: uninline and cleanup page-mapping related helpers 2015-04-15 16:35:19 -07:00
vmacache.c
vmalloc.c mm/vmalloc: get rid of dirty bitmap inside vmap_block structure 2015-04-15 16:35:18 -07:00
vmpressure.c
vmscan.c mm: rename RECLAIM_SWAP to RECLAIM_UNMAP 2015-06-24 17:49:42 -07:00
vmstat.c
workingset.c
zbud.c
zpool.c
zsmalloc.c zsmalloc: fix a null pointer dereference in destroy_handle_cache() 2015-06-10 16:43:43 -07:00
zswap.c