2020-05-19 20:17:16

by John Hubbard

[permalink] [raw]
Subject: [PATCH v2] fpga: dfl: afu: 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/

Cc: Xu Yilun <[email protected]>
Cc: Wu Hao <[email protected]>
Cc: Moritz Fischer <[email protected]>
Cc: [email protected]
Signed-off-by: John Hubbard <[email protected]>
---

Hi,

Changes since v1:

Changed the label from "put_pages", to "unpin_pages".

thanks,
John Hubbard
NVIDIA

drivers/fpga/dfl-afu-dma-region.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c
index 62f924489db5..a31dd3a7e581 100644
--- a/drivers/fpga/dfl-afu-dma-region.c
+++ b/drivers/fpga/dfl-afu-dma-region.c
@@ -16,15 +16,6 @@

#include "dfl-afu.h"

-static void put_all_pages(struct page **pages, int npages)
-{
- int i;
-
- for (i = 0; i < npages; i++)
- if (pages[i])
- put_page(pages[i]);
-}
-
void afu_dma_region_init(struct dfl_feature_platform_data *pdata)
{
struct dfl_afu *afu = dfl_fpga_pdata_get_private(pdata);
@@ -57,11 +48,11 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
goto unlock_vm;
}

- pinned = get_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
+ pinned = pin_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
region->pages);
if (pinned < 0) {
ret = pinned;
- goto put_pages;
+ goto unpin_pages;
} else if (pinned != npages) {
ret = -EFAULT;
goto free_pages;
@@ -71,8 +62,8 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,

return 0;

-put_pages:
- put_all_pages(region->pages, pinned);
+unpin_pages:
+ unpin_user_pages(region->pages, pinned);
free_pages:
kfree(region->pages);
unlock_vm:
@@ -94,7 +85,7 @@ static void afu_dma_unpin_pages(struct dfl_feature_platform_data *pdata,
long npages = region->length >> PAGE_SHIFT;
struct device *dev = &pdata->dev->dev;

- put_all_pages(region->pages, npages);
+ unpin_user_pages(region->pages, npages);
kfree(region->pages);
account_locked_vm(current->mm, npages, false);

--
2.26.2


2020-05-23 01:55:39

by John Hubbard

[permalink] [raw]
Subject: Re: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

On 2020-05-19 13:14, John Hubbard wrote:
> 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/
>
> Cc: Xu Yilun <[email protected]>
> Cc: Wu Hao <[email protected]>
> Cc: Moritz Fischer <[email protected]>
> Cc: [email protected]
> Signed-off-by: John Hubbard <[email protected]>


Hi Moritz and FPGA developers,

Is this OK? And if so, is it going into your git tree? Or should I
send it up through a different tree? (I'm new to the FPGA development
model).


thanks,
--
John Hubbard
NVIDIA



> ---
>
> Hi,
>
> Changes since v1:
>
> Changed the label from "put_pages", to "unpin_pages".
>
> thanks,
> John Hubbard
> NVIDIA
>
> drivers/fpga/dfl-afu-dma-region.c | 19 +++++--------------
> 1 file changed, 5 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c
> index 62f924489db5..a31dd3a7e581 100644
> --- a/drivers/fpga/dfl-afu-dma-region.c
> +++ b/drivers/fpga/dfl-afu-dma-region.c
> @@ -16,15 +16,6 @@
>
> #include "dfl-afu.h"
>
> -static void put_all_pages(struct page **pages, int npages)
> -{
> - int i;
> -
> - for (i = 0; i < npages; i++)
> - if (pages[i])
> - put_page(pages[i]);
> -}
> -
> void afu_dma_region_init(struct dfl_feature_platform_data *pdata)
> {
> struct dfl_afu *afu = dfl_fpga_pdata_get_private(pdata);
> @@ -57,11 +48,11 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
> goto unlock_vm;
> }
>
> - pinned = get_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
> + pinned = pin_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
> region->pages);
> if (pinned < 0) {
> ret = pinned;
> - goto put_pages;
> + goto unpin_pages;
> } else if (pinned != npages) {
> ret = -EFAULT;
> goto free_pages;
> @@ -71,8 +62,8 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
>
> return 0;
>
> -put_pages:
> - put_all_pages(region->pages, pinned);
> +unpin_pages:
> + unpin_user_pages(region->pages, pinned);
> free_pages:
> kfree(region->pages);
> unlock_vm:
> @@ -94,7 +85,7 @@ static void afu_dma_unpin_pages(struct dfl_feature_platform_data *pdata,
> long npages = region->length >> PAGE_SHIFT;
> struct device *dev = &pdata->dev->dev;
>
> - put_all_pages(region->pages, npages);
> + unpin_user_pages(region->pages, npages);
> kfree(region->pages);
> account_locked_vm(current->mm, npages, false);
>
>

2020-05-23 21:00:45

by Moritz Fischer

[permalink] [raw]
Subject: Re: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

On Fri, May 22, 2020 at 06:52:34PM -0700, John Hubbard wrote:
> On 2020-05-19 13:14, John Hubbard wrote:
> > 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/
> >
> > Cc: Xu Yilun <[email protected]>
> > Cc: Wu Hao <[email protected]>
> > Cc: Moritz Fischer <[email protected]>
> > Cc: [email protected]
> > Signed-off-by: John Hubbard <[email protected]>
>
>
> Hi Moritz and FPGA developers,
>
> Is this OK? And if so, is it going into your git tree? Or should I
> send it up through a different tree? (I'm new to the FPGA development
> model).

I can take it, sorry for sluggish response.

Cheers,
Moritz

>
>
> thanks,
> --
> John Hubbard
> NVIDIA
>
>
>
> > ---
> >
> > Hi,
> >
> > Changes since v1:
> >
> > Changed the label from "put_pages", to "unpin_pages".
> >
> > thanks,
> > John Hubbard
> > NVIDIA
> > drivers/fpga/dfl-afu-dma-region.c | 19 +++++--------------
> > 1 file changed, 5 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c
> > index 62f924489db5..a31dd3a7e581 100644
> > --- a/drivers/fpga/dfl-afu-dma-region.c
> > +++ b/drivers/fpga/dfl-afu-dma-region.c
> > @@ -16,15 +16,6 @@
> > #include "dfl-afu.h"
> > -static void put_all_pages(struct page **pages, int npages)
> > -{
> > - int i;
> > -
> > - for (i = 0; i < npages; i++)
> > - if (pages[i])
> > - put_page(pages[i]);
> > -}
> > -
> > void afu_dma_region_init(struct dfl_feature_platform_data *pdata)
> > {
> > struct dfl_afu *afu = dfl_fpga_pdata_get_private(pdata);
> > @@ -57,11 +48,11 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
> > goto unlock_vm;
> > }
> > - pinned = get_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
> > + pinned = pin_user_pages_fast(region->user_addr, npages, FOLL_WRITE,
> > region->pages);
> > if (pinned < 0) {
> > ret = pinned;
> > - goto put_pages;
> > + goto unpin_pages;
> > } else if (pinned != npages) {
> > ret = -EFAULT;
> > goto free_pages;
> > @@ -71,8 +62,8 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata,
> > return 0;
> > -put_pages:
> > - put_all_pages(region->pages, pinned);
> > +unpin_pages:
> > + unpin_user_pages(region->pages, pinned);
> > free_pages:
> > kfree(region->pages);
> > unlock_vm:
> > @@ -94,7 +85,7 @@ static void afu_dma_unpin_pages(struct dfl_feature_platform_data *pdata,
> > long npages = region->length >> PAGE_SHIFT;
> > struct device *dev = &pdata->dev->dev;
> > - put_all_pages(region->pages, npages);
> > + unpin_user_pages(region->pages, npages);
> > kfree(region->pages);
> > account_locked_vm(current->mm, npages, false);
> >
>

2020-05-23 21:35:11

by John Hubbard

[permalink] [raw]
Subject: Re: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

On 2020-05-23 13:57, Moritz Fischer wrote:
> On Fri, May 22, 2020 at 06:52:34PM -0700, John Hubbard wrote:
>> On 2020-05-19 13:14, John Hubbard wrote:
>>> 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/
>>>
>>> Cc: Xu Yilun <[email protected]>
>>> Cc: Wu Hao <[email protected]>
>>> Cc: Moritz Fischer <[email protected]>
>>> Cc: [email protected]
>>> Signed-off-by: John Hubbard <[email protected]>
>>
>>
>> Hi Moritz and FPGA developers,
>>
>> Is this OK? And if so, is it going into your git tree? Or should I
>> send it up through a different tree? (I'm new to the FPGA development
>> model).
>
> I can take it, sorry for sluggish response.
>

That's great news, thanks Moritz! Sorry to be pushy, just didn't want it
to get lost. :)

thanks,
--
John Hubbard
NVIDIA

2020-05-25 02:28:45

by Wu Hao

[permalink] [raw]
Subject: RE: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

> >> Hi Moritz and FPGA developers,
> >>
> >> Is this OK? And if so, is it going into your git tree? Or should I
> >> send it up through a different tree? (I'm new to the FPGA development
> >> model).
> >
> > I can take it, sorry for sluggish response.
> >
>
> That's great news, thanks Moritz! Sorry to be pushy, just didn't want it
> to get lost. :)

Thanks John for this patch, and thanks Moritz for taking care of this.
Sorry for late response, one thing here we may need to be careful is
a recent bug fixing patch, that fixing patch has been merged by Greg
in char-misc-next tree, and may have some conflict with this one.

https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/commit/?h=char-misc-next&id=c9d7e3da1f3c4cf5dddfc5d7ce4d76d013aba1cc
fpga: dfl: afu: Corrected error handling levels

I guess we need to rebase this patch on top of it?
Moritz, do you have any suggestion?

Thanks
Hao

>
> thanks,
> --
> John Hubbard
> NVIDIA

2020-05-25 02:49:41

by John Hubbard

[permalink] [raw]
Subject: Re: [PATCH v2] fpga: dfl: afu: convert get_user_pages() --> pin_user_pages()

On 2020-05-24 19:25, Wu, Hao wrote:
>>>> Hi Moritz and FPGA developers,
>>>>
>>>> Is this OK? And if so, is it going into your git tree? Or should I
>>>> send it up through a different tree? (I'm new to the FPGA development
>>>> model).
>>>
>>> I can take it, sorry for sluggish response.
>>>
>>
>> That's great news, thanks Moritz! Sorry to be pushy, just didn't want it
>> to get lost. :)
>
> Thanks John for this patch, and thanks Moritz for taking care of this.
> Sorry for late response, one thing here we may need to be careful is
> a recent bug fixing patch, that fixing patch has been merged by Greg
> in char-misc-next tree, and may have some conflict with this one.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/commit/?h=char-misc-next&id=c9d7e3da1f3c4cf5dddfc5d7ce4d76d013aba1cc
> fpga: dfl: afu: Corrected error handling levels
>
> I guess we need to rebase this patch on top of it?
> Moritz, do you have any suggestion?
>

I'll send you a v2, rebased on top of the latest char-misc.git, no problem.

thanks,
--
John Hubbard
NVIDIA