summaryrefslogtreecommitdiff
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2014-04-16 10:54:44 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2014-04-17 09:52:35 +1000
commit7dfb01f768901c2fed8848aea83538db179b31dc (patch)
treec1ec59b54b73db04b36c17989593c579a9fbbb3b /mm/huge_memory.c
parent0cc58d7c5d985900f7a054954ff97f8d3bfc424e (diff)
mm, hugetlbfs: fix rmapping for anonymous hugepages with page_pgoff()
page->index stores pagecache index when the page is mapped into file mapping region, and the index is in pagecache size unit, so it depends on the page size. Some of users of reverse mapping obviously assumes that page->index is in PAGE_CACHE_SHIFT unit, so they don't work for anonymous hugepage. For example, consider that we have 3-hugepage vma and try to mbind the 2nd hugepage to migrate to another node. Then the vma is split and migrate_page() is called for the 2nd hugepage (belonging to the middle vma.) In migrate operation, rmap_walk_anon() tries to find the relevant vma to which the target hugepage belongs, but here we miscalculate pgoff. So anon_vma_interval_tree_foreach() grabs invalid vma, which fires VM_BUG_ON. This patch introduces a new API that is usable both for normal page and hugepage to get PAGE_SIZE offset from page->index. Users should clearly distinguish page_index for pagecache index and page_pgoff for page offset. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Reported-by: Sasha Levin <sasha.levin@oracle.com> Cc: Rik van Riel <riel@redhat.com> Cc: <stable@vger.kernel.org> [3.12+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 64635f5278ff..7577c40f2ad7 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1800,7 +1800,7 @@ static void __split_huge_page(struct page *page,
struct list_head *list)
{
int mapcount, mapcount2;
- pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+ pgoff_t pgoff = page_pgoff(page);
struct anon_vma_chain *avc;
BUG_ON(!PageHead(page));