2019-02-07 05:38:57

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH -tip 0/2] more get_user_pages mmap_sem cleanups

Hi,

Here are two more patchlets that cleanup mmap_sem and gup abusers.
The second is also a fixlet.

Compile-tested only. Please consider for v5.1

Thanks!

Davidlohr Bueso (2):
xsk: do not use mmap_sem
MIPS/c-r4k: do no use mmap_sem for gup_fast()

arch/mips/mm/c-r4k.c | 6 +-----
net/xdp/xdp_umem.c | 6 ++----
2 files changed, 3 insertions(+), 9 deletions(-)

--
2.16.4



2019-02-07 05:40:17

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 1/2] xsk: do not use mmap_sem

Holding mmap_sem exclusively for a gup() is an overkill.
Lets replace the call for gup_fast() and let the mm take
it if necessary.

Cc: David S. Miller <[email protected]>
Cc: Bjorn Topel <[email protected]>
Cc: Magnus Karlsson <[email protected]>
CC: [email protected]
Signed-off-by: Davidlohr Bueso <[email protected]>
---
net/xdp/xdp_umem.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
index 5ab236c5c9a5..25e1e76654a8 100644
--- a/net/xdp/xdp_umem.c
+++ b/net/xdp/xdp_umem.c
@@ -265,10 +265,8 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
if (!umem->pgs)
return -ENOMEM;

- down_write(&current->mm->mmap_sem);
- npgs = get_user_pages(umem->address, umem->npgs,
- gup_flags, &umem->pgs[0], NULL);
- up_write(&current->mm->mmap_sem);
+ npgs = get_user_pages_fast(umem->address, umem->npgs,
+ gup_flags, &umem->pgs[0]);

if (npgs != umem->npgs) {
if (npgs >= 0) {
--
2.16.4


2019-02-07 05:40:31

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH 2/2] MIPS/c-r4k: do no use mmap_sem for gup_fast()

It is well known that because the mm can internally
call the regular gup_unlocked if the lockless approach
fails and take the sem there, the caller must not hold
the mmap_sem already.

Fixes: e523f289fe4d (MIPS: c-r4k: Fix sigtramp SMP call to use kmap)
Cc: Ralf Baechle <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Signed-off-by: Davidlohr Bueso <[email protected]>
---
arch/mips/mm/c-r4k.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index cc4e17caeb26..38fe86928837 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1034,11 +1034,9 @@ static void r4k_flush_cache_sigtramp(unsigned long addr)
struct flush_cache_sigtramp_args args;
int npages;

- down_read(&current->mm->mmap_sem);
-
npages = get_user_pages_fast(addr, 1, 0, &args.page);
if (npages < 1)
- goto out;
+ return;

args.mm = current->mm;
args.addr = addr;
@@ -1046,8 +1044,6 @@ static void r4k_flush_cache_sigtramp(unsigned long addr)
r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args);

put_page(args.page);
-out:
- up_read(&current->mm->mmap_sem);
}

static void r4k_flush_icache_all(void)
--
2.16.4


2019-02-07 05:52:37

by Davidlohr Bueso

[permalink] [raw]
Subject: Re: [PATCH -tip 0/2] more get_user_pages mmap_sem cleanups

Unlike what the subject says, this is not against -tip, it applies
on today's -next.

On Wed, 06 Feb 2019, Davidlohr Bueso wrote:

>Hi,
>
>Here are two more patchlets that cleanup mmap_sem and gup abusers.
>The second is also a fixlet.
>
>Compile-tested only. Please consider for v5.1
>
>Thanks!
>
>Davidlohr Bueso (2):
> xsk: do not use mmap_sem
> MIPS/c-r4k: do no use mmap_sem for gup_fast()
>
> arch/mips/mm/c-r4k.c | 6 +-----
> net/xdp/xdp_umem.c | 6 ++----
> 2 files changed, 3 insertions(+), 9 deletions(-)
>
>--
>2.16.4
>

2019-02-07 07:43:44

by Björn Töpel

[permalink] [raw]
Subject: Re: [PATCH 1/2] xsk: do not use mmap_sem

