[PATCHv2 06/13] mm, thp, tmpfs: request huge page in shm_fault whenneeded
From: Ning Qu
Date: Mon Oct 21 2013 - 17:47:24 EST
Add the function to request huge page in shm_fault when needed.
And it will fall back to regular page if huge page can't be
satisfied or allocated.
If small page requested but huge page is found, the huge page will
be splitted.
Signed-off-by: Ning Qu <quning@xxxxxxxxx>
---
mm/shmem.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index b80ace7..0dd6689 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1469,19 +1469,43 @@ unlock:
static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct inode *inode = file_inode(vma->vm_file);
+ struct page *page = NULL;
int error;
int ret = VM_FAULT_LOCKED;
gfp_t gfp = mapping_gfp_mask(inode->i_mapping);
+ bool must_use_thp = vmf->flags & FAULT_FLAG_TRANSHUGE;
+ int flags = AOP_FLAG_TRANSHUGE;
- error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, gfp,
- 0, &ret);
+retry_find:
+ error = shmem_getpage(inode, vmf->pgoff, &page, SGP_CACHE, gfp,
+ flags, &ret);
if (error)
return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
+ /* Split huge page if we don't want huge page to be here */
+ if (!must_use_thp && PageTransCompound(page)) {
+ unlock_page(page);
+ page_cache_release(page);
+ split_huge_page(compound_trans_head(page));
+ page = NULL;
+ goto retry_find;
+ }
+
+ if (must_use_thp && !PageTransHuge(page)) {
+ /*
+ * Caller asked for huge page, but we have small page
+ * by this offset. Fallback to small pages.
+ */
+ unlock_page(page);
+ page_cache_release(page);
+ return VM_FAULT_FALLBACK;
+ }
+
if (ret & VM_FAULT_MAJOR) {
count_vm_event(PGMAJFAULT);
mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT);
}
+ vmf->page = page;
return ret;
}
--
1.8.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/