diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2016-07-26 15:25:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-26 16:19:19 -0700 |
commit | baa355fd331424526e742d41d9b90d5f9d10f716 (patch) | |
tree | 762004078f781ba9fd053186dcb7d9925d3c41bd /mm/gup.c | |
parent | 37f9f5595c26d3cb644ca2fab83dc4c4db119f9f (diff) | |
download | linux-exynos-baa355fd331424526e742d41d9b90d5f9d10f716.tar.gz linux-exynos-baa355fd331424526e742d41d9b90d5f9d10f716.tar.bz2 linux-exynos-baa355fd331424526e742d41d9b90d5f9d10f716.zip |
thp: file pages support for split_huge_page()
Basic scheme is the same as for anon THP.
Main differences:
- File pages are on radix-tree, so we have head->_count offset by
HPAGE_PMD_NR. The count got distributed to small pages during split.
- mapping->tree_lock prevents non-lockless access to pages under split
over radix-tree;
- Lockless access is prevented by setting the head->_count to 0 during
split;
- After split, some pages can be beyond i_size. We drop them from
radix-tree.
- We don't setup migration entries. Just unmap pages. It helps
handling cases when i_size is in the middle of the page: no need
handle unmap pages beyond i_size manually.
Link: http://lkml.kernel.org/r/1466021202-61880-20-git-send-email-kirill.shutemov@linux.intel.com
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/gup.c')
-rw-r--r-- | mm/gup.c | 2 |
1 files changed, 2 insertions, 0 deletions
@@ -288,6 +288,8 @@ struct page *follow_page_mask(struct vm_area_struct *vma, ret = split_huge_page(page); unlock_page(page); put_page(page); + if (pmd_none(*pmd)) + return no_page_table(vma, flags); } return ret ? ERR_PTR(ret) : |