Den tors 7 feb. 2019 kl 06:38 skrev Davidlohr Bueso <[email protected]>:
>
> Holding mmap_sem exclusively for a gup() is an overkill.
> Lets replace the call for gup_fast() and let the mm take
> it if necessary.
>
> Cc: David S. Miller <[email protected]>
> Cc: Bjorn Topel <[email protected]>
> Cc: Magnus Karlsson <[email protected]>
> CC: [email protected]
> Signed-off-by: Davidlohr Bueso <[email protected]>
> ---
> net/xdp/xdp_umem.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
> index 5ab236c5c9a5..25e1e76654a8 100644
> --- a/net/xdp/xdp_umem.c
> +++ b/net/xdp/xdp_umem.c
> @@ -265,10 +265,8 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
> if (!umem->pgs)
> return -ENOMEM;
>
> - down_write(&current->mm->mmap_sem);
> - npgs = get_user_pages(umem->address, umem->npgs,
> - gup_flags, &umem->pgs[0], NULL);
> - up_write(&current->mm->mmap_sem);
> + npgs = get_user_pages_fast(umem->address, umem->npgs,
> + gup_flags, &umem->pgs[0]);
>

Thanks for the patch!

The lifetime of the pinning is similar to RDMA umem mapping, so isn't
gup_longterm preferred?


Björn

> if (npgs != umem->npgs) {
> if (npgs >= 0) {
> --
> 2.16.4
>

2019-02-07 19:01:09

by Paul Burton

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS/c-r4k: do no use mmap_sem for gup_fast()

Hi Davidlohr,

On Wed, Feb 06, 2019 at 09:37:40PM -0800, Davidlohr Bueso wrote:
> It is well known that because the mm can internally
> call the regular gup_unlocked if the lockless approach
> fails and take the sem there, the caller must not hold
> the mmap_sem already.
>
> Fixes: e523f289fe4d (MIPS: c-r4k: Fix sigtramp SMP call to use kmap)
> Cc: Ralf Baechle <[email protected]>
> Cc: Paul Burton <[email protected]>
> Cc: James Hogan <[email protected]>
> Cc: [email protected]
> Signed-off-by: Davidlohr Bueso <[email protected]>

Thanks - this looks good, but:

1) The problem it fixes was introduced in v4.8.

2) Commit adcc81f148d7 ("MIPS: math-emu: Write-protect delay slot
emulation pages") actually left flush_cache_sigtramp unused, and has
been backported to stable kernels also as far as v4.8.

Therefore this will just fix code that never gets called, and I'll go
delete the whole thing instead.

Thanks,
Paul

2019-02-07 19:26:27

by Davidlohr Bueso

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS/c-r4k: do no use mmap_sem for gup_fast()

On Thu, 07 Feb 2019, Paul Burton wrote:

>Hi Davidlohr,
>
>On Wed, Feb 06, 2019 at 09:37:40PM -0800, Davidlohr Bueso wrote:
>> It is well known that because the mm can internally
>> call the regular gup_unlocked if the lockless approach
>> fails and take the sem there, the caller must not hold
>> the mmap_sem already.
>>
>> Fixes: e523f289fe4d (MIPS: c-r4k: Fix sigtramp SMP call to use kmap)
>> Cc: Ralf Baechle <[email protected]>
>> Cc: Paul Burton <[email protected]>
>> Cc: James Hogan <[email protected]>
>> Cc: [email protected]
>> Signed-off-by: Davidlohr Bueso <[email protected]>
>
>Thanks - this looks good, but:
>
> 1) The problem it fixes was introduced in v4.8.
>
> 2) Commit adcc81f148d7 ("MIPS: math-emu: Write-protect delay slot
> emulation pages") actually left flush_cache_sigtramp unused, and has
> been backported to stable kernels also as far as v4.8.
>
>Therefore this will just fix code that never gets called, and I'll go
>delete the whole thing instead.

Even better.

Thanks,
Davidlohr

2019-02-11 15:36:01

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH 1/2] xsk: do not use mmap_sem

[ +Dan ]

