linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Punit Agrawal <punit.agrawal@arm.com>
To: daniel.m.jordan@oracle.com
Cc: linux-mm@kvack.org, aarcange@redhat.com,
	akpm@linux-foundation.org, aneesh.kumar@linux.vnet.ibm.com,
	gerald.schaefer@de.ibm.com, james.morse@arm.com,
	kirill.shutemov@linux.intel.com, mhocko@suse.com,
	mike.kravetz@oracle.com, n-horiguchi@ah.jp.nec.com,
	zhongjiang@huawei.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mm/hugetlb: __get_user_pages ignores certain follow_hugetlb_page errors
Date: Fri, 21 Jul 2017 10:20:50 +0100	[thread overview]
Message-ID: <87o9sekux9.fsf@e105922-lin.cambridge.arm.com> (raw)
In-Reply-To: <1500406795-58462-1-git-send-email-daniel.m.jordan@oracle.com> (daniel m. jordan's message of "Tue, 18 Jul 2017 12:39:55 -0700")

Hi Daniel,

daniel.m.jordan@oracle.com writes:

> Commit 9a291a7c9428 ("mm/hugetlb: report -EHWPOISON not -EFAULT when
> FOLL_HWPOISON is specified") causes __get_user_pages to ignore certain
> errors from follow_hugetlb_page.  After such error, __get_user_pages
> subsequently calls faultin_page on the same VMA and start address that
> follow_hugetlb_page failed on instead of returning the error immediately
> as it should.
>
> In follow_hugetlb_page, when hugetlb_fault returns a value covered under
> VM_FAULT_ERROR, follow_hugetlb_page returns it without setting nr_pages
> to 0 as __get_user_pages expects in this case, which causes the
> following to happen in __get_user_pages: the "while (nr_pages)" check
> succeeds, we skip the "if (!vma..." check because we got a VMA the last
> time around, we find no page with follow_page_mask, and we call
> faultin_page, which calls hugetlb_fault for the second time.
>
> This issue also slightly changes how __get_user_pages works.  Before, it
> only returned error if it had made no progress (i = 0).  But now,
> follow_hugetlb_page can clobber "i" with an error code since its new
> return path doesn't check for progress.  So if "i" is nonzero before a
> failing call to follow_hugetlb_page, that indication of progress is lost
> and __get_user_pages can return error even if some pages were
> successfully pinned.
>
> To fix this, change follow_hugetlb_page so that it updates nr_pages,
> allowing __get_user_pages to fail immediately and restoring the "error
> only if no progress" behavior to __get_user_pages.
>
> Tested that __get_user_pages returns when expected on error from
> hugetlb_fault in follow_hugetlb_page.
>
> Fixes: 9a291a7c9428 ("mm/hugetlb: report -EHWPOISON not -EFAULT when FOLL_HWPOISON is specified")
> Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com>
> Cc: Andrea Arcangeli <aarcange@redhat.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Kravetz <mike.kravetz@oracle.com>
> Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
> Cc: Punit Agrawal <punit.agrawal@arm.com>
> Cc: zhong jiang <zhongjiang@huawei.com>
> ---
>  mm/hugetlb.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index 3eedb18..cc28993 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -4095,6 +4095,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
>  	unsigned long vaddr = *position;
>  	unsigned long remainder = *nr_pages;
>  	struct hstate *h = hstate_vma(vma);
> +	int err = -EFAULT;
>  
>  	while (vaddr < vma->vm_end && remainder) {
>  		pte_t *pte;
> @@ -4170,11 +4171,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
>  			}
>  			ret = hugetlb_fault(mm, vma, vaddr, fault_flags);
>  			if (ret & VM_FAULT_ERROR) {
> -				int err = vm_fault_to_errno(ret, flags);
> -
> -				if (err)
> -					return err;
> -
> +				err = vm_fault_to_errno(ret, flags);
>  				remainder = 0;
>  				break;
>  			}
> @@ -4229,7 +4226,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
>  	 */
>  	*position = vaddr;
>  
> -	return i ? i : -EFAULT;
> +	return i ? i : err;
>  }
>  
>  #ifndef __HAVE_ARCH_FLUSH_HUGETLB_TLB_RANGE

The change makes sense.

FWIW,

Acked-by: Punit Agrawal <punit.agrawal@arm.com>

I was wondering how you hit the issue. Is there a test case that could
have spotted this earlier?

Thanks,
Punit

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2017-07-21  9:20 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-18 19:39 [PATCH] mm/hugetlb: __get_user_pages ignores certain follow_hugetlb_page errors daniel.m.jordan
2017-07-21  9:20 ` Punit Agrawal [this message]
2017-07-22  0:05   ` Daniel Jordan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o9sekux9.fsf@e105922-lin.cambridge.arm.com \
    --to=punit.agrawal@arm.com \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=daniel.m.jordan@oracle.com \
    --cc=gerald.schaefer@de.ibm.com \
    --cc=james.morse@arm.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=mike.kravetz@oracle.com \
    --cc=n-horiguchi@ah.jp.nec.com \
    --cc=zhongjiang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).