Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mm/memory-failure: introduce get_hwpoison_page() for consistent refco…
…unt handling memory_failrue() can run in 2 different mode (specified by MF_COUNT_INCREASED) in page refcount perspective. When MF_COUNT_INCREASED is set, memory_failrue() 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 in such case. 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. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> --- ChangeLog v1->v2: - fix function's comment to kernel-doc format - remove 'inline' directive in get_hwpoison_page() definition - separate if blocks instead of using else blocks - add comment about thp refcounting - add put_page(hpage) in failure path - clear PageHWPoison if failed to handle thp - revert the change removing VM_BUG_ON_PAGE() in put_refcounted_compound_page() - revert the change allowing unpoison_memory() to handle thp
- Loading branch information