On 02/07/2019 08:43 AM, Björn Töpel wrote:
> Den tors 7 feb. 2019 kl 06:38 skrev Davidlohr Bueso <[email protected]>:
>>
>> Holding mmap_sem exclusively for a gup() is an overkill.
>> Lets replace the call for gup_fast() and let the mm take
>> it if necessary.
>>
>> Cc: David S. Miller <[email protected]>
>> Cc: Bjorn Topel <[email protected]>
>> Cc: Magnus Karlsson <[email protected]>
>> CC: [email protected]
>> Signed-off-by: Davidlohr Bueso <[email protected]>
>> ---
>> net/xdp/xdp_umem.c | 6 ++----
>> 1 file changed, 2 insertions(+), 4 deletions(-)
>>
>> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
>> index 5ab236c5c9a5..25e1e76654a8 100644
>> --- a/net/xdp/xdp_umem.c
>> +++ b/net/xdp/xdp_umem.c
>> @@ -265,10 +265,8 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
>> if (!umem->pgs)
>> return -ENOMEM;
>>
>> - down_write(&current->mm->mmap_sem);
>> - npgs = get_user_pages(umem->address, umem->npgs,
>> - gup_flags, &umem->pgs[0], NULL);
>> - up_write(&current->mm->mmap_sem);
>> + npgs = get_user_pages_fast(umem->address, umem->npgs,
>> + gup_flags, &umem->pgs[0]);
>>
>
> Thanks for the patch!
>
> The lifetime of the pinning is similar to RDMA umem mapping, so isn't
> gup_longterm preferred?

Seems reasonable from reading what gup_longterm seems to do. Davidlohr
or Dan, any thoughts on the above?

Thanks,
Daniel

2019-02-11 16:17:07

by Davidlohr Bueso

[permalink] [raw]
Subject: [PATCH v2] xsk: share the mmap_sem for page pinning

Holding mmap_sem exclusively for a gup() is an overkill.
Lets share the lock and replace the gup call for gup_longterm(),
as it is better suited for the lifetime of the pinning.

Cc: David S. Miller <[email protected]>
Cc: Bjorn Topel <[email protected]>
Cc: Magnus Karlsson <[email protected]>
CC: [email protected]
Signed-off-by: Davidlohr Bueso <[email protected]>
---
net/xdp/xdp_umem.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
index 5ab236c5c9a5..e7fa8d0d7090 100644
--- a/net/xdp/xdp_umem.c
+++ b/net/xdp/xdp_umem.c
@@ -265,10 +265,10 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
if (!umem->pgs)
return -ENOMEM;

