Thread (31 messages) 31 messages, 5 authors, 2022-09-01

Re: [PATCH 5/6] NFS: direct-io: convert to FOLL_PIN pages

From: Jan Kara <jack@suse.cz>
Date: 2022-08-29 16:08:18
Also in: linux-fsdevel, linux-mm, linux-nfs, linux-xfs, lkml

On Sun 28-08-22 21:59:49, John Hubbard wrote:
On 8/27/22 17:39, Al Viro wrote:
quoted
On Sun, Aug 28, 2022 at 01:38:57AM +0100, Al Viro wrote:
quoted
On Sat, Aug 27, 2022 at 04:55:18PM -0700, John Hubbard wrote:
quoted
On 8/27/22 15:48, Al Viro wrote:
quoted
On Sat, Aug 27, 2022 at 01:36:06AM -0700, John Hubbard wrote:
quoted
Convert the NFS Direct IO layer to use pin_user_pages_fast() and
unpin_user_page(), instead of get_user_pages_fast() and put_page().
Again, this stuff can be hit with ITER_BVEC iterators
quoted
-		result = iov_iter_get_pages_alloc2(iter, &pagevec,
+		result = dio_w_iov_iter_pin_pages_alloc(iter, &pagevec,
 						  rsize, &pgbase);
and this will break on those.
If anyone has an example handy, of a user space program that leads
to this situation (O_DIRECT with ITER_BVEC), it would really help
me reach enlightenment a lot quicker in this area. :)
Er...  splice(2) to O_DIRECT-opened file on e.g. ext4?  Or
sendfile(2) to the same, for that matter...
s/ext4/nfs/ to hit this particular codepath, obviously.
OK, I have a solution to this that's pretty easy:

1) Get rid of the user_backed_iter(i) check in
dio_w_iov_iter_pin_pages() and dio_w_iov_iter_pin_pages_alloc(), and

2) At the call sites, match up the unpin calls appropriately.

...and apply a similar fix for the fuse conversion patch.

However, the core block/bio conversion in patch 4 still does depend upon
a key assumption, which I got from a 2019 email discussion with
Christoph Hellwig and others here [1], which says:

    "All pages released by bio_release_pages should come from
     get_get_user_pages...".

I really hope that still holds true. Otherwise this whole thing is in
trouble.

[1] https://lore.kernel.org/kvm/20190724053053.GA18330@infradead.org/ (local)
Well as far as I've checked that discussion, Christoph was aware of pipe
pages etc. (i.e., bvecs) entering direct IO code. But he had some patches
[2] which enabled GUP to work for bvecs as well (using the kernel mapping
under the hood AFAICT from a quick glance at the series). I suppose we
could also handle this in __iov_iter_get_pages_alloc() by grabbing pin
reference instead of plain get_page() for the case of bvec iter. That way
we should have only pinned pages in bio_release_pages() even for the bvec
case.

[2] http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/gup-bvec

								Honza
-- 
Jan Kara [off-list ref]
SUSE Labs, CR
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help