linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: John Hubbard <jhubbard@nvidia.com>
To: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Peter Xu <peterx@redhat.com>, Jason Gunthorpe <jgg@ziepe.ca>,
	David Hildenbrand <david@redhat.com>,
	Lukas Bulwahn <lukas.bulwahn@gmail.com>, Jan Kara <jack@suse.cz>,
	"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
	Alex Williamson <alex.williamson@redhat.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-mm@kvack.org, Jason Gunthorpe <jgg@nvidia.com>
Subject: Re: [PATCH v3 2/4] mm/gup: clean up follow_pfn_pte() slightly
Date: Thu, 3 Feb 2022 12:53:19 -0800	[thread overview]
Message-ID: <a73fbb8a-e98a-975d-613c-d88a6091a326@nvidia.com> (raw)
In-Reply-To: <20220203143114.42d59bbe@p-imbrenda>

On 2/3/22 05:31, Claudio Imbrenda wrote:
...
>> @@ -1180,8 +1176,13 @@ static long __get_user_pages(struct mm_struct *mm,
>>   		} else if (PTR_ERR(page) == -EEXIST) {
>>   			/*
>>   			 * Proper page table entry exists, but no corresponding
>> -			 * struct page.
>> +			 * struct page. If the caller expects **pages to be
>> +			 * filled in, bail out now, because that can't be done
>> +			 * for this page.
>>   			 */
>> +			if (pages)
>> +				goto out;
>> +
>>   			goto next_page;
>>   		} else if (IS_ERR(page)) {
>>   			ret = PTR_ERR(page);
> 
> I'm not an expert, can you explain why this is better, and why it does
> not cause new issues?
> 
> If I understand correctly, the problem you are trying to solve is that
> in some cases you might try to get n pages, but you only get m < n
> pages instead, because some don't have an associated struct page, and
> the missing pages might even be in the middle.
> 
> The `pages` array would contain the list of pages actually pinned
> (getted?), but this won't tell which of the requested pages have been
> pinned (e.g. if some pages in the middle of the run were skipped)
> 

The get_user_pages() API doesn't leave pages in the middle, ever.
Instead, it stops at the first error, and reports the number of page
that were successfully pinned. And the caller is responsible for
unpinning.

 From __get_user_pages()'s kerneldoc documentation:

  * Returns either number of pages pinned (which may be less than the
  * number requested), or an error. Details about the return value:
  *
  * -- If nr_pages is 0, returns 0.
  * -- If nr_pages is >0, but no pages were pinned, returns -errno.
  * -- If nr_pages is >0, and some pages were pinned, returns the number of
  *    pages pinned. Again, this may be less than nr_pages.
  * -- 0 return value is possible when the fault would need to be retried.
  *
  * The caller is responsible for releasing returned @pages, via put_page().

So the **pages array doesn't have holes, and the caller just counts up
from the beginning of **pages and stops at nr_pages.


> With your patch you will stop at the first page without a struct page,
> meaning that if the caller tries again, it will get 0 pages. Why won't
> this cause issues?

Callers are already written to deal with this case.

> 
> Why will this not cause problems when the `pages` parameter is NULL?

The behavior is unchanged here if pages == NULL. But maybe you meant,
if pages != NULL. And in that case, the new behavior is to stop early
and return n < m, which is (I am claiming) better than just leaving
garbage values in **pages.

Another approach would be to file in PTR_ERR(page) values, but GUP is
a well-established and widely used API, and that would be a large
change that would require changing a lot of caller code.

> 
> 
> sorry for the dumb questions, but this seems a rather important change,
> and I think in these circumstances you can't have too much
> documentation.
> 

Thanks for reviewing this!


thanks,
-- 
John Hubbard
NVIDIA


  reply	other threads:[~2022-02-03 20:53 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-03  9:32 [PATCH v3 0/4] mm/gup: some cleanups John Hubbard
2022-02-03  9:32 ` [PATCH v3 1/4] mm: Fix invalid page pointer returned with FOLL_PIN gups John Hubbard
2022-02-03 12:10   ` Claudio Imbrenda
2022-02-03 21:25     ` John Hubbard
2022-02-03 14:00   ` Christoph Hellwig
2022-02-03 21:13     ` John Hubbard
2022-02-03  9:32 ` [PATCH v3 2/4] mm/gup: clean up follow_pfn_pte() slightly John Hubbard
2022-02-03 13:31   ` Claudio Imbrenda
2022-02-03 20:53     ` John Hubbard [this message]
2022-02-03 13:53   ` Jan Kara
2022-02-03 15:01     ` Jason Gunthorpe
2022-02-03 15:18       ` Matthew Wilcox
2022-02-03 21:19         ` John Hubbard
2022-02-03  9:32 ` [PATCH v3 3/4] mm/gup: remove unused pin_user_pages_locked() John Hubbard
2022-02-03 11:52   ` Claudio Imbrenda
2022-02-03  9:32 ` [PATCH v3 4/4] mm/gup: remove get_user_pages_locked() John Hubbard
2022-02-03 12:04   ` Claudio Imbrenda
2022-02-03 14:01   ` Christoph Hellwig
2022-02-03 21:27     ` John Hubbard

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=a73fbb8a-e98a-975d-613c-d88a6091a326@nvidia.com \
    --to=jhubbard@nvidia.com \
    --cc=aarcange@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.williamson@redhat.com \
    --cc=david@redhat.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=jack@suse.cz \
    --cc=jgg@nvidia.com \
    --cc=jgg@ziepe.ca \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lukas.bulwahn@gmail.com \
    --cc=peterx@redhat.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