- down_write(&current->mm->mmap_sem);
- npgs = get_user_pages(umem->address, umem->npgs,
+ down_read(&current->mm->mmap_sem);
+ npgs = get_user_pages_longterm(umem->address, umem->npgs,
gup_flags, &umem->pgs[0], NULL);
- up_write(&current->mm->mmap_sem);
+ up_read(&current->mm->mmap_sem);

if (npgs != umem->npgs) {
if (npgs >= 0) {
--
2.16.4


2019-02-11 16:23:35

by Björn Töpel

[permalink] [raw]
Subject: Re: [PATCH v2] xsk: share the mmap_sem for page pinning

Den mån 11 feb. 2019 kl 17:15 skrev Davidlohr Bueso <[email protected]>:
>
> Holding mmap_sem exclusively for a gup() is an overkill.
> Lets share the lock and replace the gup call for gup_longterm(),
> as it is better suited for the lifetime of the pinning.
>

Thanks for the cleanup!

Acked-by: Björn Töpel <[email protected]>

> Cc: David S. Miller <[email protected]>
> Cc: Bjorn Topel <[email protected]>
> Cc: Magnus Karlsson <[email protected]>
> CC: [email protected]
> Signed-off-by: Davidlohr Bueso <[email protected]>
> ---
> net/xdp/xdp_umem.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
> index 5ab236c5c9a5..e7fa8d0d7090 100644
> --- a/net/xdp/xdp_umem.c
> +++ b/net/xdp/xdp_umem.c
> @@ -265,10 +265,10 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
> if (!umem->pgs)
> return -ENOMEM;
>
> - down_write(&current->mm->mmap_sem);
> - npgs = get_user_pages(umem->address, umem->npgs,
> + down_read(&current->mm->mmap_sem);
> + npgs = get_user_pages_longterm(umem->address, umem->npgs,
> gup_flags, &umem->pgs[0], NULL);
> - up_write(&current->mm->mmap_sem);
> + up_read(&current->mm->mmap_sem);
>
> if (npgs != umem->npgs) {
> if (npgs >= 0) {
> --
> 2.16.4
>

2019-02-11 16:39:57

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH 1/2] xsk: do not use mmap_sem

[ add Ira ]

On Mon, Feb 11, 2019 at 7:33 AM Daniel Borkmann <[email protected]> wrote:
>
> [ +Dan ]
>
> On 02/07/2019 08:43 AM, Björn Töpel wrote:
> > Den tors 7 feb. 2019 kl 06:38 skrev Davidlohr Bueso <[email protected]>:
> >>
> >> Holding mmap_sem exclusively for a gup() is an overkill.
> >> Lets replace the call for gup_fast() and let the mm take
> >> it if necessary.
> >>
> >> Cc: David S. Miller <[email protected]>
> >> Cc: Bjorn Topel <[email protected]>
> >> Cc: Magnus Karlsson <[email protected]>
> >> CC: [email protected]
> >> Signed-off-by: Davidlohr Bueso <[email protected]>
> >> ---
> >> net/xdp/xdp_umem.c | 6 ++----
> >> 1 file changed, 2 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c
> >> index 5ab236c5c9a5..25e1e76654a8 100644
> >> --- a/net/xdp/xdp_umem.c
> >> +++ b/net/xdp/xdp_umem.c
> >> @@ -265,10 +265,8 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem)
> >> if (!umem->pgs)
> >> return -ENOMEM;
> >>
> >> - down_write(&current->mm->mmap_sem);
> >> - npgs = get_user_pages(umem->address, umem->npgs,
> >> - gup_flags, &umem->pgs[0], NULL);
> >> - up_write(&current->mm->mmap_sem);
> >> + npgs = get_user_pages_fast(umem->address, umem->npgs,
> >> + gup_flags, &umem->pgs[0]);
> >>
> >
> > Thanks for the patch!
> >
> > The lifetime of the pinning is similar to RDMA umem mapping, so isn't
> > gup_longterm preferred?
>
> Seems reasonable from reading what gup_longterm seems to do. Davidlohr
> or Dan, any thoughts on the above?

Yes, any gup where the lifetime of the corresponding put_page() is
under direct control of userspace should be using the _longterm flavor
to coordinate be careful in the presence of dax. In the dax case there
is no page cache indirection to coordinate truncate vs page pins. Ira
is looking to add a "fast + longterm" flavor for cases like this.

2019-02-11 20:31:27

by Ira Weiny

[permalink] [raw]
Subject: RE: [PATCH 1/2] xsk: do not use mmap_sem

> > >> ---
> > >> net/xdp/xdp_umem.c | 6 ++----
> > >> 1 file changed, 2 insertions(+), 4 deletions(-)
> > >>
> > >> diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c index
> > >> 5ab236c5c9a5..25e1e76654a8 100644
> > >> --- a/net/xdp/xdp_umem.c
> > >> +++ b/net/xdp/xdp_umem.c
> > >> @@ -265,10 +265,8 @@ static int xdp_umem_pin_pages(struct
> xdp_umem *umem)
> > >> if (!umem->pgs)
> > >> return -ENOMEM;
> > >>
> > >> - down_write(&current->mm->mmap_sem);
> > >> - npgs = get_user_pages(umem->address, umem->npgs,
> > >> - gup_flags, &umem->pgs[0], NULL);
> > >> - up_write(&current->mm->mmap_sem);
> > >> + npgs = get_user_pages_fast(umem->address, umem->npgs,
> > >> + gup_flags, &umem->pgs[0]);
> > >>
> > >
> > > Thanks for the patch!
> > >
> > > The lifetime of the pinning is similar to RDMA umem mapping, so
> > > isn't gup_longterm preferred?
> >
> > Seems reasonable from reading what gup_longterm seems to do. Davidlohr
> > or Dan, any thoughts on the above?
>
> Yes, any gup where the lifetime of the corresponding put_page() is under
> direct control of userspace should be using the _longterm flavor to
> coordinate be careful in the presence of dax. In the dax case there is no page
> cache indirection to coordinate truncate vs page pins. Ira is looking to add a
> "fast + longterm" flavor for cases like this.

Yes I'm just about ready with a small patch set to add a GUP fast longterm.

I think this should wait for that series.

Ira

2019-02-11 20:43:28

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH v2] xsk: share the mmap_sem for page pinning

On 02/11/2019 05:15 PM, Davidlohr Bueso wrote:
> Holding mmap_sem exclusively for a gup() is an overkill.
> Lets share the lock and replace the gup call for gup_longterm(),
> as it is better suited for the lifetime of the pinning.
>
> Cc: David S. Miller <[email protected]>
> Cc: Bjorn Topel <[email protected]>
> Cc: Magnus Karlsson <[email protected]>
> CC: [email protected]
> Signed-off-by: Davidlohr Bueso <[email protected]>

Applied, thanks!