Re: [PATCH] scsi: st: convert convert get_user_pages() --> pin_user_pages()

From: John Hubbard
Date: Tue May 26 2020 - 14:15:33 EST

On 2020-05-22 01:32, "Kai MÃkisara (Kolumbus)" wrote:
On 21. May 2020, at 22.47, Bart Van Assche <bvanassche@xxxxxxx> wrote:

On 2020-05-18 21:55, John Hubbard wrote:
This code was using get_user_pages*(), in a "Case 2" scenario
(DMA/RDMA), using the categorization from [1]. That means that it's
time to convert the get_user_pages*() + put_page() calls to
pin_user_pages*() + unpin_user_pages() calls.

There is some helpful background in [2]: basically, this is a small
part of fixing a long-standing disconnect between pinning pages, and
file systems' use of those pages.

Note that this effectively changes the code's behavior as well: it now
ultimately calls set_page_dirty_lock(), instead of SetPageDirty().This
is probably more accurate.

As Christoph Hellwig put it, "set_page_dirty() is only safe if we are
dealing with a file backed page where we have reference on the inode it
hangs off." [3]

Also, this deletes one of the two FIXME comments (about refcounting),
because there is nothing wrong with the refcounting at this point.

[1] Documentation/core-api/pin_user_pages.rst

[2] "Explicit pinning of user-space pages":


Kai, why is the st driver calling get_user_pages_fast() directly instead
of calling blk_rq_map_user()? blk_rq_map_user() is already used in
st_scsi_execute(). I think that the blk_rq_map_user() implementation is
also based on get_user_pages_fast(). See also iov_iter_get_pages_alloc()
in lib/iov_iter.c.

The reason is that the blk_ functions were not available when that part
of the code was done. Nobody has converted that to use the more
modern functions because the old method still works.

Hi Kai, Bart,

Say, thinking about this some more, it seems like: as only sgl_unmap_user_pages()
is allowed to release the pages that were pinned in sgl_map_user_pages(), then
this is a clear case of Direct IO (not DMA/RDMA, as I first thought) that needs
to be handled via pin_user_pages_fast().

I'll send a v2 with the commit log updated to refer to Direct IO, because this
does still apply, after all.

John Hubbard