From: John Hubbard <jhubbard@nvidia.com>
To: Andrew Morton <akpm@linux-foundation.org>, john.hubbard@gmail.com
Cc: Matthew Wilcox <willy@infradead.org>,
Michal Hocko <mhocko@kernel.org>,
Christopher Lameter <cl@linux.com>,
Jason Gunthorpe <jgg@ziepe.ca>,
Dan Williams <dan.j.williams@intel.com>, Jan Kara <jack@suse.cz>,
linux-mm@kvack.org, LKML <linux-kernel@vger.kernel.org>,
linux-rdma <linux-rdma@vger.kernel.org>,
linux-fsdevel@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>,
Jerome Glisse <jglisse@redhat.com>,
Christoph Hellwig <hch@infradead.org>,
Ralph Campbell <rcampbell@nvidia.com>
Subject: Re: [PATCH v4 2/3] mm: introduce put_user_page*(), placeholder versions
Date: Tue, 9 Oct 2018 17:42:09 -0700 [thread overview]
Message-ID: <5198a797-fa34-c859-ff9d-568834a85a83@nvidia.com> (raw)
In-Reply-To: <20181008171442.d3b3a1ea07d56c26d813a11e@linux-foundation.org>
On 10/8/18 5:14 PM, Andrew Morton wrote:
> On Mon, 8 Oct 2018 14:16:22 -0700 john.hubbard@gmail.com wrote:
>
>> From: John Hubbard <jhubbard@nvidia.com>
[...]
>> +/*
>> + * Pages that were pinned via get_user_pages*() should be released via
>> + * either put_user_page(), or one of the put_user_pages*() routines
>> + * below.
>> + */
>> +static inline void put_user_page(struct page *page)
>> +{
>> + put_page(page);
>> +}
>> +
>> +static inline void put_user_pages_dirty(struct page **pages,
>> + unsigned long npages)
>> +{
>> + unsigned long index;
>> +
>> + for (index = 0; index < npages; index++) {
>> + if (!PageDirty(pages[index]))
>
> Both put_page() and set_page_dirty() handle compound pages. But
> because of the above statement, put_user_pages_dirty() might misbehave?
> Or maybe it won't - perhaps the intent here is to skip dirtying the
> head page if the sub page is clean? Please clarify, explain and add
> comment if so.
>
Yes, technically, the accounting is wrong: we normally use the head page to
track dirtiness, and here, that is not done. (Nor was it done before this
patch). However, it's not causing problems in code today because sub pages
are released at about the same time as head pages, so the head page does get
properly checked at some point. And that means that set_page_dirty*() gets
called if it needs to be called.
Obviously this is a little fragile, in that it depends on the caller behaving
a certain way. And in any case, the long-term fix (coming later) *also* only
operates on the head page. So actually, instead of a comment, I think it's good
to just insert
page = compound_head(page);
...into these new routines, right now. I'll do that.
[...]
>
> Otherwise looks OK. Ish. But it would be nice if that comment were to
> explain *why* get_user_pages() pages must be released with
> put_user_page().
>
Yes, will do.
> Also, maintainability. What happens if someone now uses put_page() by
> mistake? Kernel fails in some mysterious fashion? How can we prevent
> this from occurring as code evolves? Is there a cheap way of detecting
> this bug at runtime?
>
It might be possible to do a few run-time checks, such as "does page that came
back to put_user_page() have the correct flags?", but it's harder (without
having a dedicated page flag) to detect the other direction: "did someone page
in a get_user_pages page, to put_page?"
As Jan said in his reply, converting get_user_pages (and put_user_page) to
work with a new data type that wraps struct pages, would solve it, but that's
an awfully large change. Still...given how much of a mess this can turn into
if it's wrong, I wonder if it's worth it--maybe?
thanks,
--
John Hubbard
NVIDIA
next prev parent reply other threads:[~2018-10-10 0:42 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-08 21:16 [PATCH v4 0/3] get_user_pages*() and RDMA: first steps john.hubbard
2018-10-08 21:16 ` [PATCH v4 1/3] mm: get_user_pages: consolidate error handling john.hubbard
2018-10-09 0:05 ` Andrew Morton
2018-10-08 21:16 ` [PATCH v4 2/3] mm: introduce put_user_page*(), placeholder versions john.hubbard
2018-10-09 0:14 ` Andrew Morton
2018-10-09 8:30 ` Jan Kara
2018-10-09 23:20 ` Andrew Morton
2018-10-10 0:32 ` John Hubbard
2018-10-10 23:43 ` Andrew Morton
2018-10-10 0:42 ` John Hubbard [this message]
2018-10-10 8:59 ` Jan Kara
2018-10-10 23:23 ` John Hubbard
2018-10-11 8:42 ` Jan Kara
2018-10-10 23:45 ` Andrew Morton
2018-10-11 8:49 ` Jan Kara
2018-10-11 13:20 ` Jason Gunthorpe
2018-10-12 1:23 ` John Hubbard
2018-10-12 3:53 ` John Hubbard
2018-10-18 10:19 ` Jan Kara
2018-11-05 7:25 ` John Hubbard
2018-10-22 19:43 ` Jason Gunthorpe
2018-11-05 7:17 ` John Hubbard
2018-11-05 8:37 ` Jan Kara
2018-10-08 21:16 ` [PATCH v4 3/3] infiniband/mm: convert put_page() to put_user_page*() john.hubbard
2018-10-09 9:52 ` kbuild test robot
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=5198a797-fa34-c859-ff9d-568834a85a83@nvidia.com \
--to=jhubbard@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=dan.j.williams@intel.com \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--cc=jgg@ziepe.ca \
--cc=jglisse@redhat.com \
--cc=john.hubbard@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mhocko@kernel.org \
--cc=rcampbell@nvidia.com \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/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