Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rapidio: convert get_user_pages() --> pin_user_pages()

This code was using get_user_pages_fast(), in a "Case 2" scenario
(DMA/RDMA), using the categorization from [1]. That means that it's time
to convert the get_user_pages_fast() + put_page() calls to
pin_user_pages_fast() + 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.

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

[2] "Explicit pinning of user-space pages":
https://lwn.net/Articles/807108/

Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Alexandre Bounine <alex.bou9@gmail.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Link: http://lkml.kernel.org/r/20200517235620.205225-3-jhubbard@nvidia.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

John Hubbard and committed by
Linus Torvalds
67446283 e1c3cdb2

+5 -8
+5 -8
drivers/rapidio/devices/rio_mport_cdev.c
··· 572 572 struct mport_dma_req *req = container_of(ref, struct mport_dma_req, 573 573 refcount); 574 574 struct mport_cdev_priv *priv = req->priv; 575 - unsigned int i; 576 575 577 576 dma_unmap_sg(req->dmach->device->dev, 578 577 req->sgt.sgl, req->sgt.nents, req->dir); 579 578 sg_free_table(&req->sgt); 580 579 if (req->page_list) { 581 - for (i = 0; i < req->nr_pages; i++) 582 - put_page(req->page_list[i]); 580 + unpin_user_pages(req->page_list, req->nr_pages); 583 581 kfree(req->page_list); 584 582 } 585 583 ··· 813 815 struct mport_dma_req *req; 814 816 struct mport_dev *md = priv->md; 815 817 struct dma_chan *chan; 816 - int i, ret; 818 + int ret; 817 819 int nents; 818 820 819 821 if (xfer->length == 0) ··· 860 862 goto err_req; 861 863 } 862 864 863 - pinned = get_user_pages_fast( 865 + pinned = pin_user_pages_fast( 864 866 (unsigned long)xfer->loc_addr & PAGE_MASK, 865 867 nr_pages, 866 868 dir == DMA_FROM_DEVICE ? FOLL_WRITE : 0, ··· 868 870 869 871 if (pinned != nr_pages) { 870 872 if (pinned < 0) { 871 - rmcd_error("get_user_pages_unlocked err=%ld", 873 + rmcd_error("pin_user_pages_fast err=%ld", 872 874 pinned); 873 875 nr_pages = 0; 874 876 } else ··· 949 951 950 952 err_pg: 951 953 if (!req->page_list) { 952 - for (i = 0; i < nr_pages; i++) 953 - put_page(page_list[i]); 954 + unpin_user_pages(page_list, nr_pages); 954 955 kfree(page_list); 955 956 } 956 957 err_req: