linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed
@ 2013-10-15  0:12 Ning Qu
  2013-10-15 10:37 ` Kirill A. Shutemov
  0 siblings, 1 reply; 4+ messages in thread
From: Ning Qu @ 2013-10-15  0:12 UTC (permalink / raw)
  To: Andrea Arcangeli, Andrew Morton, Kirill A. Shutemov, Hugh Dickins
  Cc: Al Viro, Hugh Dickins, Wu Fengguang, Jan Kara, Mel Gorman,
	linux-mm, Andi Kleen, Matthew Wilcox, Hillf Danton, Dave Hansen,
	Alexander Shishkin, linux-fsdevel, linux-kernel, Ning Qu

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@gmail.com>
---
 mm/shmem.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 68a0e1d..2fc450d 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1472,19 +1472,45 @@ 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);
-
-	error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, gfp,
-				0, &ret);
+	bool must_use_thp = vmf->flags & FAULT_FLAG_TRANSHUGE;
+	int flags = 0;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE
+	flags |= AOP_FLAG_TRANSHUGE;
+#endif
+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



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed
  2013-10-15  0:12 [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed Ning Qu
@ 2013-10-15 10:37 ` Kirill A. Shutemov
  2013-10-15 18:49   ` Ning Qu
  0 siblings, 1 reply; 4+ messages in thread
From: Kirill A. Shutemov @ 2013-10-15 10:37 UTC (permalink / raw)
  To: Ning Qu
  Cc: Andrea Arcangeli, Andrew Morton, Kirill A. Shutemov,
	Hugh Dickins, Al Viro, Hugh Dickins, Wu Fengguang, Jan Kara,
	Mel Gorman, linux-mm, Andi Kleen, Matthew Wilcox, Hillf Danton,
	Dave Hansen, Alexander Shishkin, linux-fsdevel, linux-kernel,
	Ning Qu

Ning Qu wrote:
> 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@gmail.com>
> ---
>  mm/shmem.c | 32 +++++++++++++++++++++++++++++---
>  1 file changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 68a0e1d..2fc450d 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -1472,19 +1472,45 @@ 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);
> -
> -	error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, gfp,
> -				0, &ret);
> +	bool must_use_thp = vmf->flags & FAULT_FLAG_TRANSHUGE;
> +	int flags = 0;
> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE
> +	flags |= AOP_FLAG_TRANSHUGE;
> +#endif

ifdef is not needed: shmem_getpage will ignore AOP_FLAG_TRANSHUGE if
CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE is not defined.

-- 
 Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed
  2013-10-15 10:37 ` Kirill A. Shutemov
@ 2013-10-15 18:49   ` Ning Qu
  2013-10-16 18:29     ` Ning Qu
  0 siblings, 1 reply; 4+ messages in thread
From: Ning Qu @ 2013-10-15 18:49 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Andrea Arcangeli, Andrew Morton, Hugh Dickins, Al Viro,
	Wu Fengguang, Jan Kara, Mel Gorman, linux-mm, Andi Kleen,
	Matthew Wilcox, Hillf Danton, Dave Hansen, Alexander Shishkin,
	linux-fsdevel, linux-kernel

Will fix this.
Best wishes,
-- 
Ning Qu (曲宁) | Software Engineer | quning@google.com | +1-408-418-6066


On Tue, Oct 15, 2013 at 3:37 AM, Kirill A. Shutemov
<kirill.shutemov@linux.intel.com> wrote:
> Ning Qu wrote:
>> 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@gmail.com>
>> ---
>>  mm/shmem.c | 32 +++++++++++++++++++++++++++++---
>>  1 file changed, 29 insertions(+), 3 deletions(-)
>>
>> diff --git a/mm/shmem.c b/mm/shmem.c
>> index 68a0e1d..2fc450d 100644
>> --- a/mm/shmem.c
>> +++ b/mm/shmem.c
>> @@ -1472,19 +1472,45 @@ 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);
>> -
>> -     error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, gfp,
>> -                             0, &ret);
>> +     bool must_use_thp = vmf->flags & FAULT_FLAG_TRANSHUGE;
>> +     int flags = 0;
>> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE
>> +     flags |= AOP_FLAG_TRANSHUGE;
>> +#endif
>
> ifdef is not needed: shmem_getpage will ignore AOP_FLAG_TRANSHUGE if
> CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE is not defined.
>
> --
>  Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed
  2013-10-15 18:49   ` Ning Qu
@ 2013-10-16 18:29     ` Ning Qu
  0 siblings, 0 replies; 4+ messages in thread
From: Ning Qu @ 2013-10-16 18:29 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: Andrea Arcangeli, Andrew Morton, Hugh Dickins, Al Viro,
	Wu Fengguang, Jan Kara, Mel Gorman, linux-mm, Andi Kleen,
	Matthew Wilcox, Hillf Danton, Dave Hansen, Alexander Shishkin,
	linux-fsdevel, linux-kernel

Fixed.
Best wishes,
-- 
Ning Qu (曲宁) | Software Engineer | quning@google.com | +1-408-418-6066


On Tue, Oct 15, 2013 at 11:49 AM, Ning Qu <quning@google.com> wrote:
> Will fix this.
> Best wishes,
> --
> Ning Qu (曲宁) | Software Engineer | quning@google.com | +1-408-418-6066
>
>
> On Tue, Oct 15, 2013 at 3:37 AM, Kirill A. Shutemov
> <kirill.shutemov@linux.intel.com> wrote:
>> Ning Qu wrote:
>>> 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@gmail.com>
>>> ---
>>>  mm/shmem.c | 32 +++++++++++++++++++++++++++++---
>>>  1 file changed, 29 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/mm/shmem.c b/mm/shmem.c
>>> index 68a0e1d..2fc450d 100644
>>> --- a/mm/shmem.c
>>> +++ b/mm/shmem.c
>>> @@ -1472,19 +1472,45 @@ 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);
>>> -
>>> -     error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, gfp,
>>> -                             0, &ret);
>>> +     bool must_use_thp = vmf->flags & FAULT_FLAG_TRANSHUGE;
>>> +     int flags = 0;
>>> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE
>>> +     flags |= AOP_FLAG_TRANSHUGE;
>>> +#endif
>>
>> ifdef is not needed: shmem_getpage will ignore AOP_FLAG_TRANSHUGE if
>> CONFIG_TRANSPARENT_HUGEPAGE_PAGECACHE is not defined.
>>
>> --
>>  Kirill A. Shutemov

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-10-16 18:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-15  0:12 [PATCH 05/12] mm, thp, tmpfs: request huge page in shm_fault when needed Ning Qu
2013-10-15 10:37 ` Kirill A. Shutemov
2013-10-15 18:49   ` Ning Qu
2013-10-16 18:29     ` Ning Qu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).