[PATCH v3] drm: renesas: rcar-du: use proper naming for R-Car

2023-11-05 Thread Wolfram Sang
Not RCAR, but R-Car.

Signed-off-by: Wolfram Sang 
Reviewed-by: Kieran Bingham 
Reviewed-by: Geert Uytterhoeven 
---

Changes since v2:
* rebased to 6.6
* added Geert's tag (thanks!)

 drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h 
b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h
index f9893d7d6dfc..e9e59c5e70d5 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.h
@@ -16,7 +16,7 @@ struct rcar_du_format_info;
 struct rcar_du_group;
 
 /*
- * The RCAR DU has 8 hardware planes, shared between primary and overlay 
planes.
+ * The R-Car DU has 8 hardware planes, shared between primary and overlay 
planes.
  * As using overlay planes requires at least one of the CRTCs being enabled, no
  * more than 7 overlay planes can be available. We thus create 1 primary plane
  * per CRTC and 7 overlay planes, for a total of up to 9 KMS planes.
-- 
2.35.1



amdgpu_amdkfd_gfx* triggers new -Walloc-size warnings in GCC 14

2023-11-05 Thread Sam James
GCC 14 introduces a new -Walloc-size warning 
(https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wno-alloc-size)
which triggers on the following amdgpu files:
"""
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c:
 In function ‘kgd_hqd_dump’:
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c:241:15:
 error: allocation of insufficient size ‘4’ for type ‘uint32_t[2]’ {aka 
‘unsigned int[2
]’} with size ‘8’ 
[-Werror=alloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
  241 | *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), 
GFP_KERNEL);
  |   ^
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c:
 In function ‘kgd_hqd_sdma_dump’:
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c:327:15:
 error: allocation of insufficient size ‘4’ for type ‘uint32_t[2]’ {aka 
‘unsigned int[2
]’} with size ‘8’ 
[-Werror=alloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
  327 | *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), 
GFP_KERNEL);
  |   ^
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c:
 In function ‘kgd_arcturus_hqd_sdma_dump’:
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c:203:15:
 error: allocation of insufficient size ‘4’ for type ‘uint32_t[2]’ {aka 
‘unsigned int
[2]’} with size ‘8’ 
[-Werror=alloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
  203 | *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), 
GFP_KERNEL);
  |   ^
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c:
 In function ‘kgd_gfx_v9_4_3_hqd_sdma_dump’:
/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.10/work/linux-6.5/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c:142:15:
 error: allocation of insufficient size ‘4’ for type ‘uint32_t[2]’ {aka 
‘unsigned int
[2]’} with size ‘8’ 
[-Werror=alloc-size[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Walloc-size]]
  142 | *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), 
GFP_KERNEL);
  |   ^
"""

$ gcc-14 --version
gcc-14 (Gentoo Hardened 14.0.0 p, commit
2b02f083e67e97f8187d3ec023c3d281f49232c0) 14.0.0 20231104 (experimental)
8d22ac6a18cf542cd541c06b2a7df8fdd293946d
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

thanks,
sam


Re: Blank screen on boot of Linux 6.5 and later on Lenovo ThinkPad L570

2023-11-05 Thread Huacai Chen
Hi, Evan,

On Sat, Nov 4, 2023 at 10:50 AM Evan Preston  wrote:
>
> Hi Huacai,
>
> On 2023-11-03 Fri 02:36pm, Huacai Chen wrote:
> > Hi, Evan,
> >
> > On Fri, Nov 3, 2023 at 1:54 PM Evan Preston  wrote:
> > >
> > > Hi Huacai,
> > >
> > > On 2023-11-02 Thu 08:38pm, Huacai Chen wrote:
> > > > Hi, Jaak,
> > > >
> > > > On Wed, Nov 1, 2023 at 7:52 PM Jaak Ristioja  wrote:
> > > > >
> > > > > On 31.10.23 14:17, Huacai Chen wrote:
> > > > > > Hi, Jaak and Evan,
> > > > > >
> > > > > > On Sun, Oct 29, 2023 at 9:42 AM Huacai Chen  
> > > > > > wrote:
> > > > > >>
> > > > > >> On Sat, Oct 28, 2023 at 7:06 PM Jaak Ristioja  
> > > > > >> wrote:
> > > > > >>>
> > > > > >>> On 26.10.23 03:58, Huacai Chen wrote:
> > > > >  Hi, Jaak,
> > > > > 
> > > > >  On Thu, Oct 26, 2023 at 2:49 AM Jaak Ristioja  
> > > > >  wrote:
> > > > > >
> > > > > > On 25.10.23 16:23, Huacai Chen wrote:
> > > > > >> On Wed, Oct 25, 2023 at 6:08 PM Thorsten Leemhuis
> > > > > >>  wrote:
> > > > > >>>
> > > > > >>> Javier, Dave, Sima,
> > > > > >>>
> > > > > >>> On 23.10.23 00:54, Evan Preston wrote:
> > > > >  On 2023-10-20 Fri 05:48pm, Huacai Chen wrote:
> > > > > > On Fri, Oct 20, 2023 at 5:35 PM Linux regression tracking 
> > > > > > (Thorsten
> > > > > > Leemhuis)  wrote:
> > > > > >> On 09.10.23 10:54, Huacai Chen wrote:
> > > > > >>> On Mon, Oct 9, 2023 at 4:45 PM Bagas Sanjaya 
> > > > > >>>  wrote:
> > > > >  On Mon, Oct 09, 2023 at 09:27:02AM +0800, Huacai Chen 
> > > > >  wrote:
> > > > > > On Tue, Sep 26, 2023 at 10:31 PM Huacai Chen 
> > > > > >  wrote:
> > > > > >> On Tue, Sep 26, 2023 at 7:15 PM Linux regression 
> > > > > >> tracking (Thorsten
> > > > > >> Leemhuis)  wrote:
> > > > > >>> On 13.09.23 14:02, Jaak Ristioja wrote:
> > > > > 
> > > > >  Upgrading to Linux 6.5 on a Lenovo ThinkPad L570 
> > > > >  (Integrated Intel HD
> > > > >  Graphics 620 (rev 02), Intel(R) Core(TM) i7-7500U) 
> > > > >  results in a blank
> > > > >  screen after boot until the display manager 
> > > > >  starts... if it does start
> > > > >  at all. Using the nomodeset kernel parameter seems 
> > > > >  to be a workaround.
> > > > > 
> > > > >  I've bisected this to commit 
> > > > >  60aebc9559492cea6a9625f514a8041717e3a2e4
> > > > >  ("drivers/firmware: Move sysfb_init() from 
> > > > >  device_initcall to
> > > > >  subsys_initcall_sync").
> > > > > >>>
> > > > > > As confirmed by Jaak, disabling DRM_SIMPLEDRM makes 
> > > > > > things work fine
> > > > > > again. So I guess the reason:
> > > > > >>
> > > > > >> Well, this to me still looks a lot (please correct me if 
> > > > > >> I'm wrong) like
> > > > > >> regression that should be fixed, as DRM_SIMPLEDRM was 
> > > > > >> enabled beforehand
> > > > > >> if I understood things correctly. Or is there a proper fix 
> > > > > >> for this
> > > > > >> already in the works and I just missed this? Or is there 
> > > > > >> some good
> > > > > >> reason why this won't/can't be fixed?
> > > > > >
> > > > > > DRM_SIMPLEDRM was enabled but it didn't work at all because 
> > > > > > there was
> > > > > > no corresponding platform device. Now DRM_SIMPLEDRM works 
> > > > > > but it has a
> > > > > > blank screen. Of course it is valuable to investigate 
> > > > > > further about
> > > > > > DRM_SIMPLEDRM on Jaak's machine, but that needs Jaak's 
> > > > > > effort because
> > > > > > I don't have a same machine.
> > > > > >>>
> > > > > >>> Side note: Huacai, have you tried working with Jaak to get 
> > > > > >>> down to the
> > > > > >>> real problem? Evan, might you be able to help out here?
> > > > > >> No, Jaak has no response after he 'fixed' his problem by 
> > > > > >> disabling SIMPLEDRM.
> > > > > >>
> > > > > >
> > > > > > I'm sorry, what was it exactly you want me to do? Please be 
> > > > > > mindful that
> > > > > > I'm not familiar with the internals of the Linux kernel and 
> > > > > > DRI, and it
> > > > > > might sometimes take weeks before I have time to work and 
> > > > > > respond on this.
> > > > >  It doesn't matter. I hope you can do some experiments to 
> > > > >  investigate
> > > > >  deeper. The first experiment you can do is enabling SIMPLEFB 
> > > > >  (i.e.
> > > > >  CONFIG_FB_SIMPLE) instead of SIMPLEDRM (CONFIG_DRM_SIMPLEDRM) to 
> > > > >  see
> > > > > 

Re: [PATCH v2 09/11] drm/mediatek: Add secure flow support to mediatek-drm

2023-11-05 Thread 林睿祥


Re: [PATCH v2 07/11] drm/mediatek: Add secure layer config support for ovl

2023-11-05 Thread 林睿祥


Re: [PATCH v2 10/11] drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt finalize

2023-11-05 Thread 林睿祥


Re: [PATCH v2 00/11] Add mediate-drm secure flow for SVP

2023-11-05 Thread 林睿祥


RE: [PATCH] Replace ioremap_cache() with memremap()

2023-11-05 Thread Michael Kelley
From: Nischala Yelchuri  Sent: Wednesday, 
November 1, 2023 9:02 AM
>

It's customary for the patch "Subject:" line to have a prefix indicating the
area of the code being modified.  This patch touches on multiple Hyper-V
drivers, so there's not a clear choice for prefix.  I would suggest using
"Drivers: hv:" as is commonly used for Hyper-V code, though other
reviewers might have a different suggestion.

 > Current Hyper-V code for CoCo VMs uses ioremap_cache() to map normal
> memory as decrypted.
> ioremap_cache() is ideally used to map I/O device memory when it has the 
> characteristics
> of normal memory. It should not be used to map normal memory as the returned 
> pointer
> has the __iomem attribute.
> 
> Fix current code by replacing ioremap_cache() with memremap().
> 
> No functional change intended.
> 
> Signed-off-by: Nischala Yelchuri 
> ---
>  arch/x86/hyperv/hv_init.c   |  6 +++---
>  drivers/gpu/drm/hyperv/hyperv_drm_drv.c |  2 +-
>  drivers/hv/hv.c | 13 +++--
>  drivers/video/fbdev/hyperv_fb.c |  6 +++---
>  4 files changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
> index 21556ad87..fae43c040 100644
> --- a/arch/x86/hyperv/hv_init.c
> +++ b/arch/x86/hyperv/hv_init.c
> @@ -68,9 +68,9 @@ static int hyperv_init_ghcb(void)
>*/
>   rdmsrl(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa);
> 
> - /* Mask out vTOM bit. ioremap_cache() maps decrypted */
> + /* Mask out vTOM bit. memremap() maps decrypted with MEMREMAP_DEC */
>   ghcb_gpa &= ~ms_hyperv.shared_gpa_boundary;
> - ghcb_va = (void *)ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE);
> + ghcb_va = memremap(ghcb_gpa, HV_HYP_PAGE_SIZE, MEMREMAP_WB | 
> MEMREMAP_DEC);
>   if (!ghcb_va)
>   return -ENOMEM;
> 
> @@ -238,7 +238,7 @@ static int hv_cpu_die(unsigned int cpu)
>   if (hv_ghcb_pg) {
>   ghcb_va = (void **)this_cpu_ptr(hv_ghcb_pg);
>   if (*ghcb_va)
> - iounmap(*ghcb_va);
> + memunmap(*ghcb_va);
>   *ghcb_va = NULL;
>   }
> 
> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> index d511d17c5..d6fec9bd3 100644
> --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> @@ -92,7 +92,7 @@ static int hyperv_setup_vram(struct hyperv_drm_device
> *hv,
>* connect to display properly for ARM64 Linux VM, as the host also maps
>* the VRAM cacheable.
>*/
> - hv->vram = ioremap_cache(hv->mem->start, hv->fb_size);
> + hv->vram = memremap(hv->mem->start, hv->fb_size, MEMREMAP_WB | 
> MEMREMAP_DEC);

This change has some additional implications that must be
accounted for.  The hv->vram field is declared as void __iomem *
in hyperv_drm.h.   The __iomem attribute should be dropped.
Then the use of IOSYS_MAP_INIT_VADDR_IOMEM() in
hyperv_blit_to_vram_rect() should be changed to
IOSYS_MAP_INIT_VADDR().  This has the desirable effect of 
allowing normal memcpy() functions to be used instead of
the _toio()/_fromio() variants.

>   if (!hv->vram) {
>   drm_err(dev, "Failed to map vram\n");
>   ret = -ENOMEM;
> diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
> index 51e5018ac..399bfa392 100644
> --- a/drivers/hv/hv.c
> +++ b/drivers/hv/hv.c
> @@ -274,11 +274,12 @@ void hv_synic_enable_regs(unsigned int cpu)
>   simp.simp_enabled = 1;
> 
>   if (ms_hyperv.paravisor_present || hv_root_partition) {
> - /* Mask out vTOM bit. ioremap_cache() maps decrypted */
> + /* Mask out vTOM bit. memremap() maps decrypted with 
> MEMREMAP_DEC */
>   u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) &
>   ~ms_hyperv.shared_gpa_boundary;
>   hv_cpu->synic_message_page
> - = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE);
> + = memremap(base,
> +HV_HYP_PAGE_SIZE, MEMREMAP_WB | 
> MEMREMAP_DEC);
>   if (!hv_cpu->synic_message_page)
>   pr_err("Fail to map synic message page.\n");
>   } else {
> @@ -293,11 +294,11 @@ void hv_synic_enable_regs(unsigned int cpu)
>   siefp.siefp_enabled = 1;
> 
>   if (ms_hyperv.paravisor_present || hv_root_partition) {
> - /* Mask out vTOM bit. ioremap_cache() maps decrypted */
> + /* Mask out vTOM bit. memremap() maps decrypted with 
> MEMREMAP_DEC */
>   u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) &
>   ~ms_hyperv.shared_gpa_boundary;
>   hv_cpu->synic_event_page
> - = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE);
> + = memremap(base, HV_HYP_PAGE_SIZE, MEMREMAP_WB | 
> MEMREMAP_DEC);
>   if (!hv_cpu->synic_event_page)
>   pr_err(

[PATCH] amdgpu: Adjust kmalloc_array calls for new -Walloc-size

2023-11-05 Thread Sam James
GCC 14 introduces a new -Walloc-size included in -Wextra which errors out
on various files in drivers/gpu/drm/amd/amdgpu like:
```
amdgpu_amdkfd_gfx_v8.c:241:15: error: allocation of insufficient size ‘4’ for 
type ‘uint32_t[2]’ {aka ‘unsigned int[2]'} with size ‘8’ [-Werror=alloc-size]
```

This is because each HQD_N_REGS is actually a uint32_t[2]. Move the * 2 to
the size argument so GCC sees we're allocating enough.

Originally did 'sizeof(uint32_t) * 2' for the size but a friend suggested
'sizeof(**dump)' better communicates the intent.

Link: https://lore.kernel.org/all/87wmuwo7i3@gentoo.org/
Signed-off-by: Sam James 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c   | 4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c   | 4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c   | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
index 625db444df1c..0ba15dcbe4e1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c
@@ -200,7 +200,7 @@ int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev,
 #undef HQD_N_REGS
 #define HQD_N_REGS (19+6+7+10)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
index 490c8f5ddb60..ca7238b5535b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c
@@ -141,7 +141,7 @@ static int kgd_gfx_v9_4_3_hqd_sdma_dump(struct 
amdgpu_device *adev,
(*dump)[i++][1] = RREG32(addr); \
} while (0)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index 6bf448ab3dff..ca4a6b82817f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -214,7 +214,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev,
(*dump)[i++][1] = RREG32(addr); \
} while (0)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
@@ -301,7 +301,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
 #undef HQD_N_REGS
 #define HQD_N_REGS (19+4)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index cd06e4a6d1da..0f3e2944edd7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -238,7 +238,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev,
(*dump)[i++][1] = RREG32(addr); \
} while (0)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
@@ -324,7 +324,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
 #undef HQD_N_REGS
 #define HQD_N_REGS (19+4+2+3+7)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
index 51011e8ee90d..a3355b90aac5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
@@ -365,7 +365,7 @@ int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev,
(*dump)[i++][1] = RREG32(addr); \
} while (0)
 
-   *dump = kmalloc_array(HQD_N_REGS * 2, sizeof(uint32_t), GFP_KERNEL);
+   *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL);
if (*dump == NULL)
return -ENOMEM;
 
@@ -462,7 +462,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev,
 #undef HQD_N_REGS
 #define HQD_N_REGS (19+6+7+10)
 
-   *dump = kmalloc_array(HQD_N_REGS 

Re: Blank screen on boot of Linux 6.5 and later on Lenovo ThinkPad L570

2023-11-05 Thread Jaak Ristioja

On 05.11.23 14:40, Huacai Chen wrote:

Hi, Evan,

On Sat, Nov 4, 2023 at 10:50 AM Evan Preston  wrote:


Hi Huacai,

On 2023-11-03 Fri 02:36pm, Huacai Chen wrote:

Hi, Evan,

On Fri, Nov 3, 2023 at 1:54 PM Evan Preston  wrote:


Hi Huacai,

On 2023-11-02 Thu 08:38pm, Huacai Chen wrote:

Hi, Jaak,

On Wed, Nov 1, 2023 at 7:52 PM Jaak Ristioja  wrote:


On 31.10.23 14:17, Huacai Chen wrote:

Hi, Jaak and Evan,

On Sun, Oct 29, 2023 at 9:42 AM Huacai Chen  wrote:


On Sat, Oct 28, 2023 at 7:06 PM Jaak Ristioja  wrote:


On 26.10.23 03:58, Huacai Chen wrote:

Hi, Jaak,

On Thu, Oct 26, 2023 at 2:49 AM Jaak Ristioja  wrote:


On 25.10.23 16:23, Huacai Chen wrote:

On Wed, Oct 25, 2023 at 6:08 PM Thorsten Leemhuis
 wrote:


Javier, Dave, Sima,

On 23.10.23 00:54, Evan Preston wrote:

On 2023-10-20 Fri 05:48pm, Huacai Chen wrote:

On Fri, Oct 20, 2023 at 5:35 PM Linux regression tracking (Thorsten
Leemhuis)  wrote:

On 09.10.23 10:54, Huacai Chen wrote:

On Mon, Oct 9, 2023 at 4:45 PM Bagas Sanjaya  wrote:

On Mon, Oct 09, 2023 at 09:27:02AM +0800, Huacai Chen wrote:

On Tue, Sep 26, 2023 at 10:31 PM Huacai Chen  wrote:

On Tue, Sep 26, 2023 at 7:15 PM Linux regression tracking (Thorsten
Leemhuis)  wrote:

On 13.09.23 14:02, Jaak Ristioja wrote:


Upgrading to Linux 6.5 on a Lenovo ThinkPad L570 (Integrated Intel HD
Graphics 620 (rev 02), Intel(R) Core(TM) i7-7500U) results in a blank
screen after boot until the display manager starts... if it does start
at all. Using the nomodeset kernel parameter seems to be a workaround.

I've bisected this to commit 60aebc9559492cea6a9625f514a8041717e3a2e4
("drivers/firmware: Move sysfb_init() from device_initcall to
subsys_initcall_sync").



As confirmed by Jaak, disabling DRM_SIMPLEDRM makes things work fine
again. So I guess the reason:


Well, this to me still looks a lot (please correct me if I'm wrong) like
regression that should be fixed, as DRM_SIMPLEDRM was enabled beforehand
if I understood things correctly. Or is there a proper fix for this
already in the works and I just missed this? Or is there some good
reason why this won't/can't be fixed?


DRM_SIMPLEDRM was enabled but it didn't work at all because there was
no corresponding platform device. Now DRM_SIMPLEDRM works but it has a
blank screen. Of course it is valuable to investigate further about
DRM_SIMPLEDRM on Jaak's machine, but that needs Jaak's effort because
I don't have a same machine.


Side note: Huacai, have you tried working with Jaak to get down to the
real problem? Evan, might you be able to help out here?

No, Jaak has no response after he 'fixed' his problem by disabling SIMPLEDRM.



I'm sorry, what was it exactly you want me to do? Please be mindful that
I'm not familiar with the internals of the Linux kernel and DRI, and it
might sometimes take weeks before I have time to work and respond on this.

It doesn't matter. I hope you can do some experiments to investigate
deeper. The first experiment you can do is enabling SIMPLEFB (i.e.
CONFIG_FB_SIMPLE) instead of SIMPLEDRM (CONFIG_DRM_SIMPLEDRM) to see
whether there is also a blank screen. If no blank screen, that
probably means SIMPLEDRM has a bug, if still blank screen, that means
the firmware may pass wrong screen information.


Testing with 6.5.9 I get a blank screen with CONFIG_DRM_SIMPLEDRM=y and
get no blank screen with CONFIG_FB_SIMPLE=y and CONFIG_DRM_SIMPLEDRM unset.

CONFIG_FB_SIMPLE and  CONFIG_DRM_SIMPLEDRM use the same device created
by sysfb_init(). Since FB_SIMPLE works fine, I think the real problem
is that DRM_SIMPLEDRM has a bug. The next step is to enable
CONFIG_DRM_SIMPLEDRM and trace its initialization. In detail, adding
some printk() in simpledrm_probe() and its sub-routines to see where
the driver fails. The output of these printk() can be seen by the
'dmesg' command after boot.

I need your help. I tried with my laptop (ThinkPad E490, Intel Core
i3-8145U, UHD Graphics 620) but I can't reproduce your problem. So
please patch your 6.5.x kernel with this temporary patch [1], then
build a "bad kernel" with SIMPLEDRM enabled. And after booting your
machine with this "bad kernel", please give me the dmesg output. Thank
you very much.

[1] http://ddns.miaomiaomiao.top:9000/download/kernel/patch-6.5.9


I'm unable to download it. Can you please send it by e-mail?

I'm sorry, please download from attachment.


When applying this patch the first hunk (drivers/firmware/sysfb.c) fails for
me with 6.5.9.  Attempting to load the 6.5.9 kernel without this patch
produces no dmesg output on my machine.

You copy-paste the patch? If you download it directly it can be
applied successfully, I think.


The patch downloaded from your URL applies successfully.  However, I still
see no dmesg output using the patched 6.5.9 kernel.  'journalctl -k -b all'
shows no dmesg output from any 6.5.x boots, only from 6.4.12 boots.

Thank you for your testing. Since you cannot boot to GUI successfully
as Jaak, you may have some troubles with getting the 

Re: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by calling lsdc_output_init()

2023-11-05 Thread kernel test robot
Hi Sui,

kernel test robot noticed the following build warnings:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on linus/master v6.6 next-20231103]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Sui-Jingfeng/drm-loongson-Introduce-a-minimal-support-for-Loongson-VBIOS/20231030-034730
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20231029194607.379459-4-suijingfeng%40loongson.cn
patch subject: [PATCH 3/8] drm/loongson: Allow attach drm bridge driver by 
calling lsdc_output_init()
config: x86_64-randconfig-122-20231102 
(https://download.01.org/0day-ci/archive/20231106/202311060159.wme8x93v-...@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231106/202311060159.wme8x93v-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202311060159.wme8x93v-...@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/loongson/lsdc_output.c:555:5: sparse: sparse: symbol 
>> 'lsdc_encoder_init' was not declared. Should it be static?
>> drivers/gpu/drm/loongson/lsdc_output.c:578:5: sparse: sparse: symbol 
>> 'lsdc_connector_init' was not declared. Should it be static?

vim +/lsdc_encoder_init +555 drivers/gpu/drm/loongson/lsdc_output.c

   554  
 > 555  int lsdc_encoder_init(struct drm_device *ddev,
   556struct lsdc_output *output,
   557unsigned int pipe)
   558  {
   559  const struct lsdc_output_desc *descp = output->descp;
   560  struct drm_encoder *encoder = &output->encoder;
   561  int ret;
   562  
   563  ret = drm_encoder_init(ddev,
   564 encoder,
   565 descp->encoder_funcs,
   566 descp->encoder_type,
   567 descp->name);
   568  if (ret)
   569  return ret;
   570  
   571  encoder->possible_crtcs = BIT(pipe);
   572  
   573  drm_encoder_helper_add(encoder, descp->encoder_helper_funcs);
   574  
   575  return 0;
   576  }
   577  
 > 578  int lsdc_connector_init(struct drm_device *ddev,
   579  struct lsdc_output *output,
   580  struct i2c_adapter *ddc,
   581  unsigned int pipe)
   582  {
   583  const struct lsdc_output_desc *descp = output->descp;
   584  struct drm_connector *connector = &output->connector;
   585  int ret;
   586  
   587  ret = drm_connector_init_with_ddc(ddev,
   588connector,
   589descp->connector_funcs,
   590descp->connector_type,
   591ddc);
   592  if (ret)
   593  return ret;
   594  
   595  drm_connector_helper_add(connector, 
descp->connector_helper_funcs);
   596  
   597  drm_connector_attach_encoder(connector, &output->encoder);
   598  
   599  connector->polled = DRM_CONNECTOR_POLL_CONNECT |
   600  DRM_CONNECTOR_POLL_DISCONNECT;
   601  
   602  connector->interlace_allowed = 0;
   603  connector->doublescan_allowed = 0;
   604  
   605  drm_info(ddev, "DisplayPipe-%u has %s\n", pipe, descp->name);
   606  
   607  return 0;
   608  }
   609  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


Re: [PATCH v2 6/9] PCI: Rename is_thunderbolt to is_tunneled

2023-11-05 Thread Lukas Wunner
On Fri, Nov 03, 2023 at 02:07:55PM -0500, Mario Limonciello wrote:
> The `is_thunderbolt` bit has been used to indicate that a PCIe device
> contained the Intel VSEC which is used by various parts of the kernel
> to change behavior. To later allow usage with USB4 controllers as well,
> rename this to `is_tunneled`.

This doesn't seem to make sense.  is_thunderbolt indicates that a device
is part of a Thunderbolt controller.  See the code comment:

> - unsigned intis_thunderbolt:1;   /* Thunderbolt controller */

A Thunderbolt controller is not necessarily tunneled.  The PCIe switch,
NHI and XHCI of the Thunderbolt host controller are not tunneled at all.

Thanks,

Lukas


Re: [PATCH] fbdev: omapfb: Drop unused remove function

2023-11-05 Thread Helge Deller

On 11/3/23 18:35, Uwe Kleine-König wrote:

OMAP2_VRFB is a bool, so the vrfb driver can never be compiled as a
module. With that __exit_p(vrfb_remove) always evaluates to NULL and
vrfb_remove() is unused.

If the driver was compilable as a module, it would fail to build because
the type of vrfb_remove() isn't compatible with struct
platform_driver::remove(). (The former returns void, the latter int.)

Fixes: aa1e49a3752f ("OMAPDSS: VRFB: add omap_vrfb_supported()")
Signed-off-by: Uwe Kleine-König 


applied.
Thanks!
Helge



---
  drivers/video/fbdev/omap2/omapfb/vrfb.c | 9 +
  1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/omap2/omapfb/vrfb.c 
b/drivers/video/fbdev/omap2/omapfb/vrfb.c
index ee0dd4c6a646..568e6e1eca62 100644
--- a/drivers/video/fbdev/omap2/omapfb/vrfb.c
+++ b/drivers/video/fbdev/omap2/omapfb/vrfb.c
@@ -368,17 +368,10 @@ static int __init vrfb_probe(struct platform_device *pdev)
return 0;
  }

-static void __exit vrfb_remove(struct platform_device *pdev)
-{
-   vrfb_loaded = false;
-}
-
  static struct platform_driver vrfb_driver = {
.driver.name= "omapvrfb",
-   .remove = __exit_p(vrfb_remove),
  };
-
-module_platform_driver_probe(vrfb_driver, vrfb_probe);
+builtin_platform_driver_probe(vrfb_driver, vrfb_probe);

  MODULE_AUTHOR("Tomi Valkeinen ");
  MODULE_DESCRIPTION("OMAP VRFB");

base-commit: e27090b1413ff236ca1aec26d6b022149115de2c




Re: [PATCH] drivers/video/fbdev: use new array-copying-wrapper

2023-11-05 Thread Helge Deller

On 11/2/23 20:24, Philipp Stanner wrote:

viafbdev.c utilizes memdup_user() to copy an array from userspace.

There is a new wrapper, specifically designed for copying arrays. Use
this one instead.

Suggested-by: Dave Airlie 
Signed-off-by: Philipp Stanner 


applied.

Thanks!
Helge



---
  drivers/video/fbdev/via/viafbdev.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/via/viafbdev.c 
b/drivers/video/fbdev/via/viafbdev.c
index 58868f8880d6..a52b1ba43a48 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -574,7 +574,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, 
u_long arg)
break;

case VIAFB_SET_GAMMA_LUT:
-   viafb_gamma_table = memdup_user(argp, 256 * sizeof(u32));
+   viafb_gamma_table = memdup_array_user(argp, 256, sizeof(u32));
if (IS_ERR(viafb_gamma_table))
return PTR_ERR(viafb_gamma_table);
viafb_set_gamma_table(viafb_bpp, viafb_gamma_table);




Re: [PATCH 1/2] fbdev/imsttfb: fix double free in probe()

2023-11-05 Thread Helge Deller

On 10/27/23 14:04, Dan Carpenter wrote:

The init_imstt() function calls framebuffer_release() on error and then
the probe() function calls it again.  It should only be done in probe.

Fixes: 518ecb6a209f ("fbdev: imsttfb: Fix error path of imsttfb_probe()")
Signed-off-by: Dan Carpenter 


Both patches applied.

Thanks!
Helge


[PATCH] nouveau: don't fail driver load if no display hw present.

2023-11-05 Thread Dave Airlie
From: Dave Airlie 

If we get back ENODEV don't fail load.

Fixes: 15740541e8f0 ("drm/nouveau/devinit/tu102-: prepare for GSP-RM")
Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/270
Signed-off-by: Dave Airlie 
---
 drivers/gpu/drm/nouveau/nouveau_display.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index d8c92521226d..f28f9a857458 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -726,6 +726,11 @@ nouveau_display_create(struct drm_device *dev)
 
if (nouveau_modeset != 2) {
ret = nvif_disp_ctor(&drm->client.device, "kmsDisp", 0, 
&disp->disp);
+   /* no display hw */
+   if (ret == -ENODEV) {
+   ret = 0;
+   goto disp_create_err;
+   }
 
if (!ret && (disp->disp.outp_mask || drm->vbios.dcb.entries)) {
nouveau_display_create_properties(dev);
-- 
2.41.0



[PATCH v1] drm: amd: Resolve Sphinx unexpected indentation warning

2023-11-05 Thread Hunter Chasens
Resolves Sphinx unexpected indentation warning when compiling
documentation (e.g. `make htmldocs`). Replaces tabs with spaces and adds
a literal block to keep vertical formatting of the
example power state list.

Signed-off-by: Hunter Chasens 
---
 drivers/gpu/drm/amd/pm/amdgpu_pm.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
index 517b9fb4624c..703fe2542258 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -990,11 +990,14 @@ static ssize_t amdgpu_get_pp_features(struct device *dev,
  * the power state and the clock information for those levels. If deep sleep is
  * applied to a clock, the level will be denoted by a special level 'S:'
  * E.g.,
- * S: 19Mhz *
- * 0: 615Mhz
- * 1: 800Mhz
- * 2: 888Mhz
- * 3: 1000Mhz
+ *
+ * ::
+ *
+ *  S: 19Mhz *
+ *  0: 615Mhz
+ *  1: 800Mhz
+ *  2: 888Mhz
+ *  3: 1000Mhz
  *
  *
  * To manually adjust these states, first select manual using
-- 
2.39.3



Re: Blank screen on boot of Linux 6.5 and later on Lenovo ThinkPad L570

2023-11-05 Thread Evan Preston
Hi Huacai,

On 2023-11-05 Sun 08:40pm, Huacai Chen wrote:
> Hi, Evan,
> 
> On Sat, Nov 4, 2023 at 10:50 AM Evan Preston  wrote:
> >
> > Hi Huacai,
> >
> > On 2023-11-03 Fri 02:36pm, Huacai Chen wrote:
> > > Hi, Evan,
> > >
> > > On Fri, Nov 3, 2023 at 1:54 PM Evan Preston  wrote:
> > > >
> > > > Hi Huacai,
> > > >
> > > > On 2023-11-02 Thu 08:38pm, Huacai Chen wrote:
> > > > > Hi, Jaak,
> > > > >
> > > > > On Wed, Nov 1, 2023 at 7:52 PM Jaak Ristioja  wrote:
> > > > > >
> > > > > > On 31.10.23 14:17, Huacai Chen wrote:
> > > > > > > Hi, Jaak and Evan,
> > > > > > >
> > > > > > > On Sun, Oct 29, 2023 at 9:42 AM Huacai Chen 
> > > > > > >  wrote:
> > > > > > >>
> > > > > > >> On Sat, Oct 28, 2023 at 7:06 PM Jaak Ristioja  
> > > > > > >> wrote:
> > > > > > >>>
> > > > > > >>> On 26.10.23 03:58, Huacai Chen wrote:
> > > > > >  Hi, Jaak,
> > > > > > 
> > > > > >  On Thu, Oct 26, 2023 at 2:49 AM Jaak Ristioja 
> > > > > >   wrote:
> > > > > > >
> > > > > > > On 25.10.23 16:23, Huacai Chen wrote:
> > > > > > >> On Wed, Oct 25, 2023 at 6:08 PM Thorsten Leemhuis
> > > > > > >>  wrote:
> > > > > > >>>
> > > > > > >>> Javier, Dave, Sima,
> > > > > > >>>
> > > > > > >>> On 23.10.23 00:54, Evan Preston wrote:
> > > > > >  On 2023-10-20 Fri 05:48pm, Huacai Chen wrote:
> > > > > > > On Fri, Oct 20, 2023 at 5:35 PM Linux regression tracking 
> > > > > > > (Thorsten
> > > > > > > Leemhuis)  wrote:
> > > > > > >> On 09.10.23 10:54, Huacai Chen wrote:
> > > > > > >>> On Mon, Oct 9, 2023 at 4:45 PM Bagas Sanjaya 
> > > > > > >>>  wrote:
> > > > > >  On Mon, Oct 09, 2023 at 09:27:02AM +0800, Huacai Chen 
> > > > > >  wrote:
> > > > > > > On Tue, Sep 26, 2023 at 10:31 PM Huacai Chen 
> > > > > > >  wrote:
> > > > > > >> On Tue, Sep 26, 2023 at 7:15 PM Linux regression 
> > > > > > >> tracking (Thorsten
> > > > > > >> Leemhuis)  wrote:
> > > > > > >>> On 13.09.23 14:02, Jaak Ristioja wrote:
> > > > > > 
> > > > > >  Upgrading to Linux 6.5 on a Lenovo ThinkPad L570 
> > > > > >  (Integrated Intel HD
> > > > > >  Graphics 620 (rev 02), Intel(R) Core(TM) i7-7500U) 
> > > > > >  results in a blank
> > > > > >  screen after boot until the display manager 
> > > > > >  starts... if it does start
> > > > > >  at all. Using the nomodeset kernel parameter seems 
> > > > > >  to be a workaround.
> > > > > > 
> > > > > >  I've bisected this to commit 
> > > > > >  60aebc9559492cea6a9625f514a8041717e3a2e4
> > > > > >  ("drivers/firmware: Move sysfb_init() from 
> > > > > >  device_initcall to
> > > > > >  subsys_initcall_sync").
> > > > > > >>>
> > > > > > > As confirmed by Jaak, disabling DRM_SIMPLEDRM makes 
> > > > > > > things work fine
> > > > > > > again. So I guess the reason:
> > > > > > >>
> > > > > > >> Well, this to me still looks a lot (please correct me if 
> > > > > > >> I'm wrong) like
> > > > > > >> regression that should be fixed, as DRM_SIMPLEDRM was 
> > > > > > >> enabled beforehand
> > > > > > >> if I understood things correctly. Or is there a proper 
> > > > > > >> fix for this
> > > > > > >> already in the works and I just missed this? Or is there 
> > > > > > >> some good
> > > > > > >> reason why this won't/can't be fixed?
> > > > > > >
> > > > > > > DRM_SIMPLEDRM was enabled but it didn't work at all 
> > > > > > > because there was
> > > > > > > no corresponding platform device. Now DRM_SIMPLEDRM works 
> > > > > > > but it has a
> > > > > > > blank screen. Of course it is valuable to investigate 
> > > > > > > further about
> > > > > > > DRM_SIMPLEDRM on Jaak's machine, but that needs Jaak's 
> > > > > > > effort because
> > > > > > > I don't have a same machine.
> > > > > > >>>
> > > > > > >>> Side note: Huacai, have you tried working with Jaak to get 
> > > > > > >>> down to the
> > > > > > >>> real problem? Evan, might you be able to help out here?
> > > > > > >> No, Jaak has no response after he 'fixed' his problem by 
> > > > > > >> disabling SIMPLEDRM.
> > > > > > >>
> > > > > > >
> > > > > > > I'm sorry, what was it exactly you want me to do? Please be 
> > > > > > > mindful that
> > > > > > > I'm not familiar with the internals of the Linux kernel and 
> > > > > > > DRI, and it
> > > > > > > might sometimes take weeks before I have time to work and 
> > > > > > > respond on this.
> > > > > >  It doesn't matter

Re: [PATCH 02/10] drm/tidss: Use PM autosuspend

2023-11-05 Thread Laurent Pinchart
Hi Tomi,

CC'ing Sakari for his expertise on runtime PM (I think he will soon
start wishing he would be ignorant in this area).

On Thu, Nov 02, 2023 at 08:34:45AM +0200, Tomi Valkeinen wrote:
> On 01/11/2023 15:54, Laurent Pinchart wrote:
> > On Wed, Nov 01, 2023 at 11:17:39AM +0200, Tomi Valkeinen wrote:
> >> Use runtime PM autosuspend feature, with 1s timeout, to avoid
> >> unnecessary suspend-resume cycles when, e.g. the userspace temporarily
> >> turns off the crtcs when configuring the outputs.
> >>
> >> Signed-off-by: Tomi Valkeinen 
> >> ---
> >>   drivers/gpu/drm/tidss/tidss_drv.c | 8 +++-
> >>   1 file changed, 7 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/tidss/tidss_drv.c 
> >> b/drivers/gpu/drm/tidss/tidss_drv.c
> >> index f403db11b846..64914331715a 100644
> >> --- a/drivers/gpu/drm/tidss/tidss_drv.c
> >> +++ b/drivers/gpu/drm/tidss/tidss_drv.c
> >> @@ -43,7 +43,9 @@ void tidss_runtime_put(struct tidss_device *tidss)
> >>   
> >>dev_dbg(tidss->dev, "%s\n", __func__);
> >>   
> >> -  r = pm_runtime_put_sync(tidss->dev);
> >> +  pm_runtime_mark_last_busy(tidss->dev);
> >> +
> >> +  r = pm_runtime_put_autosuspend(tidss->dev);
> >>WARN_ON(r < 0);
> >>   }
> >>   
> >> @@ -144,6 +146,9 @@ static int tidss_probe(struct platform_device *pdev)
> >>   
> >>pm_runtime_enable(dev);
> >>   
> >> +  pm_runtime_set_autosuspend_delay(dev, 1000);
> >> +  pm_runtime_use_autosuspend(dev);
> >> +
> >>   #ifndef CONFIG_PM
> >>/* If we don't have PM, we need to call resume manually */
> >>dispc_runtime_resume(tidss->dispc);
> > 
> > By the way, there's a way to handle this without any ifdef:
> > 
> > dispc_runtime_resume(tidss->dispc);
> > 
> > pm_runtime_set_active(dev);
> > pm_runtime_get_noresume(dev);
> > pm_runtime_enable(dev);
> > pm_runtime_set_autosuspend_delay(dev, 1000);
> > pm_runtime_use_autosuspend(dev);
> 
> I'm not sure I follow what you are trying to do here. The call to 
> dispc_runtime_resume() would crash if we have PM, as the HW would not be 
> enabled at that point.

Isn't dispc_runtime_resume() meant to enable the hardware ?

The idea is to enable the hardware, then enable runtime PM, and tell the
runtime PM framework that the device is enabled. If CONFIG_PM is not
set, the RPM calls will be no-ops, and the device will stay enable. If
CONFIG_PM is set, the device will be enabled, and will get disabled at
end of probe by a call to pm_runtime_put_autosuspend().

> And even if it wouldn't, we don't want to call dispc_runtime_resume()
> in probe when we have PM.

Don't you need to enable the device at probe time in order to reset it,
as done in later patches in the series ?

> > Then, in the error path,
> > 
> > pm_runtime_dont_use_autosuspend(dev);
> > pm_runtime_disable(dev);
> > pm_runtime_put_noidle(dev);
> > 
> > dispc_runtime_suspend(tidss->dispc);
> > 
> > And in remove:
> > 
> > pm_runtime_dont_use_autosuspend(dev);
> > pm_runtime_disable(dev);
> > if (!pm_runtime_status_suspended(dev))
> > dispc_runtime_suspend(tidss->dispc);
> > pm_runtime_set_suspended(dev);
> > 
> > And yes, runtime PM is a horrible API.
> > 
> >> @@ -215,6 +220,7 @@ static void tidss_remove(struct platform_device *pdev)
> >>/* If we don't have PM, we need to call suspend manually */
> >>dispc_runtime_suspend(tidss->dispc);
> >>   #endif
> >> +  pm_runtime_dont_use_autosuspend(dev);
> > 
> > This also needs to be done in the probe error path.
> 
> Oops. Right, I'll add that.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 04/10] drm/tidss: Move reset to the end of dispc_init()

2023-11-05 Thread Laurent Pinchart
On Thu, Nov 02, 2023 at 08:40:10AM +0200, Tomi Valkeinen wrote:
> On 01/11/2023 15:57, Laurent Pinchart wrote:
> > On Wed, Nov 01, 2023 at 11:17:41AM +0200, Tomi Valkeinen wrote:
> >> We do a DSS reset in the middle of the dispc_init(). While that happens
> >> to work now, we should really make sure that e..g the fclk, which is
> >> acquired only later in the function, is enabled when doing a reset. This
> >> will be handled in a later patch, but for now, let's move the
> >> dispc_softreset() call to the end of dispc_init(), which is a sensible
> >> place for it anyway.
> >>
> >> Signed-off-by: Tomi Valkeinen 
> > 
> > Reviewed-by: Laurent Pinchart 
> > 
> > But do I understand correctly that the device isn't powered up at this
> > point ? That seems problematic.
> 
> Indeed. It's fixed later in this series.
> 
> > I'm also not sure why we need to reset the device at probe time.
> 
> That's the usual place to do a reset, to make sure the HW is in a known 
> state, is it not? Where would you place it?

The first time the device is used, or possibly every time it is resumed
? It seems that you're resuming it at probe time for the only reason
that you want to then reset it. Resuming it at probe could get entirely
skipped.

-- 
Regards,

Laurent Pinchart


Re: [Freedreno] [PATCH v7 0/7] incorporate pm runtime framework and eDP clean up

2023-11-05 Thread Leonard Lausen
Verified this fixes the "[drm:drm_mode_config_helper_resume] *ERROR* Failed to
resume (-107)" issue https://gitlab.freedesktop.org/drm/msm/-/issues/25

Tested-by: Leonard Lausen  # on sc7180 lazor

On 10/6/23 18:55, Kuogee Hsieh wrote:
> The purpose of this patch series is to incorporate pm runtime framework
> into MSM eDP/DP driver so that eDP panel can be detected by DRM eDP panel
> driver during system probe time. During incorporating procedure, original
> customized pm realted fucntions, such as dp_pm_prepare(), dp_pm_suspend(),
> dp_pm_resume() and dp_pm_prepare(), are removed and replaced with functions
> provided by pm runtiem framework such as pm_runtime_force_suspend() and
> pm_runtime_force_resume(). In addition, both eDP aux-bus and irq handler
> are bound at system probe time too.
> 
> Kuogee Hsieh (7):
>   drm/msm/dp: tie dp_display_irq_handler() with dp driver
>   drm/msm/dp: rename is_connected with link_ready
>   drm/msm/dp: use drm_bridge_hpd_notify() to report HPD status changes
>   drm/msm/dp: move parser->parse() and dp_power_client_init() to probe
>   drm/msm/dp: incorporate pm_runtime framework into DP driver
>   drm/msm/dp: delete EV_HPD_INIT_SETUP
>   drm/msm/dp: move of_dp_aux_populate_bus() to eDP probe()
> 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |   4 -
>  drivers/gpu/drm/msm/dp/dp_aux.c |  39 +++-
>  drivers/gpu/drm/msm/dp/dp_display.c | 333 
> 
>  drivers/gpu/drm/msm/dp/dp_display.h |   3 +-
>  drivers/gpu/drm/msm/dp/dp_drm.c |  14 +-
>  drivers/gpu/drm/msm/dp/dp_power.c   |  16 --
>  drivers/gpu/drm/msm/dp/dp_power.h   |  11 --
>  drivers/gpu/drm/msm/msm_drv.h   |   5 -
>  8 files changed, 161 insertions(+), 264 deletions(-)
> 


Re: [PATCH v2 09/11] drm/mediatek: Add secure flow support to mediatek-drm

2023-11-05 Thread 胡俊光


Re: [PATCH v2 07/11] drm/mediatek: Add secure layer config support for ovl

2023-11-05 Thread 胡俊光


Re: [PATCH v2 10/11] drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt finalize

2023-11-05 Thread 胡俊光


Re: [PATCH v2 00/11] Add mediate-drm secure flow for SVP

2023-11-05 Thread 胡俊光


Re: [PATCH v2 10/11] drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt finalize

2023-11-05 Thread 林睿祥


Re: [PATCH v2 00/11] Add mediate-drm secure flow for SVP

2023-11-05 Thread 林睿祥


Re: [PATCH v18 25/26] drm/virtio: Support shmem shrinking

2023-11-05 Thread Dmitry Osipenko
On 11/4/23 01:55, Gurchetan Singh wrote:
> On Sun, Oct 29, 2023 at 4:03 PM Dmitry Osipenko <
> dmitry.osipe...@collabora.com> wrote:
> 
>> Support generic drm-shmem memory shrinker and add new madvise IOCTL to
>> the VirtIO-GPU driver. BO cache manager of Mesa driver will mark BOs as
>> "don't need" using the new IOCTL to let shrinker purge the marked BOs on
>> OOM, the shrinker will also evict unpurgeable shmem BOs from memory if
>> guest supports SWAP file or partition.
>>
>> Acked-by: Gerd Hoffmann 
>> Signed-off-by: Daniel Almeida 
>> Signed-off-by: Dmitry Osipenko 
>> ---
>>  drivers/gpu/drm/virtio/virtgpu_drv.h| 13 +-
>>  drivers/gpu/drm/virtio/virtgpu_gem.c| 35 ++
>>  drivers/gpu/drm/virtio/virtgpu_ioctl.c  | 25 ++
>>  drivers/gpu/drm/virtio/virtgpu_kms.c|  8 
>>  drivers/gpu/drm/virtio/virtgpu_object.c | 61 +
>>  drivers/gpu/drm/virtio/virtgpu_vq.c | 40 
>>  include/uapi/drm/virtgpu_drm.h  | 14 ++
>>  7 files changed, 195 insertions(+), 1 deletion(-)
...
> 
> Link to open-source userspace?

https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15278

I'll add it to the commit message

> Also, don't you need a VIRTGPU_PARAM_MADVISE_SUPPORTED or is the plan to
> use a DRM version?

The ioctl() returns error if DRM_VIRTGPU_MADVISE unsupported, extra
flags not needed by userspace

> Overall, the series for a generic shrinker seems useful for a wide variety
> of DRM drivers, such as Panfrost.
> 
> For virtio-gpu, it could be a tad VIRGIL specific: since other context
> types (gfxstream gles, DRM, vk contexts) decrease memory consumption by
> either not allocating shadow buffers for textures/buffers, or using blob
> memory.
> 
> Maybe we need to design with blob in mind, since we expect virgl to be
> deprecated.  On Android, it basically is with ANGLE and native contexts.
> On Linux, Zink looks good too.  Even with memory issues fixed, virgl is
> unattractive compared to those solutions.

We should finish shmem first since started with it, then move to blobs.

My rough idea for the blobs is to use a timer-based approach to avoid
frequent virtio syncing with host that will be bad for performance
otherwise. Virtio-gpu kernel driver will maintain a list of purgeable
blobs and will send the list of idling blobs down to host after a period
of inactivity.

Virgl may be not interesting for CrOS, but Qemu will continue supporting
it. I also expect that today's ARM Chromebooks which use Virgl and only
support GL will continue to use Virgl for the next 4 years.

> Android specific idea: I wonder if we could tie GEM blob buffers usage to
> the lmkd and kill based on that ... ?
> 
> https://source.android.com/docs/core/perf/lmkd
> 
> Is there GEM buffer accounting infrastructure already?

Are you talking about killing a guest APP that uses host blobs when host
is under pressure? I'm not familiar with how arcvm works, but may assume
that it runs a VM per APP. In that case VM is just another process from
the lmkd perspective that will be taken down on OOM, i.e. blob buffers
already should be seen as a part of a VM's memory by lmkd when they
reside in sysmem.

-- 
Best regards,
Dmitry



Re: Blank screen on boot of Linux 6.5 and later on Lenovo ThinkPad L570

2023-11-05 Thread Huacai Chen
Hi, Jaak and Evan,

On Mon, Nov 6, 2023 at 12:28 AM Jaak Ristioja  wrote:
>
> On 05.11.23 14:40, Huacai Chen wrote:
> > Hi, Evan,
> >
> > On Sat, Nov 4, 2023 at 10:50 AM Evan Preston  wrote:
> >>
> >> Hi Huacai,
> >>
> >> On 2023-11-03 Fri 02:36pm, Huacai Chen wrote:
> >>> Hi, Evan,
> >>>
> >>> On Fri, Nov 3, 2023 at 1:54 PM Evan Preston  wrote:
> 
>  Hi Huacai,
> 
>  On 2023-11-02 Thu 08:38pm, Huacai Chen wrote:
> > Hi, Jaak,
> >
> > On Wed, Nov 1, 2023 at 7:52 PM Jaak Ristioja  wrote:
> >>
> >> On 31.10.23 14:17, Huacai Chen wrote:
> >>> Hi, Jaak and Evan,
> >>>
> >>> On Sun, Oct 29, 2023 at 9:42 AM Huacai Chen  
> >>> wrote:
> 
>  On Sat, Oct 28, 2023 at 7:06 PM Jaak Ristioja  
>  wrote:
> >
> > On 26.10.23 03:58, Huacai Chen wrote:
> >> Hi, Jaak,
> >>
> >> On Thu, Oct 26, 2023 at 2:49 AM Jaak Ristioja  
> >> wrote:
> >>>
> >>> On 25.10.23 16:23, Huacai Chen wrote:
>  On Wed, Oct 25, 2023 at 6:08 PM Thorsten Leemhuis
>   wrote:
> >
> > Javier, Dave, Sima,
> >
> > On 23.10.23 00:54, Evan Preston wrote:
> >> On 2023-10-20 Fri 05:48pm, Huacai Chen wrote:
> >>> On Fri, Oct 20, 2023 at 5:35 PM Linux regression tracking 
> >>> (Thorsten
> >>> Leemhuis)  wrote:
>  On 09.10.23 10:54, Huacai Chen wrote:
> > On Mon, Oct 9, 2023 at 4:45 PM Bagas Sanjaya 
> >  wrote:
> >> On Mon, Oct 09, 2023 at 09:27:02AM +0800, Huacai Chen 
> >> wrote:
> >>> On Tue, Sep 26, 2023 at 10:31 PM Huacai Chen 
> >>>  wrote:
>  On Tue, Sep 26, 2023 at 7:15 PM Linux regression 
>  tracking (Thorsten
>  Leemhuis)  wrote:
> > On 13.09.23 14:02, Jaak Ristioja wrote:
> >>
> >> Upgrading to Linux 6.5 on a Lenovo ThinkPad L570 
> >> (Integrated Intel HD
> >> Graphics 620 (rev 02), Intel(R) Core(TM) i7-7500U) 
> >> results in a blank
> >> screen after boot until the display manager starts... 
> >> if it does start
> >> at all. Using the nomodeset kernel parameter seems to 
> >> be a workaround.
> >>
> >> I've bisected this to commit 
> >> 60aebc9559492cea6a9625f514a8041717e3a2e4
> >> ("drivers/firmware: Move sysfb_init() from 
> >> device_initcall to
> >> subsys_initcall_sync").
> >
> >>> As confirmed by Jaak, disabling DRM_SIMPLEDRM makes 
> >>> things work fine
> >>> again. So I guess the reason:
> 
>  Well, this to me still looks a lot (please correct me if I'm 
>  wrong) like
>  regression that should be fixed, as DRM_SIMPLEDRM was 
>  enabled beforehand
>  if I understood things correctly. Or is there a proper fix 
>  for this
>  already in the works and I just missed this? Or is there 
>  some good
>  reason why this won't/can't be fixed?
> >>>
> >>> DRM_SIMPLEDRM was enabled but it didn't work at all because 
> >>> there was
> >>> no corresponding platform device. Now DRM_SIMPLEDRM works but 
> >>> it has a
> >>> blank screen. Of course it is valuable to investigate further 
> >>> about
> >>> DRM_SIMPLEDRM on Jaak's machine, but that needs Jaak's effort 
> >>> because
> >>> I don't have a same machine.
> >
> > Side note: Huacai, have you tried working with Jaak to get down 
> > to the
> > real problem? Evan, might you be able to help out here?
>  No, Jaak has no response after he 'fixed' his problem by 
>  disabling SIMPLEDRM.
> 
> >>>
> >>> I'm sorry, what was it exactly you want me to do? Please be 
> >>> mindful that
> >>> I'm not familiar with the internals of the Linux kernel and DRI, 
> >>> and it
> >>> might sometimes take weeks before I have time to work and respond 
> >>> on this.
> >> It doesn't matter. I hope you can do some experiments to 
> >> investigate
> >> deeper. The first experiment you can do is enabling SIMPLEFB (i.e.
> >> CONFIG_FB_SIMPLE) instead of SIMPLEDRM (CONFIG_DRM_SIMPLEDRM) to 
> >> see
> >> whether there is also a blank screen. If no blank scre

[RFC PATCH v3 00/12] Device Memory TCP

2023-11-05 Thread Mina Almasry
Changes in RFC v3:
--

1. Pulled in the memory-provider dependency from Jakub's RFC[1] to make the
   series reviewable and mergable.

2. Implemented multi-rx-queue binding which was a todo in v2.

3. Fix to cmsg handling.

The sticking point in RFC v2[2] was the device reset required to refill
the device rx-queues after the dmabuf bind/unbind. The solution
suggested as I understand is a subset of the per-queue management ops
Jakub suggested or similar:

https://lore.kernel.org/netdev/20230815171638.4c057...@kernel.org/

This is not addressed in this revision, because:

1. This point was discussed at netconf & netdev and there is openness to
   using the current approach of requiring a device reset.

2. Implementing individual queue resetting seems to be difficult for my
   test bed with GVE. My prototype to test this ran into issues with the
   rx-queues not coming back up properly if reset individually. At the
   moment I'm unsure if it's a mistake in the POC or a genuine issue in
   the virtualization stack behind GVE, which currently doesn't test
   individual rx-queue restart.

3. Our usecases are not bothered by requiring a device reset to refill
   the buffer queues, and we'd like to support NICs that run into this
   limitation with resetting individual queues.

My thought is that drivers that have trouble with per-queue configs can
use the support in this series, while drivers that support new netdev
ops to reset individual queues can automatically reset the queue as
part of the dma-buf bind/unbind.

The same approach with device resets is presented again for consideration
with other sticking points addressed.

This proposal includes the rx devmem path only proposed for merge. For a
snapshot of my entire tree which includes the GVE POC page pool support &
device memory support:

https://github.com/torvalds/linux/compare/master...mina:linux:tcpdevmem-v3

[1] 
https://lore.kernel.org/netdev/f8270765-a27b-6ccf-33ea-cda097168...@redhat.com/T/
[2] 
https://lore.kernel.org/netdev/cahs8izovjgjh5wf68osrwfkjid1_huzzuk+hpkblcl4psod...@mail.gmail.com/T/

Cc: Shakeel Butt 
Cc: Jeroen de Borst 
Cc: Praveen Kaligineedi 

Changes in RFC v2:
--

The sticking point in RFC v1[1] was the dma-buf pages approach we used to
deliver the device memory to the TCP stack. RFC v2 is a proof-of-concept
that attempts to resolve this by implementing scatterlist support in the
networking stack, such that we can import the dma-buf scatterlist
directly. This is the approach proposed at a high level here[2].

Detailed changes:
1. Replaced dma-buf pages approach with importing scatterlist into the
   page pool.
2. Replace the dma-buf pages centric API with a netlink API.
3. Removed the TX path implementation - there is no issue with
   implementing the TX path with scatterlist approach, but leaving
   out the TX path makes it easier to review.
4. Functionality is tested with this proposal, but I have not conducted
   perf testing yet. I'm not sure there are regressions, but I removed
   perf claims from the cover letter until they can be re-confirmed.
5. Added Signed-off-by: contributors to the implementation.
6. Fixed some bugs with the RX path since RFC v1.

Any feedback welcome, but specifically the biggest pending questions
needing feedback IMO are:

1. Feedback on the scatterlist-based approach in general.
2. Netlink API (Patch 1 & 2).
3. Approach to handle all the drivers that expect to receive pages from
   the page pool (Patch 6).

[1] 
https://lore.kernel.org/netdev/dfe4bae7-13a0-3c5d-d671-f61b375cb...@gmail.com/T/
[2] 
https://lore.kernel.org/netdev/CAHS8izPm6XRS54LdCDZVd0C75tA1zHSu6jLVO8nzTLXCc=h...@mail.gmail.com/

--

* TL;DR:

Device memory TCP (devmem TCP) is a proposal for transferring data to and/or
from device memory efficiently, without bouncing the data to a host memory
buffer.

* Problem:

A large amount of data transfers have device memory as the source and/or
destination. Accelerators drastically increased the volume of such transfers.
Some examples include:
- ML accelerators transferring large amounts of training data from storage into
  GPU/TPU memory. In some cases ML training setup time can be as long as 50% of
  TPU compute time, improving data transfer throughput & efficiency can help
  improving GPU/TPU utilization.

- Distributed training, where ML accelerators, such as GPUs on different hosts,
  exchange data among them.

- Distributed raw block storage applications transfer large amounts of data with
  remote SSDs, much of this data does not require host processing.

Today, the majority of the Device-to-Device data transfers the network are
implemented as the following low level operations: Device-to-Host copy,
Host-to-Host network transfer, and Host-to-Device copy.

The implementation is suboptimal, especially for bulk data transfers, and can
put significant strains on system resources, such as host memory bandwidth,
PCIe bandwidth, etc. One import

[RFC PATCH v3 02/12] net: page_pool: create hooks for custom page providers

2023-11-05 Thread Mina Almasry
From: Jakub Kicinski 

The page providers which try to reuse the same pages will
need to hold onto the ref, even if page gets released from
the pool - as in releasing the page from the pp just transfers
the "ownership" reference from pp to the provider, and provider
will wait for other references to be gone before feeding this
page back into the pool.

Signed-off-by: Jakub Kicinski 
Signed-off-by: Mina Almasry 


---

This is implemented by Jakub in his RFC:
https://lore.kernel.org/netdev/f8270765-a27b-6ccf-33ea-cda097168...@redhat.com/T/

I take no credit for the idea or implementation; I only added minor
edits to make this workable with device memory TCP, and removed some
hacky test code. This is a critical dependency of device memory TCP
and thus I'm pulling it into this series to make it revewable and
mergable.

---
 include/net/page_pool/types.h | 18 +
 net/core/page_pool.c  | 51 +++
 2 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
index 6fc5134095ed..d4bea053bb7e 100644
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -60,6 +60,8 @@ struct page_pool_params {
int nid;
struct device   *dev;
struct napi_struct *napi;
+   u8  memory_provider;
+   void*mp_priv;
enum dma_data_direction dma_dir;
unsigned intmax_len;
unsigned intoffset;
@@ -118,6 +120,19 @@ struct page_pool_stats {
 };
 #endif
 
+struct mem_provider;
+
+enum pp_memory_provider_type {
+   __PP_MP_NONE, /* Use system allocator directly */
+};
+
+struct pp_memory_provider_ops {
+   int (*init)(struct page_pool *pool);
+   void (*destroy)(struct page_pool *pool);
+   struct page *(*alloc_pages)(struct page_pool *pool, gfp_t gfp);
+   bool (*release_page)(struct page_pool *pool, struct page *page);
+};
+
 struct page_pool {
struct page_pool_params p;
 
@@ -165,6 +180,9 @@ struct page_pool {
 */
struct ptr_ring ring;
 
+   const struct pp_memory_provider_ops *mp_ops;
+   void *mp_priv;
+
 #ifdef CONFIG_PAGE_POOL_STATS
/* recycle stats are per-cpu to avoid locking */
struct page_pool_recycle_stats __percpu *recycle_stats;
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 578b6f2eeb46..7ea1f4682479 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -23,6 +23,8 @@
 
 #include 
 
+static DEFINE_STATIC_KEY_FALSE(page_pool_mem_providers);
+
 #define DEFER_TIME (msecs_to_jiffies(1000))
 #define DEFER_WARN_INTERVAL (60 * HZ)
 
@@ -172,6 +174,7 @@ static int page_pool_init(struct page_pool *pool,
  const struct page_pool_params *params)
 {
unsigned int ring_qsize = 1024; /* Default */
+   int err;
 
memcpy(&pool->p, params, sizeof(pool->p));
 
@@ -225,10 +228,34 @@ static int page_pool_init(struct page_pool *pool,
/* Driver calling page_pool_create() also call page_pool_destroy() */
refcount_set(&pool->user_cnt, 1);
 
+   switch (pool->p.memory_provider) {
+   case __PP_MP_NONE:
+   break;
+   default:
+   err = -EINVAL;
+   goto free_ptr_ring;
+   }
+
+   pool->mp_priv = pool->p.mp_priv;
+   if (pool->mp_ops) {
+   err = pool->mp_ops->init(pool);
+   if (err) {
+   pr_warn("%s() mem-provider init failed %d\n",
+   __func__, err);
+   goto free_ptr_ring;
+   }
+
+   static_branch_inc(&page_pool_mem_providers);
+   }
+
if (pool->p.flags & PP_FLAG_DMA_MAP)
get_device(pool->p.dev);
 
return 0;
+
+free_ptr_ring:
+   ptr_ring_cleanup(&pool->ring, NULL);
+   return err;
 }
 
 /**
@@ -490,7 +517,10 @@ struct page *page_pool_alloc_pages(struct page_pool *pool, 
gfp_t gfp)
return page;
 
/* Slow-path: cache empty, do real allocation */
-   page = __page_pool_alloc_pages_slow(pool, gfp);
+   if (static_branch_unlikely(&page_pool_mem_providers) && pool->mp_ops)
+   page = pool->mp_ops->alloc_pages(pool, gfp);
+   else
+   page = __page_pool_alloc_pages_slow(pool, gfp);
return page;
 }
 EXPORT_SYMBOL(page_pool_alloc_pages);
@@ -542,10 +572,13 @@ void __page_pool_release_page_dma(struct page_pool *pool, 
struct page *page)
 void page_pool_return_page(struct page_pool *pool, struct page *page)
 {
int count;
+   bool put;
 
-   __page_pool_release_page_dma(pool, page);
-
-   page_pool_clear_pp_info(page);
+   put = true;
+   if (static_branch_unlikely(&page_pool_mem_providers) && pool->mp_ops)
+   put = pool->mp_ops->release_page(pool, page);
+   else
+   __page_pool_release_page_dma(pool, page);
 
/* This may be the last p

[RFC PATCH v3 03/12] net: netdev netlink api to bind dma-buf to a net device

2023-11-05 Thread Mina Almasry
API takes the dma-buf fd as input, and binds it to the netdevice. The
user can specify the rx queues to bind the dma-buf to.

Suggested-by: Stanislav Fomichev 
Signed-off-by: Mina Almasry 

---

Changes in v3:
- Support binding multiple rx rx-queues

---
 Documentation/netlink/specs/netdev.yaml | 28 +++
 include/uapi/linux/netdev.h | 10 ++
 net/core/netdev-genl-gen.c  | 14 
 net/core/netdev-genl-gen.h  |  1 +
 net/core/netdev-genl.c  |  6 
 tools/include/uapi/linux/netdev.h   | 10 ++
 tools/net/ynl/generated/netdev-user.c   | 42 ++
 tools/net/ynl/generated/netdev-user.h   | 47 +
 8 files changed, 158 insertions(+)

diff --git a/Documentation/netlink/specs/netdev.yaml 
b/Documentation/netlink/specs/netdev.yaml
index 14511b13f305..2141c5f5c33e 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -86,6 +86,24 @@ attribute-sets:
  See Documentation/networking/xdp-rx-metadata.rst for more details.
 type: u64
 enum: xdp-rx-metadata
+  -
+name: bind-dmabuf
+attributes:
+  -
+name: ifindex
+doc: netdev ifindex to bind the dma-buf to.
+type: u32
+checks:
+  min: 1
+  -
+name: queues
+doc: receive queues to bind the dma-buf to.
+type: u32
+multi-attr: true
+  -
+name: dmabuf-fd
+doc: dmabuf file descriptor to bind.
+type: u32
 
 operations:
   list:
@@ -120,6 +138,16 @@ operations:
   doc: Notification about device configuration being changed.
   notify: dev-get
   mcgrp: mgmt
+-
+  name: bind-rx
+  doc: Bind dmabuf to netdev
+  attribute-set: bind-dmabuf
+  do:
+request:
+  attributes:
+- ifindex
+- dmabuf-fd
+- queues
 
 mcast-groups:
   list:
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 2943a151d4f1..2cd367c498c7 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -64,11 +64,21 @@ enum {
NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
 };
 
+enum {
+   NETDEV_A_BIND_DMABUF_IFINDEX = 1,
+   NETDEV_A_BIND_DMABUF_QUEUES,
+   NETDEV_A_BIND_DMABUF_DMABUF_FD,
+
+   __NETDEV_A_BIND_DMABUF_MAX,
+   NETDEV_A_BIND_DMABUF_MAX = (__NETDEV_A_BIND_DMABUF_MAX - 1)
+};
+
 enum {
NETDEV_CMD_DEV_GET = 1,
NETDEV_CMD_DEV_ADD_NTF,
NETDEV_CMD_DEV_DEL_NTF,
NETDEV_CMD_DEV_CHANGE_NTF,
+   NETDEV_CMD_BIND_RX,
 
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
index ea9231378aa6..58300efaf4e5 100644
--- a/net/core/netdev-genl-gen.c
+++ b/net/core/netdev-genl-gen.c
@@ -15,6 +15,13 @@ static const struct nla_policy 
netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 1
[NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
 };
 
+/* NETDEV_CMD_BIND_RX - do */
+static const struct nla_policy 
netdev_bind_rx_nl_policy[NETDEV_A_BIND_DMABUF_DMABUF_FD + 1] = {
+   [NETDEV_A_BIND_DMABUF_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+   [NETDEV_A_BIND_DMABUF_DMABUF_FD] = { .type = NLA_U32, },
+   [NETDEV_A_BIND_DMABUF_QUEUES] = { .type = NLA_U32, },
+};
+
 /* Ops table for netdev */
 static const struct genl_split_ops netdev_nl_ops[] = {
{
@@ -29,6 +36,13 @@ static const struct genl_split_ops netdev_nl_ops[] = {
.dumpit = netdev_nl_dev_get_dumpit,
.flags  = GENL_CMD_CAP_DUMP,
},
+   {
+   .cmd= NETDEV_CMD_BIND_RX,
+   .doit   = netdev_nl_bind_rx_doit,
+   .policy = netdev_bind_rx_nl_policy,
+   .maxattr= NETDEV_A_BIND_DMABUF_DMABUF_FD,
+   .flags  = GENL_CMD_CAP_DO,
+   },
 };
 
 static const struct genl_multicast_group netdev_nl_mcgrps[] = {
diff --git a/net/core/netdev-genl-gen.h b/net/core/netdev-genl-gen.h
index 7b370c073e7d..5aaeb435ec08 100644
--- a/net/core/netdev-genl-gen.h
+++ b/net/core/netdev-genl-gen.h
@@ -13,6 +13,7 @@
 
 int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info);
 int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info);
 
 enum {
NETDEV_NLGRP_MGMT,
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index fe61f85bcf33..59d3d512d9cc 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -129,6 +129,12 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct 
netlink_callback *cb)
return skb->len;
 }
 
+/* Stub */
+int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
+{
+   return 0;
+}
+
 static int netdev_genl_netdevice_event(struct notifier_block *nb,
  

[RFC PATCH v3 01/12] net: page_pool: factor out releasing DMA from releasing the page

2023-11-05 Thread Mina Almasry
From: Jakub Kicinski 

Releasing the DMA mapping will be useful for other types
of pages, so factor it out. Make sure compiler inlines it,
to avoid any regressions.

Signed-off-by: Jakub Kicinski 
Signed-off-by: Mina Almasry 

---

This is implemented by Jakub in his RFC:

https://lore.kernel.org/netdev/f8270765-a27b-6ccf-33ea-cda097168...@redhat.com/T/

I take no credit for the idea or implementation. This is a critical
dependency of device memory TCP and thus I'm pulling it into this series
to make it revewable and mergable.

---
 net/core/page_pool.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 5e409b98aba0..578b6f2eeb46 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -514,21 +514,16 @@ static s32 page_pool_inflight(struct page_pool *pool)
return inflight;
 }
 
-/* Disconnects a page (from a page_pool).  API users can have a need
- * to disconnect a page (from a page_pool), to allow it to be used as
- * a regular page (that will eventually be returned to the normal
- * page-allocator via put_page).
- */
-static void page_pool_return_page(struct page_pool *pool, struct page *page)
+static __always_inline
+void __page_pool_release_page_dma(struct page_pool *pool, struct page *page)
 {
dma_addr_t dma;
-   int count;
 
if (!(pool->p.flags & PP_FLAG_DMA_MAP))
/* Always account for inflight pages, even if we didn't
 * map them
 */
-   goto skip_dma_unmap;
+   return;
 
dma = page_pool_get_dma_addr(page);
 
@@ -537,7 +532,19 @@ static void page_pool_return_page(struct page_pool *pool, 
struct page *page)
 PAGE_SIZE << pool->p.order, pool->p.dma_dir,
 DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING);
page_pool_set_dma_addr(page, 0);
-skip_dma_unmap:
+}
+
+/* Disconnects a page (from a page_pool).  API users can have a need
+ * to disconnect a page (from a page_pool), to allow it to be used as
+ * a regular page (that will eventually be returned to the normal
+ * page-allocator via put_page).
+ */
+void page_pool_return_page(struct page_pool *pool, struct page *page)
+{
+   int count;
+
+   __page_pool_release_page_dma(pool, page);
+
page_pool_clear_pp_info(page);
 
/* This may be the last page returned, releasing the pool, so
-- 
2.42.0.869.gea05f2083d-goog



[RFC PATCH v3 04/12] netdev: support binding dma-buf to netdevice

2023-11-05 Thread Mina Almasry
Add a netdev_dmabuf_binding struct which represents the
dma-buf-to-netdevice binding. The netlink API will bind the dma-buf to
rx queues on the netdevice. On the binding, the dma_buf_attach
& dma_buf_map_attachment will occur. The entries in the sg_table from
mapping will be inserted into a genpool to make it ready
for allocation.

The chunks in the genpool are owned by a dmabuf_chunk_owner struct which
holds the dma-buf offset of the base of the chunk and the dma_addr of
the chunk. Both are needed to use allocations that come from this chunk.

We create a new type that represents an allocation from the genpool:
page_pool_iov. We setup the page_pool_iov allocation size in the
genpool to PAGE_SIZE for simplicity: to match the PAGE_SIZE normally
allocated by the page pool and given to the drivers.

The user can unbind the dmabuf from the netdevice by closing the netlink
socket that established the binding. We do this so that the binding is
automatically unbound even if the userspace process crashes.

The binding and unbinding leaves an indicator in struct netdev_rx_queue
that the given queue is bound, but the binding doesn't take effect until
the driver actually reconfigures its queues, and re-initializes its page
pool.

The netdev_dmabuf_binding struct is refcounted, and releases its
resources only when all the refs are released.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---

RFC v3:
- Support multi rx-queue binding

---
 include/linux/netdevice.h |  80 ++
 include/net/netdev_rx_queue.h |   1 +
 include/net/page_pool/types.h |  27 +
 net/core/dev.c| 203 ++
 net/core/netdev-genl.c| 116 ++-
 5 files changed, 425 insertions(+), 2 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b8bf669212cc..eeeda849115c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -52,6 +52,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 struct netpoll_info;
 struct device;
@@ -808,6 +810,84 @@ bool rps_may_expire_flow(struct net_device *dev, u16 
rxq_index, u32 flow_id,
 #endif
 #endif /* CONFIG_RPS */
 
+struct netdev_dmabuf_binding {
+   struct dma_buf *dmabuf;
+   struct dma_buf_attachment *attachment;
+   struct sg_table *sgt;
+   struct net_device *dev;
+   struct gen_pool *chunk_pool;
+
+   /* The user holds a ref (via the netlink API) for as long as they want
+* the binding to remain alive. Each page pool using this binding holds
+* a ref to keep the binding alive. Each allocated page_pool_iov holds a
+* ref.
+*
+* The binding undos itself and unmaps the underlying dmabuf once all
+* those refs are dropped and the binding is no longer desired or in
+* use.
+*/
+   refcount_t ref;
+
+   /* The portid of the user that owns this binding. Used for netlink to
+* notify us of the user dropping the bind.
+*/
+   u32 owner_nlportid;
+
+   /* The list of bindings currently active. Used for netlink to notify us
+* of the user dropping the bind.
+*/
+   struct list_head list;
+
+   /* rxq's this binding is active on. */
+   struct xarray bound_rxq_list;
+};
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+void __netdev_devmem_binding_free(struct netdev_dmabuf_binding *binding);
+int netdev_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
+  struct netdev_dmabuf_binding **out);
+void netdev_unbind_dmabuf(struct netdev_dmabuf_binding *binding);
+int netdev_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
+   struct netdev_dmabuf_binding *binding);
+#else
+static inline void
+__netdev_devmem_binding_free(struct netdev_dmabuf_binding *binding)
+{
+}
+
+static inline int netdev_bind_dmabuf(struct net_device *dev,
+unsigned int dmabuf_fd,
+struct netdev_dmabuf_binding **out)
+{
+   return -EOPNOTSUPP;
+}
+static inline void netdev_unbind_dmabuf(struct netdev_dmabuf_binding *binding)
+{
+}
+
+static inline int
+netdev_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
+   struct netdev_dmabuf_binding *binding)
+{
+   return -EOPNOTSUPP;
+}
+#endif
+
+static inline void
+netdev_devmem_binding_get(struct netdev_dmabuf_binding *binding)
+{
+   refcount_inc(&binding->ref);
+}
+
+static inline void
+netdev_devmem_binding_put(struct netdev_dmabuf_binding *binding)
+{
+   if (!refcount_dec_and_test(&binding->ref))
+   return;
+
+   __netdev_devmem_binding_free(binding);
+}
+
 /* XPS map type and offset of the xps map within net_device->xps_maps[]. */
 enum xps_map_type {
XPS_CPUS = 0,
diff --git a/include/net/netdev_rx_queue.h b/include/net/netdev_rx_queue.h
index cdcafb30d437..1bfcf60a145d 100644

[RFC PATCH v3 05/12] netdev: netdevice devmem allocator

2023-11-05 Thread Mina Almasry
Implement netdev devmem allocator. The allocator takes a given struct
netdev_dmabuf_binding as input and allocates page_pool_iov from that
binding.

The allocation simply delegates to the binding's genpool for the
allocation logic and wraps the returned memory region in a page_pool_iov
struct.

page_pool_iov are refcounted and are freed back to the binding when the
refcount drops to 0.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---
 include/linux/netdevice.h   | 13 
 include/net/page_pool/helpers.h | 28 +
 net/core/dev.c  | 37 +
 3 files changed, 78 insertions(+)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index eeeda849115c..1c351c138a5b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -843,6 +843,9 @@ struct netdev_dmabuf_binding {
 };
 
 #ifdef CONFIG_DMA_SHARED_BUFFER
+struct page_pool_iov *
+netdev_alloc_devmem(struct netdev_dmabuf_binding *binding);
+void netdev_free_devmem(struct page_pool_iov *ppiov);
 void __netdev_devmem_binding_free(struct netdev_dmabuf_binding *binding);
 int netdev_bind_dmabuf(struct net_device *dev, unsigned int dmabuf_fd,
   struct netdev_dmabuf_binding **out);
@@ -850,6 +853,16 @@ void netdev_unbind_dmabuf(struct netdev_dmabuf_binding 
*binding);
 int netdev_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
struct netdev_dmabuf_binding *binding);
 #else
+static inline struct page_pool_iov *
+netdev_alloc_devmem(struct netdev_dmabuf_binding *binding)
+{
+   return NULL;
+}
+
+static inline void netdev_free_devmem(struct page_pool_iov *ppiov)
+{
+}
+
 static inline void
 __netdev_devmem_binding_free(struct netdev_dmabuf_binding *binding)
 {
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 4ebd544ae977..78cbb040af94 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -83,6 +83,34 @@ static inline u64 *page_pool_ethtool_stats_get(u64 *data, 
void *stats)
 }
 #endif
 
+/* page_pool_iov support */
+
+static inline struct dmabuf_genpool_chunk_owner *
+page_pool_iov_owner(const struct page_pool_iov *ppiov)
+{
+   return ppiov->owner;
+}
+
+static inline unsigned int page_pool_iov_idx(const struct page_pool_iov *ppiov)
+{
+   return ppiov - page_pool_iov_owner(ppiov)->ppiovs;
+}
+
+static inline dma_addr_t
+page_pool_iov_dma_addr(const struct page_pool_iov *ppiov)
+{
+   struct dmabuf_genpool_chunk_owner *owner = page_pool_iov_owner(ppiov);
+
+   return owner->base_dma_addr +
+  ((dma_addr_t)page_pool_iov_idx(ppiov) << PAGE_SHIFT);
+}
+
+static inline struct netdev_dmabuf_binding *
+page_pool_iov_binding(const struct page_pool_iov *ppiov)
+{
+   return page_pool_iov_owner(ppiov)->binding;
+}
+
 /**
  * page_pool_dev_alloc_pages() - allocate a page.
  * @pool:  pool from which to allocate
diff --git a/net/core/dev.c b/net/core/dev.c
index c8c3709d42c8..2315bbc03ec8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -156,6 +156,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dev.h"
 #include "net-sysfs.h"
@@ -2077,6 +2078,42 @@ void __netdev_devmem_binding_free(struct 
netdev_dmabuf_binding *binding)
kfree(binding);
 }
 
+struct page_pool_iov *netdev_alloc_devmem(struct netdev_dmabuf_binding 
*binding)
+{
+   struct dmabuf_genpool_chunk_owner *owner;
+   struct page_pool_iov *ppiov;
+   unsigned long dma_addr;
+   ssize_t offset;
+   ssize_t index;
+
+   dma_addr = gen_pool_alloc_owner(binding->chunk_pool, PAGE_SIZE,
+   (void **)&owner);
+   if (!dma_addr)
+   return NULL;
+
+   offset = dma_addr - owner->base_dma_addr;
+   index = offset / PAGE_SIZE;
+   ppiov = &owner->ppiovs[index];
+
+   netdev_devmem_binding_get(binding);
+
+   return ppiov;
+}
+
+void netdev_free_devmem(struct page_pool_iov *ppiov)
+{
+   struct netdev_dmabuf_binding *binding = page_pool_iov_binding(ppiov);
+
+   refcount_set(&ppiov->refcount, 1);
+
+   if (gen_pool_has_addr(binding->chunk_pool,
+ page_pool_iov_dma_addr(ppiov), PAGE_SIZE))
+   gen_pool_free(binding->chunk_pool,
+ page_pool_iov_dma_addr(ppiov), PAGE_SIZE);
+
+   netdev_devmem_binding_put(binding);
+}
+
 void netdev_unbind_dmabuf(struct netdev_dmabuf_binding *binding)
 {
struct netdev_rx_queue *rxq;
-- 
2.42.0.869.gea05f2083d-goog



[RFC PATCH v3 06/12] memory-provider: dmabuf devmem memory provider

2023-11-05 Thread Mina Almasry
Implement a memory provider that allocates dmabuf devmem page_pool_iovs.

Support of PP_FLAG_DMA_MAP and PP_FLAG_DMA_SYNC_DEV is omitted for
simplicity.

The provider receives a reference to the struct netdev_dmabuf_binding
via the pool->mp_priv pointer. The driver needs to set this pointer for
the provider in the page_pool_params.

The provider obtains a reference on the netdev_dmabuf_binding which
guarantees the binding and the underlying mapping remains alive until
the provider is destroyed.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---
 include/net/page_pool/helpers.h | 40 +
 include/net/page_pool/types.h   | 10 +
 net/core/page_pool.c| 76 +
 3 files changed, 126 insertions(+)

diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 78cbb040af94..b93243c2a640 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -53,6 +53,7 @@
 #define _NET_PAGE_POOL_HELPERS_H
 
 #include 
+#include 
 
 #ifdef CONFIG_PAGE_POOL_STATS
 int page_pool_ethtool_stats_get_count(void);
@@ -111,6 +112,45 @@ page_pool_iov_binding(const struct page_pool_iov *ppiov)
return page_pool_iov_owner(ppiov)->binding;
 }
 
+static inline int page_pool_iov_refcount(const struct page_pool_iov *ppiov)
+{
+   return refcount_read(&ppiov->refcount);
+}
+
+static inline void page_pool_iov_get_many(struct page_pool_iov *ppiov,
+ unsigned int count)
+{
+   refcount_add(count, &ppiov->refcount);
+}
+
+void __page_pool_iov_free(struct page_pool_iov *ppiov);
+
+static inline void page_pool_iov_put_many(struct page_pool_iov *ppiov,
+ unsigned int count)
+{
+   if (!refcount_sub_and_test(count, &ppiov->refcount))
+   return;
+
+   __page_pool_iov_free(ppiov);
+}
+
+/* page pool mm helpers */
+
+static inline bool page_is_page_pool_iov(const struct page *page)
+{
+   return (unsigned long)page & PP_DEVMEM;
+}
+
+static inline struct page_pool_iov *page_to_page_pool_iov(struct page *page)
+{
+   if (page_is_page_pool_iov(page))
+   return (struct page_pool_iov *)((unsigned long)page &
+   ~PP_DEVMEM);
+
+   DEBUG_NET_WARN_ON_ONCE(true);
+   return NULL;
+}
+
 /**
  * page_pool_dev_alloc_pages() - allocate a page.
  * @pool:  pool from which to allocate
diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
index 64386325d965..1e67f9466250 100644
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -124,6 +124,7 @@ struct mem_provider;
 
 enum pp_memory_provider_type {
__PP_MP_NONE, /* Use system allocator directly */
+   PP_MP_DMABUF_DEVMEM, /* dmabuf devmem provider */
 };
 
 struct pp_memory_provider_ops {
@@ -133,8 +134,15 @@ struct pp_memory_provider_ops {
bool (*release_page)(struct page_pool *pool, struct page *page);
 };
 
+extern const struct pp_memory_provider_ops dmabuf_devmem_ops;
+
 /* page_pool_iov support */
 
+/*  We overload the LSB of the struct page pointer to indicate whether it's
+ *  a page or page_pool_iov.
+ */
+#define PP_DEVMEM 0x01UL
+
 /* Owner of the dma-buf chunks inserted into the gen pool. Each scatterlist
  * entry from the dmabuf is inserted into the genpool as a chunk, and needs
  * this owner struct to keep track of some metadata necessary to create
@@ -158,6 +166,8 @@ struct page_pool_iov {
struct dmabuf_genpool_chunk_owner *owner;
 
refcount_t refcount;
+
+   struct page_pool *pp;
 };
 
 struct page_pool {
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 7ea1f4682479..138ddea0b28f 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -231,6 +232,9 @@ static int page_pool_init(struct page_pool *pool,
switch (pool->p.memory_provider) {
case __PP_MP_NONE:
break;
+   case PP_MP_DMABUF_DEVMEM:
+   pool->mp_ops = &dmabuf_devmem_ops;
+   break;
default:
err = -EINVAL;
goto free_ptr_ring;
@@ -996,3 +1000,75 @@ void page_pool_update_nid(struct page_pool *pool, int 
new_nid)
}
 }
 EXPORT_SYMBOL(page_pool_update_nid);
+
+void __page_pool_iov_free(struct page_pool_iov *ppiov)
+{
+   if (ppiov->pp->mp_ops != &dmabuf_devmem_ops)
+   return;
+
+   netdev_free_devmem(ppiov);
+}
+EXPORT_SYMBOL_GPL(__page_pool_iov_free);
+
+/*** "Dmabuf devmem memory provider" ***/
+
+static int mp_dmabuf_devmem_init(struct page_pool *pool)
+{
+   struct netdev_dmabuf_binding *binding = pool->mp_priv;
+
+   if (!binding)
+   return -EINVAL;
+
+   if (pool->p.flags & PP_FLAG_DMA_MAP ||
+   pool->p.flags & PP_FLAG_DMA_SYNC_DEV)
+   return -EOPN

[RFC PATCH v3 07/12] page-pool: device memory support

2023-11-05 Thread Mina Almasry
Overload the LSB of struct page* to indicate that it's a page_pool_iov.

Refactor mm calls on struct page* into helpers, and add page_pool_iov
handling on those helpers. Modify callers of these mm APIs with calls to
these helpers instead.

In areas where struct page* is dereferenced, add a check for special
handling of page_pool_iov.

Signed-off-by: Mina Almasry 

---
 include/net/page_pool/helpers.h | 74 -
 net/core/page_pool.c| 63 
 2 files changed, 118 insertions(+), 19 deletions(-)

diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index b93243c2a640..08f1a2cc70d2 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -151,6 +151,64 @@ static inline struct page_pool_iov 
*page_to_page_pool_iov(struct page *page)
return NULL;
 }
 
+static inline int page_pool_page_ref_count(struct page *page)
+{
+   if (page_is_page_pool_iov(page))
+   return page_pool_iov_refcount(page_to_page_pool_iov(page));
+
+   return page_ref_count(page);
+}
+
+static inline void page_pool_page_get_many(struct page *page,
+  unsigned int count)
+{
+   if (page_is_page_pool_iov(page))
+   return page_pool_iov_get_many(page_to_page_pool_iov(page),
+ count);
+
+   return page_ref_add(page, count);
+}
+
+static inline void page_pool_page_put_many(struct page *page,
+  unsigned int count)
+{
+   if (page_is_page_pool_iov(page))
+   return page_pool_iov_put_many(page_to_page_pool_iov(page),
+ count);
+
+   if (count > 1)
+   page_ref_sub(page, count - 1);
+
+   put_page(page);
+}
+
+static inline bool page_pool_page_is_pfmemalloc(struct page *page)
+{
+   if (page_is_page_pool_iov(page))
+   return false;
+
+   return page_is_pfmemalloc(page);
+}
+
+static inline bool page_pool_page_is_pref_nid(struct page *page, int pref_nid)
+{
+   /* Assume page_pool_iov are on the preferred node without actually
+* checking...
+*
+* This check is only used to check for recycling memory in the page
+* pool's fast paths. Currently the only implementation of page_pool_iov
+* is dmabuf device memory. It's a deliberate decision by the user to
+* bind a certain dmabuf to a certain netdev, and the netdev rx queue
+* would not be able to reallocate memory from another dmabuf that
+* exists on the preferred node, so, this check doesn't make much sense
+* in this case. Assume all page_pool_iovs can be recycled for now.
+*/
+   if (page_is_page_pool_iov(page))
+   return true;
+
+   return page_to_nid(page) == pref_nid;
+}
+
 /**
  * page_pool_dev_alloc_pages() - allocate a page.
  * @pool:  pool from which to allocate
@@ -301,6 +359,9 @@ static inline long page_pool_defrag_page(struct page *page, 
long nr)
 {
long ret;
 
+   if (page_is_page_pool_iov(page))
+   return -EINVAL;
+
/* If nr == pp_frag_count then we have cleared all remaining
 * references to the page:
 * 1. 'n == 1': no need to actually overwrite it.
@@ -431,7 +492,12 @@ static inline void page_pool_free_va(struct page_pool 
*pool, void *va,
  */
 static inline dma_addr_t page_pool_get_dma_addr(struct page *page)
 {
-   dma_addr_t ret = page->dma_addr;
+   dma_addr_t ret;
+
+   if (page_is_page_pool_iov(page))
+   return page_pool_iov_dma_addr(page_to_page_pool_iov(page));
+
+   ret = page->dma_addr;
 
if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA)
ret <<= PAGE_SHIFT;
@@ -441,6 +507,12 @@ static inline dma_addr_t page_pool_get_dma_addr(struct 
page *page)
 
 static inline bool page_pool_set_dma_addr(struct page *page, dma_addr_t addr)
 {
+   /* page_pool_iovs are mapped and their dma-addr can't be modified. */
+   if (page_is_page_pool_iov(page)) {
+   DEBUG_NET_WARN_ON_ONCE(true);
+   return false;
+   }
+
if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA) {
page->dma_addr = addr >> PAGE_SHIFT;
 
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 138ddea0b28f..d211996d423b 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -317,7 +317,7 @@ static struct page *page_pool_refill_alloc_cache(struct 
page_pool *pool)
if (unlikely(!page))
break;
 
-   if (likely(page_to_nid(page) == pref_nid)) {
+   if (likely(page_pool_page_is_pref_nid(page, pref_nid))) {
pool->alloc.cache[pool->alloc.count++] = page;
} else {
/* NUMA mismatch;
@@ -362,7 +362,15 @@ static void page_pool_dma_sync_for_device(struct page_poo

[RFC PATCH v3 08/12] net: support non paged skb frags

2023-11-05 Thread Mina Almasry
Make skb_frag_page() fail in the case where the frag is not backed
by a page, and fix its relevent callers to handle this case.

Correctly handle skb_frag refcounting in the page_pool_iovs case.

Signed-off-by: Mina Almasry 

---
 include/linux/skbuff.h | 42 +++---
 net/core/gro.c |  2 +-
 net/core/skbuff.c  |  3 +++
 net/ipv4/tcp.c | 10 +-
 4 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 97bfef071255..1fae276c1353 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -37,6 +37,8 @@
 #endif
 #include 
 #include 
+#include 
+#include 
 
 /**
  * DOC: skb checksums
@@ -3402,15 +3404,38 @@ static inline void skb_frag_off_copy(skb_frag_t *fragto,
fragto->bv_offset = fragfrom->bv_offset;
 }
 
+/* Returns true if the skb_frag contains a page_pool_iov. */
+static inline bool skb_frag_is_page_pool_iov(const skb_frag_t *frag)
+{
+   return page_is_page_pool_iov(frag->bv_page);
+}
+
 /**
  * skb_frag_page - retrieve the page referred to by a paged fragment
  * @frag: the paged fragment
  *
- * Returns the &struct page associated with @frag.
+ * Returns the &struct page associated with @frag. Returns NULL if this frag
+ * has no associated page.
  */
 static inline struct page *skb_frag_page(const skb_frag_t *frag)
 {
-   return frag->bv_page;
+   if (!page_is_page_pool_iov(frag->bv_page))
+   return frag->bv_page;
+
+   return NULL;
+}
+
+/**
+ * skb_frag_page_pool_iov - retrieve the page_pool_iov referred to by fragment
+ * @frag: the fragment
+ *
+ * Returns the &struct page_pool_iov associated with @frag. Returns NULL if 
this
+ * frag has no associated page_pool_iov.
+ */
+static inline struct page_pool_iov *
+skb_frag_page_pool_iov(const skb_frag_t *frag)
+{
+   return page_to_page_pool_iov(frag->bv_page);
 }
 
 /**
@@ -3421,7 +3446,7 @@ static inline struct page *skb_frag_page(const skb_frag_t 
*frag)
  */
 static inline void __skb_frag_ref(skb_frag_t *frag)
 {
-   get_page(skb_frag_page(frag));
+   page_pool_page_get_many(frag->bv_page, 1);
 }
 
 /**
@@ -3441,13 +3466,13 @@ bool napi_pp_put_page(struct page *page, bool 
napi_safe);
 static inline void
 napi_frag_unref(skb_frag_t *frag, bool recycle, bool napi_safe)
 {
-   struct page *page = skb_frag_page(frag);
-
 #ifdef CONFIG_PAGE_POOL
-   if (recycle && napi_pp_put_page(page, napi_safe))
+   if (recycle && napi_pp_put_page(frag->bv_page, napi_safe))
return;
+   page_pool_page_put_many(frag->bv_page, 1);
+#else
+   put_page(skb_frag_page(frag));
 #endif
-   put_page(page);
 }
 
 /**
@@ -3487,6 +3512,9 @@ static inline void skb_frag_unref(struct sk_buff *skb, 
int f)
  */
 static inline void *skb_frag_address(const skb_frag_t *frag)
 {
+   if (!skb_frag_page(frag))
+   return NULL;
+
return page_address(skb_frag_page(frag)) + skb_frag_off(frag);
 }
 
diff --git a/net/core/gro.c b/net/core/gro.c
index 0759277dc14e..42d7f6755f32 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -376,7 +376,7 @@ static inline void skb_gro_reset_offset(struct sk_buff 
*skb, u32 nhoff)
NAPI_GRO_CB(skb)->frag0 = NULL;
NAPI_GRO_CB(skb)->frag0_len = 0;
 
-   if (!skb_headlen(skb) && pinfo->nr_frags &&
+   if (!skb_headlen(skb) && pinfo->nr_frags && skb_frag_page(frag0) &&
!PageHighMem(skb_frag_page(frag0)) &&
(!NET_IP_ALIGN || !((skb_frag_off(frag0) + nhoff) & 3))) {
NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c52ddd6891d9..13eca4fd25e1 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2994,6 +2994,9 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct 
pipe_inode_info *pipe,
for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) {
const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
 
+   if (WARN_ON_ONCE(!skb_frag_page(f)))
+   return false;
+
if (__splice_segment(skb_frag_page(f),
 skb_frag_off(f), skb_frag_size(f),
 offset, len, spd, false, sk, pipe))
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a86d8200a1e8..23b29dc49271 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2155,6 +2155,9 @@ static int tcp_zerocopy_receive(struct sock *sk,
break;
}
page = skb_frag_page(frags);
+   if (WARN_ON_ONCE(!page))
+   break;
+
prefetchw(page);
pages[pages_to_map++] = page;
length += PAGE_SIZE;
@@ -4411,7 +4414,12 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
for (i = 0; i < shi->nr_frags; ++i) {
const skb_frag_t *f = &shi->frags[i];
unsigned int offset = skb_

[RFC PATCH v3 09/12] net: add support for skbs with unreadable frags

2023-11-05 Thread Mina Almasry
For device memory TCP, we expect the skb headers to be available in host
memory for access, and we expect the skb frags to be in device memory
and unaccessible to the host. We expect there to be no mixing and
matching of device memory frags (unaccessible) with host memory frags
(accessible) in the same skb.

Add a skb->devmem flag which indicates whether the frags in this skb
are device memory frags or not.

__skb_fill_page_desc() now checks frags added to skbs for page_pool_iovs,
and marks the skb as skb->devmem accordingly.

Add checks through the network stack to avoid accessing the frags of
devmem skbs and avoid coalescing devmem skbs with non devmem skbs.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---
 include/linux/skbuff.h | 14 +++-
 include/net/tcp.h  |  5 +--
 net/core/datagram.c|  6 
 net/core/gro.c |  5 ++-
 net/core/skbuff.c  | 77 --
 net/ipv4/tcp.c |  6 
 net/ipv4/tcp_input.c   | 13 +--
 net/ipv4/tcp_output.c  |  5 ++-
 net/packet/af_packet.c |  4 +--
 9 files changed, 115 insertions(+), 20 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1fae276c1353..8fb468ff8115 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -805,6 +805,8 @@ typedef unsigned char *sk_buff_data_t;
  * @csum_level: indicates the number of consecutive checksums found in
  * the packet minus one that have been verified as
  * CHECKSUM_UNNECESSARY (max 3)
+ * @devmem: indicates that all the fragments in this skb are backed by
+ * device memory.
  * @dst_pending_confirm: need to confirm neighbour
  * @decrypted: Decrypted SKB
  * @slow_gro: state present at GRO time, slower prepare step required
@@ -991,7 +993,7 @@ struct sk_buff {
 #if IS_ENABLED(CONFIG_IP_SCTP)
__u8csum_not_inet:1;
 #endif
-
+   __u8devmem:1;
 #if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS)
__u16   tc_index;   /* traffic control index */
 #endif
@@ -1766,6 +1768,12 @@ static inline void skb_zcopy_downgrade_managed(struct 
sk_buff *skb)
__skb_zcopy_downgrade_managed(skb);
 }
 
+/* Return true if frags in this skb are not readable by the host. */
+static inline bool skb_frags_not_readable(const struct sk_buff *skb)
+{
+   return skb->devmem;
+}
+
 static inline void skb_mark_not_on_list(struct sk_buff *skb)
 {
skb->next = NULL;
@@ -2468,6 +2476,10 @@ static inline void __skb_fill_page_desc(struct sk_buff 
*skb, int i,
struct page *page, int off, int size)
 {
__skb_fill_page_desc_noacc(skb_shinfo(skb), i, page, off, size);
+   if (page_is_page_pool_iov(page)) {
+   skb->devmem = true;
+   return;
+   }
 
/* Propagate page pfmemalloc to the skb if we can. The problem is
 * that not all callers have unique ownership of the page but rely
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 39b731c900dd..1ae62d1e284b 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1012,7 +1012,7 @@ static inline int tcp_skb_mss(const struct sk_buff *skb)
 
 static inline bool tcp_skb_can_collapse_to(const struct sk_buff *skb)
 {
-   return likely(!TCP_SKB_CB(skb)->eor);
+   return likely(!TCP_SKB_CB(skb)->eor && !skb_frags_not_readable(skb));
 }
 
 static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
@@ -1020,7 +1020,8 @@ static inline bool tcp_skb_can_collapse(const struct 
sk_buff *to,
 {
return likely(tcp_skb_can_collapse_to(to) &&
  mptcp_skb_can_collapse(to, from) &&
- skb_pure_zcopy_same(to, from));
+ skb_pure_zcopy_same(to, from) &&
+ skb_frags_not_readable(to) == 
skb_frags_not_readable(from));
 }
 
 /* Events passed to congestion control interface */
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 176eb5834746..cdd4fb129968 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -425,6 +425,9 @@ static int __skb_datagram_iter(const struct sk_buff *skb, 
int offset,
return 0;
}
 
+   if (skb_frags_not_readable(skb))
+   goto short_copy;
+
/* Copy paged appendix. Hmm... why does this look so complicated? */
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
int end;
@@ -616,6 +619,9 @@ int __zerocopy_sg_from_iter(struct msghdr *msg, struct sock 
*sk,
 {
int frag;
 
+   if (skb_frags_not_readable(skb))
+   return -EFAULT;
+
if (msg && msg->msg_ubuf && msg->sg_from_iter)
return msg->sg_from_iter(sk, skb, from, length);
 
diff --git a/net/core/gro.c b/net/core/gro.c
index 42d7f6755f32..56046d65386a 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -390,6 +390,9 @

[RFC PATCH v3 10/12] tcp: RX path for devmem TCP

2023-11-05 Thread Mina Almasry
In tcp_recvmsg_locked(), detect if the skb being received by the user
is a devmem skb. In this case - if the user provided the MSG_SOCK_DEVMEM
flag - pass it to tcp_recvmsg_devmem() for custom handling.

tcp_recvmsg_devmem() copies any data in the skb header to the linear
buffer, and returns a cmsg to the user indicating the number of bytes
returned in the linear buffer.

tcp_recvmsg_devmem() then loops over the unaccessible devmem skb frags,
and returns to the user a cmsg_devmem indicating the location of the
data in the dmabuf device memory. cmsg_devmem contains this information:

1. the offset into the dmabuf where the payload starts. 'frag_offset'.
2. the size of the frag. 'frag_size'.
3. an opaque token 'frag_token' to return to the kernel when the buffer
is to be released.

The pages awaiting freeing are stored in the newly added
sk->sk_user_pages, and each page passed to userspace is get_page()'d.
This reference is dropped once the userspace indicates that it is
done reading this page.  All pages are released when the socket is
destroyed.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---

RFC v3:
- Fixed issue with put_cmsg() failing silently.

---
 include/linux/socket.h|   1 +
 include/net/page_pool/helpers.h   |   9 ++
 include/net/sock.h|   2 +
 include/uapi/asm-generic/socket.h |   5 +
 include/uapi/linux/uio.h  |   6 +
 net/ipv4/tcp.c| 189 +-
 net/ipv4/tcp_ipv4.c   |   7 ++
 7 files changed, 214 insertions(+), 5 deletions(-)

diff --git a/include/linux/socket.h b/include/linux/socket.h
index cfcb7e2c3813..fe2b9e2081bb 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -326,6 +326,7 @@ struct ucred {
  * plain text and require encryption
  */
 
+#define MSG_SOCK_DEVMEM 0x200  /* Receive devmem skbs as cmsg */
 #define MSG_ZEROCOPY   0x400   /* Use user data in kernel path */
 #define MSG_SPLICE_PAGES 0x800 /* Splice the pages from the iterator 
in sendmsg() */
 #define MSG_FASTOPEN   0x2000  /* Send data in TCP SYN */
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 08f1a2cc70d2..95f4d579cbc4 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -106,6 +106,15 @@ page_pool_iov_dma_addr(const struct page_pool_iov *ppiov)
   ((dma_addr_t)page_pool_iov_idx(ppiov) << PAGE_SHIFT);
 }
 
+static inline unsigned long
+page_pool_iov_virtual_addr(const struct page_pool_iov *ppiov)
+{
+   struct dmabuf_genpool_chunk_owner *owner = page_pool_iov_owner(ppiov);
+
+   return owner->base_virtual +
+  ((unsigned long)page_pool_iov_idx(ppiov) << PAGE_SHIFT);
+}
+
 static inline struct netdev_dmabuf_binding *
 page_pool_iov_binding(const struct page_pool_iov *ppiov)
 {
diff --git a/include/net/sock.h b/include/net/sock.h
index 242590308d64..986d9da6e062 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -353,6 +353,7 @@ struct sk_filter;
   *@sk_txtime_unused: unused txtime flags
   *@ns_tracker: tracker for netns reference
   *@sk_bind2_node: bind node in the bhash2 table
+  *@sk_user_pages: xarray of pages the user is holding a reference on.
   */
 struct sock {
/*
@@ -545,6 +546,7 @@ struct sock {
struct rcu_head sk_rcu;
netns_tracker   ns_tracker;
struct hlist_node   sk_bind2_node;
+   struct xarray   sk_user_pages;
 };
 
 enum sk_pacing {
diff --git a/include/uapi/asm-generic/socket.h 
b/include/uapi/asm-generic/socket.h
index 8ce8a39a1e5f..aacb97f16b78 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -135,6 +135,11 @@
 #define SO_PASSPIDFD   76
 #define SO_PEERPIDFD   77
 
+#define SO_DEVMEM_HEADER   98
+#define SCM_DEVMEM_HEADER  SO_DEVMEM_HEADER
+#define SO_DEVMEM_OFFSET   99
+#define SCM_DEVMEM_OFFSET  SO_DEVMEM_OFFSET
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/include/uapi/linux/uio.h b/include/uapi/linux/uio.h
index 059b1a9147f4..ae94763b1963 100644
--- a/include/uapi/linux/uio.h
+++ b/include/uapi/linux/uio.h
@@ -20,6 +20,12 @@ struct iovec
__kernel_size_t iov_len; /* Must be size_t (1003.1g) */
 };
 
+struct cmsg_devmem {
+   __u64 frag_offset;
+   __u32 frag_size;
+   __u32 frag_token;
+};
+
 /*
  * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1)
  */
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5c6fed52ed0e..fd7f6d7e7671 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -461,6 +461,7 @@ void tcp_init_sock(struct sock *sk)
 
set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
sk_sockets_allocated_inc(sk);
+   xa_init_flags(&sk->sk_user_pages, XA_FLAGS_

[RFC PATCH v3 12/12] selftests: add ncdevmem, netcat for devmem TCP

2023-11-05 Thread Mina Almasry
ncdevmem is a devmem TCP netcat. It works similarly to netcat, but it
sends and receives data using the devmem TCP APIs. It uses udmabuf as
the dmabuf provider. It is compatible with a regular netcat running on
a peer, or a ncdevmem running on a peer.

In addition to normal netcat support, ncdevmem has a validation mode,
where it sends a specific pattern and validates this pattern on the
receiver side to ensure data integrity.

Suggested-by: Stanislav Fomichev 
Signed-off-by: Mina Almasry 


---

RFC v2:
- General cleanups (Willem).

---
 tools/testing/selftests/net/.gitignore |   1 +
 tools/testing/selftests/net/Makefile   |   5 +
 tools/testing/selftests/net/ncdevmem.c | 546 +
 3 files changed, 552 insertions(+)
 create mode 100644 tools/testing/selftests/net/ncdevmem.c

diff --git a/tools/testing/selftests/net/.gitignore 
b/tools/testing/selftests/net/.gitignore
index 2f9d378edec3..b644dbae58b7 100644
--- a/tools/testing/selftests/net/.gitignore
+++ b/tools/testing/selftests/net/.gitignore
@@ -17,6 +17,7 @@ ipv6_flowlabel
 ipv6_flowlabel_mgr
 log.txt
 msg_zerocopy
+ncdevmem
 nettest
 psock_fanout
 psock_snd
diff --git a/tools/testing/selftests/net/Makefile 
b/tools/testing/selftests/net/Makefile
index b9804ceb9494..6c6e53c70e99 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -5,6 +5,10 @@ CFLAGS =  -Wall -Wl,--no-as-needed -O2 -g
 CFLAGS += -I../../../../usr/include/ $(KHDR_INCLUDES)
 # Additional include paths needed by kselftest.h
 CFLAGS += -I../
+CFLAGS += -I../../../net/ynl/generated/
+CFLAGS += -I../../../net/ynl/lib/
+
+LDLIBS += ../../../net/ynl/lib/ynl.a ../../../net/ynl/generated/protos.a
 
 TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh \
  rtnetlink.sh xfrm_policy.sh test_blackhole_dev.sh
@@ -91,6 +95,7 @@ TEST_PROGS += test_bridge_neigh_suppress.sh
 TEST_PROGS += test_vxlan_nolocalbypass.sh
 TEST_PROGS += test_bridge_backup_port.sh
 TEST_PROGS += fdb_flush.sh
+TEST_GEN_FILES += ncdevmem
 
 TEST_FILES := settings
 
diff --git a/tools/testing/selftests/net/ncdevmem.c 
b/tools/testing/selftests/net/ncdevmem.c
new file mode 100644
index ..78bc3ad767ca
--- /dev/null
+++ b/tools/testing/selftests/net/ncdevmem.c
@@ -0,0 +1,546 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#define __EXPORTED_HEADERS__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#define __iovec_defined
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "netdev-user.h"
+#include 
+
+#define PAGE_SHIFT 12
+#define TEST_PREFIX "ncdevmem"
+#define NUM_PAGES 16000
+
+#ifndef MSG_SOCK_DEVMEM
+#define MSG_SOCK_DEVMEM 0x200
+#endif
+
+/*
+ * tcpdevmem netcat. Works similarly to netcat but does device memory TCP
+ * instead of regular TCP. Uses udmabuf to mock a dmabuf provider.
+ *
+ * Usage:
+ *
+ * * Without validation:
+ *
+ * On server:
+ * ncdevmem -s  -c  -f eth1 -n :06:00.0 -l \
+ * -p 5201
+ *
+ * On client:
+ * ncdevmem -s  -c  -f eth1 -n :06:00.0 -p 5201
+ *
+ * * With Validation:
+ * On server:
+ * ncdevmem -s  -c  -l -f eth1 -n :06:00.0 \
+ * -p 5202 -v 1
+ *
+ * On client:
+ * ncdevmem -s  -c  -f eth1 -n :06:00.0 -p 5202 \
+ * -v 10
+ *
+ * Note this is compatible with regular netcat. i.e. the sender or receiver can
+ * be replaced with regular netcat to test the RX or TX path in isolation.
+ */
+
+static char *server_ip = "192.168.1.4";
+static char *client_ip = "192.168.1.2";
+static char *port = "5201";
+static size_t do_validation;
+static int queue_num = 15;
+static char *ifname = "eth1";
+static char *nic_pci_addr = ":06:00.0";
+static unsigned int iterations;
+
+void print_bytes(void *ptr, size_t size)
+{
+   unsigned char *p = ptr;
+   int i;
+
+   for (i = 0; i < size; i++) {
+   printf("%02hhX ", p[i]);
+   }
+   printf("\n");
+}
+
+void print_nonzero_bytes(void *ptr, size_t size)
+{
+   unsigned char *p = ptr;
+   unsigned int i;
+
+   for (i = 0; i < size; i++)
+   putchar(p[i]);
+   printf("\n");
+}
+
+void validate_buffer(void *line, size_t size)
+{
+   static unsigned char seed = 1;
+   unsigned char *ptr = line;
+   int errors = 0;
+   size_t i;
+
+   for (i = 0; i < size; i++) {
+   if (ptr[i] != seed) {
+   fprintf(stderr,
+   "Failed validation: expected=%u, actual=%u, 
index=%lu\n",
+   seed, ptr[i], i);
+   errors++;
+   if (errors > 20)
+   exit(1);
+   }
+   seed++;
+   if (seed == do_validation)
+   see

[RFC PATCH v3 11/12] net: add SO_DEVMEM_DONTNEED setsockopt to release RX pages

2023-11-05 Thread Mina Almasry
Add an interface for the user to notify the kernel that it is done
reading the NET_RX dmabuf pages returned as cmsg. The kernel will
drop the reference on the NET_RX pages to make them available for
re-use.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---
 include/uapi/asm-generic/socket.h |  1 +
 include/uapi/linux/uio.h  |  4 
 net/core/sock.c   | 36 +++
 3 files changed, 41 insertions(+)

diff --git a/include/uapi/asm-generic/socket.h 
b/include/uapi/asm-generic/socket.h
index aacb97f16b78..eb93b43394d4 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -135,6 +135,7 @@
 #define SO_PASSPIDFD   76
 #define SO_PEERPIDFD   77
 
+#define SO_DEVMEM_DONTNEED 97
 #define SO_DEVMEM_HEADER   98
 #define SCM_DEVMEM_HEADER  SO_DEVMEM_HEADER
 #define SO_DEVMEM_OFFSET   99
diff --git a/include/uapi/linux/uio.h b/include/uapi/linux/uio.h
index ae94763b1963..71314bf41590 100644
--- a/include/uapi/linux/uio.h
+++ b/include/uapi/linux/uio.h
@@ -26,6 +26,10 @@ struct cmsg_devmem {
__u32 frag_token;
 };
 
+struct devmemtoken {
+   __u32 token_start;
+   __u32 token_count;
+};
 /*
  * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1)
  */
diff --git a/net/core/sock.c b/net/core/sock.c
index 1d28e3e87970..4ddc6b11d915 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1051,6 +1051,39 @@ static int sock_reserve_memory(struct sock *sk, int 
bytes)
return 0;
 }
 
+static noinline_for_stack int
+sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen)
+{
+   struct devmemtoken tokens[128];
+   unsigned int num_tokens, i, j;
+   int ret;
+
+   if (sk->sk_type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP)
+   return -EBADF;
+
+   if (optlen % sizeof(struct devmemtoken) || optlen > sizeof(tokens))
+   return -EINVAL;
+
+   num_tokens = optlen / sizeof(struct devmemtoken);
+   if (copy_from_sockptr(tokens, optval, optlen))
+   return -EFAULT;
+
+   ret = 0;
+   for (i = 0; i < num_tokens; i++) {
+   for (j = 0; j < tokens[i].token_count; j++) {
+   struct page *page = xa_erase(&sk->sk_user_pages,
+tokens[i].token_start + j);
+
+   if (page) {
+   page_pool_page_put_many(page, 1);
+   ret++;
+   }
+   }
+   }
+
+   return ret;
+}
+
 void sockopt_lock_sock(struct sock *sk)
 {
/* When current->bpf_ctx is set, the setsockopt is called from
@@ -1538,6 +1571,9 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
break;
}
 
+   case SO_DEVMEM_DONTNEED:
+   ret = sock_devmem_dontneed(sk, optval, optlen);
+   break;
default:
ret = -ENOPROTOOPT;
break;
-- 
2.42.0.869.gea05f2083d-goog



Re: [PATCH v2 07/11] drm/mediatek: Add secure layer config support for ovl

2023-11-05 Thread 林睿祥


Re: [PATCH v2 09/11] drm/mediatek: Add secure flow support to mediatek-drm

2023-11-05 Thread 林睿祥


Re: [PATCH v2 09/11] drm/mediatek: Add secure flow support to mediatek-drm

2023-11-05 Thread 胡俊光


Re: [PATCH v1] docs: gpu: rfc: i915_scheduler.rst remove unused directives for namespacing

2023-11-05 Thread Bagas Sanjaya
On Sat, Nov 04, 2023 at 09:47:08AM -0400, Hunter Chasens wrote:
> diff --git a/Documentation/gpu/rfc/i915_scheduler.rst 
> b/Documentation/gpu/rfc/i915_scheduler.rst
> index c237ebc024cd..23ba7006929b 100644
> --- a/Documentation/gpu/rfc/i915_scheduler.rst
> +++ b/Documentation/gpu/rfc/i915_scheduler.rst
> @@ -135,13 +135,9 @@ Add I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT and
>  drm_i915_context_engines_parallel_submit to the uAPI to implement this
>  extension.
>  
> -.. c:namespace-push:: rfc
> -
>  .. kernel-doc:: include/uapi/drm/i915_drm.h
>  :functions: i915_context_engines_parallel_submit
>  
> -.. c:namespace-pop::
> -
>  Extend execbuf2 IOCTL to support submitting N BBs in a single IOCTL
>  ---
>  Contexts that have been configured with the 'set_parallel' extension can only

The warnings go away, thanks!

Fixes: f6757dfcfde7 ("drm/doc: fix duplicate declaration warning")
Reviewed-by: Bagas Sanjaya 

-- 
An old man doll... just what I always wanted! - Clara


signature.asc
Description: PGP signature


Re: [PATCH v1] drm: amd: Resolve Sphinx unexpected indentation warning

2023-11-05 Thread Bagas Sanjaya
On Sun, Nov 05, 2023 at 04:00:44PM -0500, Hunter Chasens wrote:
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> index 517b9fb4624c..703fe2542258 100644
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
> @@ -990,11 +990,14 @@ static ssize_t amdgpu_get_pp_features(struct device 
> *dev,
>   * the power state and the clock information for those levels. If deep sleep 
> is
>   * applied to a clock, the level will be denoted by a special level 'S:'
>   * E.g.,
> - *   S: 19Mhz *
> - *   0: 615Mhz
> - *   1: 800Mhz
> - *   2: 888Mhz
> - *   3: 1000Mhz
> + *
> + * ::
> + *
> + *  S: 19Mhz *
> + *  0: 615Mhz
> + *  1: 800Mhz
> + *  2: 888Mhz
> + *  3: 1000Mhz
>   *
>   *
>   * To manually adjust these states, first select manual using

LGTM, thanks!

Fixes: 615585d09b33 ("Documentation/amdgpu: Modify pp_dpm_*clk details")
Reviewed-by: Bagas Sanjaya 

-- 
An old man doll... just what I always wanted! - Clara


signature.asc
Description: PGP signature


Re: [PATCH v1] drm: amd: Resolve Sphinx unexpected indentation warning

2023-11-05 Thread Randy Dunlap



On 11/5/23 21:15, Bagas Sanjaya wrote:
> On Sun, Nov 05, 2023 at 04:00:44PM -0500, Hunter Chasens wrote:
>> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c 
>> b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>> index 517b9fb4624c..703fe2542258 100644
>> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c
>> @@ -990,11 +990,14 @@ static ssize_t amdgpu_get_pp_features(struct device 
>> *dev,
>>   * the power state and the clock information for those levels. If deep 
>> sleep is
>>   * applied to a clock, the level will be denoted by a special level 'S:'
>>   * E.g.,
>> - *  S: 19Mhz *
>> - *  0: 615Mhz
>> - *  1: 800Mhz
>> - *  2: 888Mhz
>> - *  3: 1000Mhz
>> + *
>> + * ::
>> + *
>> + *  S: 19Mhz *
>> + *  0: 615Mhz
>> + *  1: 800Mhz
>> + *  2: 888Mhz
>> + *  3: 1000Mhz
>>   *
>>   *
>>   * To manually adjust these states, first select manual using
> 
> LGTM, thanks!
> 
> Fixes: 615585d09b33 ("Documentation/amdgpu: Modify pp_dpm_*clk details")
> Reviewed-by: Bagas Sanjaya 
> 

but can it be done without being so obvious about using Sphinx (or is it ReST?)
in source files?

e.g.: (not tested)

 * E.g.:
 * *S: 19Mhz *
 * *0: 615Mhz
 * *1: 800Mhz
 * *2: 888Mhz
 * *3: 1000Mhz

This is what I have seen done in quite a few source files.

Oh well, lots of files are already infected, so WTH. :(

-- 
~Randy


Re: [PATCH v2 09/11] drm/mediatek: Add secure flow support to mediatek-drm

2023-11-05 Thread 林睿祥


Re: [PATCH v2 1/1] drm/mediatek: Fix errors when reporting rotation capability

2023-11-05 Thread 胡俊光


Re: [PATCH 8/9] dt-bindings: reserved-memory: MediaTek: Add reserved memory for SVP

2023-11-05 Thread 吴勇
On Wed, 2023-11-01 at 11:20 +0530, Jaskaran Singh wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  On 10/20/2023 3:20 PM, Yong Wu (吴勇) wrote:
> > On Thu, 2023-10-19 at 10:16 +0530, Vijayanand Jitta wrote:
> >>   
> >> Instead of having a vendor specific binding for cma area, How
> about
> >> retrieving
> >>
> > 
> https://lore.kernel.org/lkml/1594948208-4739-1-git-send-email-hayashi.kunih...@socionext.com/
> >>  ?
> >> dma_heap_add_cma can just associate cma region and create a heap.
> So,
> >> we can reuse cma heap
> >> code for allocation instead of replicating that code here.
> >>
> > 
> > Thanks for the reference. I guess we can't use it. There are two
> > reasons:
> >   
> > a) The secure heap driver is a pure software driver and we have no
> > device for it, therefore we cannot call dma_heap_add_cma.
> >   
> 
> Hi Yong,
> 
> We're considering using struct cma as the function argument to
> dma_heap_add_cma() rather than struct device. Would this help
> resolve the problem of usage with dma_heap_add_cma()?

Yes. If we use "struct cma", I guess it works.

> 
> > b) The CMA area here is dynamic for SVP. Normally this CMA can be
> used
> > in the kernel. In the SVP case we use cma_alloc to get it and pass
> the
> > entire CMA physical start address and size into TEE to protect the
> CMA
> > region. The original CMA heap cannot help with the TEE part.
> >
> 
> Referring the conversation at
> 
https://lore.kernel.org/lkml/7a2995de23c24ef22c071c6976c02b97e9b50126.ca...@mediatek.com/
> ;
> 
> since we're considering abstracting secure mem ops, would it make
> sense
> to use the default CMA heap ops (cma_heap_ops), allocate buffers from
> it
> and secure each allocated buffer?

Then it looks you also need tee operation like tee_client_open_session
and tee_client_invoke_func, right?

It seems we also need change a bit for "cma_heap_allocate" to allow cma
support operations from secure heap.

I will send a v2 to move the discussion forward. The v2 is based on our
case, It won't include the cma part.

> 
> Thanks,
> Jaskaran.
> 
> > Thanks.
> > 
> >> Thanks,
> >> Vijay
> >>
> >>
> >>
> 


[PATCH v2 3/3] selftests/dma-buf/udmabuf: Add tests to verify data after page migration

2023-11-05 Thread Vivek Kasireddy
Since the memfd pages associated with a udmabuf may be migrated
as part of udmabuf create, we need to verify the data coherency
after successful migration. The new tests added in this patch try
to do just that using 4k sized pages and also 2 MB sized huge
pages for the memfd.

Successful completion of the tests would mean that there is no
disconnect between the memfd pages and the ones associated with
a udmabuf. And, these tests can also be augmented in the future
to test newer udmabuf features (such as handling memfd hole punch).

Cc: Shuah Khan 
Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Based-on-patch-by: Mike Kravetz 
Signed-off-by: Vivek Kasireddy 
---
 .../selftests/drivers/dma-buf/udmabuf.c   | 151 +-
 1 file changed, 147 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c 
b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
index c812080e304e..d76c813fe652 100644
--- a/tools/testing/selftests/drivers/dma-buf/udmabuf.c
+++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c
@@ -9,26 +9,132 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #define TEST_PREFIX"drivers/dma-buf/udmabuf"
 #define NUM_PAGES   4
+#define NUM_ENTRIES 4
+#define MEMFD_SIZE  1024 /* in pages */
 
-static int memfd_create(const char *name, unsigned int flags)
+static unsigned int page_size;
+
+static int create_memfd_with_seals(off64_t size, bool hpage)
+{
+   int memfd, ret;
+   unsigned int flags = MFD_ALLOW_SEALING;
+
+   if (hpage)
+   flags |= MFD_HUGETLB;
+
+   memfd = memfd_create("udmabuf-test", flags);
+   if (memfd < 0) {
+   printf("%s: [skip,no-memfd]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
+   if (ret < 0) {
+   printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
+   exit(77);
+   }
+
+   ret = ftruncate(memfd, size);
+   if (ret == -1) {
+   printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return memfd;
+}
+
+static int create_udmabuf_list(int devfd, int memfd, off64_t memfd_size)
+{
+   struct udmabuf_create_list *list;
+   int ubuf_fd, i;
+
+   list = malloc(sizeof(struct udmabuf_create_list) +
+ sizeof(struct udmabuf_create_item) * NUM_ENTRIES);
+   if (!list) {
+   printf("%s: [FAIL, udmabuf-malloc]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   for (i = 0; i < NUM_ENTRIES; i++) {
+   list->list[i].memfd  = memfd;
+   list->list[i].offset = i * (memfd_size / NUM_ENTRIES);
+   list->list[i].size   = getpagesize() * NUM_PAGES;
+   }
+
+   list->count = NUM_ENTRIES;
+   list->flags = UDMABUF_FLAGS_CLOEXEC;
+   ubuf_fd = ioctl(devfd, UDMABUF_CREATE_LIST, list);
+   free(list);
+   if (ubuf_fd < 0) {
+   printf("%s: [FAIL, udmabuf-create]\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return ubuf_fd;
+}
+
+static void write_to_memfd(void *addr, off64_t size, char chr)
+{
+   int i;
+
+   for (i = 0; i < size / page_size; i++) {
+   *((char *)addr + (i * page_size)) = chr;
+   }
+}
+
+static void *mmap_fd(int fd, off64_t size)
 {
-   return syscall(__NR_memfd_create, name, flags);
+   void *addr;
+
+   addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+   if (addr == MAP_FAILED) {
+   printf("%s: ubuf_fd mmap fail\n", TEST_PREFIX);
+   exit(1);
+   }
+
+   return addr;
+}
+
+static int compare_chunks(void *addr1, void *addr2, off64_t memfd_size)
+{
+   off64_t off;
+   int i = 0, j, k = 0, ret = 0;
+   char char1, char2;
+
+   while (i < NUM_ENTRIES) {
+   off = i * (memfd_size / NUM_ENTRIES);
+   for (j = 0; j < NUM_PAGES; j++, k++) {
+   char1 = *((char *)addr1 + off + (j * getpagesize()));
+   char2 = *((char *)addr2 + (k * getpagesize()));
+   if (char1 != char2) {
+   ret = -1;
+   goto err;
+   }
+   }
+   i++;
+   }
+err:
+   munmap(addr1, memfd_size);
+   munmap(addr2, NUM_ENTRIES * NUM_PAGES * getpagesize());
+   return ret;
 }
 
 int main(int argc, char *argv[])
 {
struct udmabuf_create create;
int devfd, memfd, buf, ret;
-   off_t size;
-   void *mem;
+   off64_t size;
+   void *addr1, *addr2;
 
devfd = open("/dev/udmabuf", O_RDWR);
if (devfd < 0) {
@@ -90,6 +196,9 @@ int main(int argc, char *argv[])
}
 
/* should work */
+   

[PATCH v2 0/3] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages (v2)

2023-11-05 Thread Vivek Kasireddy
The first patch introduces pin_user_pages_fd() API and the second
patch shows how the udmabuf driver can use it to longterm-pin the
the pages. The last patch adds two new udmabuf selftests to verify
data coherency after page migration.

v2:
- Updated the first patch to include review feedback from David and
  Jason. The main change in this series is the allocation of page
  in the case of hugetlbfs if it is not found in the page cache.

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 

Vivek Kasireddy (3):
  mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file
pages (v2)
  udmabuf: Pin the pages using pin_user_pages_fd() API (v2)
  selftests/dma-buf/udmabuf: Add tests to verify data after page
migration

 drivers/dma-buf/udmabuf.c |  81 +++---
 include/linux/mm.h|   2 +
 mm/gup.c  |  99 
 .../selftests/drivers/dma-buf/udmabuf.c   | 151 +-
 4 files changed, 308 insertions(+), 25 deletions(-)

-- 
2.39.2



[PATCH v2 1/3] mm/gup: Introduce pin_user_pages_fd() for pinning shmem/hugetlbfs file pages (v2)

2023-11-05 Thread Vivek Kasireddy
For drivers that would like to longterm-pin the pages associated
with a file, the pin_user_pages_fd() API provides an option to
not only pin the pages via FOLL_PIN but also to check and migrate
them if they reside in movable zone or CMA block. This API
currently works with files that belong to either shmem or hugetlbfs.
Files belonging to other filesystems are rejected for now.

The pages need to be located first before pinning them via FOLL_PIN.
If they are found in the page cache, they can be immediately pinned.
Otherwise, they need to be allocated using the filesystem specific
APIs and then pinned.

v2:
- Drop gup_flags and improve comments and commit message (David)
- Allocate a page if we cannot find in page cache for the hugetlbfs
  case as well (David)
- Don't unpin pages if there is a migration related failure (David)
- Drop the unnecessary nr_pages <= 0 check (Jason)
- Have the caller of the API pass in file * instead of fd (Jason)

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Suggested-by: Jason Gunthorpe 
Signed-off-by: Vivek Kasireddy 
---
 include/linux/mm.h |  2 +
 mm/gup.c   | 99 ++
 2 files changed, 101 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index bf5d0b1b16f4..f6cc17b14653 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2457,6 +2457,8 @@ long get_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
 long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
struct page **pages, unsigned int gup_flags);
+long pin_user_pages_fd(struct file *file, pgoff_t start,
+  unsigned long nr_pages, struct page **pages);
 
 int get_user_pages_fast(unsigned long start, int nr_pages,
unsigned int gup_flags, struct page **pages);
diff --git a/mm/gup.c b/mm/gup.c
index 2f8a2d89fde1..d30b9dfebbb6 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3400,3 +3400,102 @@ long pin_user_pages_unlocked(unsigned long start, 
unsigned long nr_pages,
 &locked, gup_flags);
 }
 EXPORT_SYMBOL(pin_user_pages_unlocked);
+
+static struct page *alloc_file_page(struct file *file, pgoff_t idx)
+{
+   struct page *page = ERR_PTR(-ENOMEM);
+   struct folio *folio;
+   int err;
+
+   if (shmem_file(file))
+   return shmem_read_mapping_page(file->f_mapping, idx);
+
+   folio = alloc_hugetlb_folio_nodemask(hstate_file(file),
+NUMA_NO_NODE,
+NULL,
+GFP_USER);
+   if (folio && folio_try_get(folio)) {
+   page = &folio->page;
+   err = hugetlb_add_to_page_cache(folio, file->f_mapping, idx);
+   if (err) {
+   folio_put(folio);
+   free_huge_folio(folio);
+   page = ERR_PTR(err);
+   }
+   }
+
+   return page;
+}
+
+/**
+ * pin_user_pages_fd() - pin user pages associated with a file
+ * @file:   the file whose pages are to be pinned
+ * @start:  starting file offset
+ * @nr_pages:   number of pages from start to pin
+ * @pages:  array that receives pointers to the pages pinned.
+ *  Should be at-least nr_pages long.
+ *
+ * Attempt to pin pages associated with a file that belongs to either shmem
+ * or hugetlbfs. The pages are either found in the page cache or allocated
+ * if necessary. Once the pages are located, they are all pinned via FOLL_PIN.
+ * And, these pinned pages need to be released using unpin_user_pages() or
+ * unpin_user_page().
+ *
+ * Returns number of pages pinned. This would be equal to the number of
+ * pages requested. If no pages were pinned, it returns -errno.
+ */
+long pin_user_pages_fd(struct file *file, pgoff_t start,
+  unsigned long nr_pages, struct page **pages)
+{
+   struct page *page;
+   unsigned int flags, i;
+   long ret;
+
+   if (start < 0)
+   return -EINVAL;
+
+   if (!file)
+   return -EINVAL;
+
+   if (!shmem_file(file) && !is_file_hugepages(file))
+   return -EINVAL;
+
+   flags = memalloc_pin_save();
+   do {
+   for (i = 0; i < nr_pages; i++) {
+   /*
+* In most cases, we should be able to find the page
+* in the page cache. If we cannot find it, we try to
+* allocate one and add it to the page cache.
+*/
+   page = find_get_page_flags(file->f_mapping,
+  start + i,
+  FGP_ACCESSED);
+ 

[PATCH v2 2/3] udmabuf: Pin the pages using pin_user_pages_fd() API (v2)

2023-11-05 Thread Vivek Kasireddy
Using pin_user_pages_fd() will ensure that the pages are pinned
correctly using FOLL_PIN. And, this also ensures that we don't
accidentally break features such as memory hotunplug as it would
not allow pinning pages in the movable zone.

This patch also adds back support for mapping hugetlbfs pages
by noting the subpage offsets within the huge pages and uses
this information while populating the scatterlist.

v2:
- Adjust to the change in signature of pin_user_pages_fd() by
  passing in file * instead of fd.

Cc: David Hildenbrand 
Cc: Daniel Vetter 
Cc: Mike Kravetz 
Cc: Hugh Dickins 
Cc: Peter Xu 
Cc: Jason Gunthorpe 
Cc: Gerd Hoffmann 
Cc: Dongwon Kim 
Cc: Junxiao Chang 
Signed-off-by: Vivek Kasireddy 
---
 drivers/dma-buf/udmabuf.c | 81 +--
 1 file changed, 60 insertions(+), 21 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 820c993c8659..aa47af2b547f 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,7 @@ struct udmabuf {
struct page **pages;
struct sg_table *sg;
struct miscdevice *device;
+   pgoff_t *subpgoff;
 };
 
 static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf)
@@ -90,23 +92,31 @@ static struct sg_table *get_sg_table(struct device *dev, 
struct dma_buf *buf,
 {
struct udmabuf *ubuf = buf->priv;
struct sg_table *sg;
+   struct scatterlist *sgl;
+   pgoff_t offset;
+   unsigned long i = 0;
int ret;
 
sg = kzalloc(sizeof(*sg), GFP_KERNEL);
if (!sg)
return ERR_PTR(-ENOMEM);
-   ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount,
-   0, ubuf->pagecount << PAGE_SHIFT,
-   GFP_KERNEL);
+
+   ret = sg_alloc_table(sg, ubuf->pagecount, GFP_KERNEL);
if (ret < 0)
-   goto err;
+   goto err_alloc;
+
+   for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) {
+   offset = ubuf->subpgoff ? ubuf->subpgoff[i] : 0;
+   sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, offset);
+   }
ret = dma_map_sgtable(dev, sg, direction, 0);
if (ret < 0)
-   goto err;
+   goto err_map;
return sg;
 
-err:
+err_map:
sg_free_table(sg);
+err_alloc:
kfree(sg);
return ERR_PTR(ret);
 }
@@ -142,7 +152,9 @@ static void release_udmabuf(struct dma_buf *buf)
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
 
for (pg = 0; pg < ubuf->pagecount; pg++)
-   put_page(ubuf->pages[pg]);
+   unpin_user_page(ubuf->pages[pg]);
+
+   kfree(ubuf->subpgoff);
kfree(ubuf->pages);
kfree(ubuf);
 }
@@ -202,12 +214,13 @@ static long udmabuf_create(struct miscdevice *device,
 {
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct file *memfd = NULL;
-   struct address_space *mapping = NULL;
struct udmabuf *ubuf;
struct dma_buf *buf;
-   pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit;
-   struct page *page;
-   int seals, ret = -EINVAL;
+   pgoff_t pgoff, pgcnt, pgbuf = 0, pglimit, nr_pages;
+   pgoff_t subpgoff, maxsubpgs;
+   struct hstate *hpstate;
+   long ret = -EINVAL;
+   int seals;
u32 i, flags;
 
ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
@@ -241,8 +254,7 @@ static long udmabuf_create(struct miscdevice *device,
memfd = fget(list[i].memfd);
if (!memfd)
goto err;
-   mapping = memfd->f_mapping;
-   if (!shmem_mapping(mapping))
+   if (!shmem_file(memfd) && !is_file_hugepages(memfd))
goto err;
seals = memfd_fcntl(memfd, F_GET_SEALS, 0);
if (seals == -EINVAL)
@@ -253,14 +265,40 @@ static long udmabuf_create(struct miscdevice *device,
goto err;
pgoff = list[i].offset >> PAGE_SHIFT;
pgcnt = list[i].size   >> PAGE_SHIFT;
-   for (pgidx = 0; pgidx < pgcnt; pgidx++) {
-   page = shmem_read_mapping_page(mapping, pgoff + pgidx);
-   if (IS_ERR(page)) {
-   ret = PTR_ERR(page);
+   if (is_file_hugepages(memfd)) {
+   if (!ubuf->subpgoff) {
+   ubuf->subpgoff = kmalloc_array(ubuf->pagecount,
+  
sizeof(*ubuf->subpgoff),
+  GFP_KERNEL);
+   if (!ubuf->subpgoff) {
+   ret = -ENOMEM;
+   goto err;
+   }
+   }
+  

Re: [PATCH] accel/qaic: Update MAX_ORDER use to be inclusive

2023-11-05 Thread Jacek Lawrynowicz
On 03.11.2023 16:33, Jeffrey Hugo wrote:
> MAX_ORDER was redefined so that valid allocations to the page allocator
> are in the range of 0..MAX_ORDER, inclusive in the commit
> 23baf831a32c ("mm, treewide: redefine MAX_ORDER sanely").
> 
> We are treating MAX_ORDER as an exclusive value, and thus could be
> requesting larger allocations.  Update our use to match the redefinition
> of MAX_ORDER.
> 
> Signed-off-by: Jeffrey Hugo 
> Reviewed-by: Pranjal Ramajor Asha Kanojiya 
> Reviewed-by: Carl Vanderlip 
> ---
>  drivers/accel/qaic/qaic_data.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
> index 8da81768f2ab..8998c28e566e 100644
> --- a/drivers/accel/qaic/qaic_data.c
> +++ b/drivers/accel/qaic/qaic_data.c
> @@ -452,7 +452,7 @@ static int create_sgt(struct qaic_device *qdev, struct 
> sg_table **sgt_out, u64 s
>* later
>*/
>   buf_extra = (PAGE_SIZE - size % PAGE_SIZE) % PAGE_SIZE;
> - max_order = min(MAX_ORDER - 1, get_order(size));
> + max_order = min(MAX_ORDER, get_order(size));
>   } else {
>   /* allocate a single page for book keeping */
>   nr_pages = 1;

Reviewed-by: Jacek Lawrynowicz 


[PATCH] drm/atomic-helper: Call stall_checks() before allocate drm_crtc_commit

2023-11-05 Thread oushixiong
From: Shixiong Ou 

Calling stall_checks() before allocating drm_crtc_commit not after that.

Signed-off-by: Shixiong Ou 
---
 drivers/gpu/drm/drm_atomic_helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2444fc33dd7c..94ea878b240d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2283,6 +2283,10 @@ int drm_atomic_helper_setup_commit(struct 
drm_atomic_state *state,
funcs = state->dev->mode_config.helper_private;
 
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, 
new_crtc_state, i) {
+   ret = stall_checks(crtc, nonblock);
+   if (ret)
+   return ret;
+
commit = kzalloc(sizeof(*commit), GFP_KERNEL);
if (!commit)
return -ENOMEM;
@@ -2291,10 +2295,6 @@ int drm_atomic_helper_setup_commit(struct 
drm_atomic_state *state,
 
new_crtc_state->commit = commit;
 
-   ret = stall_checks(crtc, nonblock);
-   if (ret)
-   return ret;
-
/*
 * Drivers only send out events when at least either current or
 * new CRTC state is active. Complete right away if everything
-- 
2.25.1



Re: [PATCH 02/10] drm/tidss: Use PM autosuspend

2023-11-05 Thread Tomi Valkeinen

On 06/11/2023 00:53, Laurent Pinchart wrote:

Hi Tomi,

CC'ing Sakari for his expertise on runtime PM (I think he will soon
start wishing he would be ignorant in this area).

On Thu, Nov 02, 2023 at 08:34:45AM +0200, Tomi Valkeinen wrote:

On 01/11/2023 15:54, Laurent Pinchart wrote:

On Wed, Nov 01, 2023 at 11:17:39AM +0200, Tomi Valkeinen wrote:

Use runtime PM autosuspend feature, with 1s timeout, to avoid
unnecessary suspend-resume cycles when, e.g. the userspace temporarily
turns off the crtcs when configuring the outputs.

Signed-off-by: Tomi Valkeinen 
---
   drivers/gpu/drm/tidss/tidss_drv.c | 8 +++-
   1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tidss/tidss_drv.c 
b/drivers/gpu/drm/tidss/tidss_drv.c
index f403db11b846..64914331715a 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -43,7 +43,9 @@ void tidss_runtime_put(struct tidss_device *tidss)
   
   	dev_dbg(tidss->dev, "%s\n", __func__);
   
-	r = pm_runtime_put_sync(tidss->dev);

+   pm_runtime_mark_last_busy(tidss->dev);
+
+   r = pm_runtime_put_autosuspend(tidss->dev);
WARN_ON(r < 0);
   }
   
@@ -144,6 +146,9 @@ static int tidss_probe(struct platform_device *pdev)
   
   	pm_runtime_enable(dev);
   
+	pm_runtime_set_autosuspend_delay(dev, 1000);

+   pm_runtime_use_autosuspend(dev);
+
   #ifndef CONFIG_PM
/* If we don't have PM, we need to call resume manually */
dispc_runtime_resume(tidss->dispc);


By the way, there's a way to handle this without any ifdef:

dispc_runtime_resume(tidss->dispc);

pm_runtime_set_active(dev);
pm_runtime_get_noresume(dev);
pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);


I'm not sure I follow what you are trying to do here. The call to
dispc_runtime_resume() would crash if we have PM, as the HW would not be
enabled at that point.


Isn't dispc_runtime_resume() meant to enable the hardware ?

The idea is to enable the hardware, then enable runtime PM, and tell the
runtime PM framework that the device is enabled. If CONFIG_PM is not
set, the RPM calls will be no-ops, and the device will stay enable. If
CONFIG_PM is set, the device will be enabled, and will get disabled at
end of probe by a call to pm_runtime_put_autosuspend().


(The text below is more about the end result of this series, rather than 
this specific patch):


Hmm, no, I don't think that's how it works. My understanding is this:

There are multiple parts "enabling the hardware", and I think they 
usually need to be done in this order: 1) enabling the parent devices, 
2) system level HW module enable (this is possibly really part of the 
1), 3) clk/regulator/register setup.


3) is handled by the driver, but 1) and 2) are handled via the runtime 
PM framework. Calling dispc_runtime_resume() as the first thing could 
mean that DSS's parents are not enabled or that the DSS HW module is not 
enabled at the system control level.


That's why I first call pm_runtime_set_active(), which should handle 1) 
and 2).


The only thing dispc_runtime_resume() does wrt. enabling the hardware is 
enabling the fclk. It does a lot more, but all the rest is just 
configuring the hardware to settings that we always want to use (e.g. 
fifo management).


Now, if the bootloader had enabled the display, and the driver did:

- pm_runtime_enable()
- pm_runtime_get()
- dispc_reset()

it would cause dispc_runtime_resume() to be called before the reset. 
This would mean that the dispc_runtime_resume() would be changing 
settings that must not be changed while streaming is enabled.


We could do a DSS reset always as the first thing in 
dispc_runtime_resume() (after enabling the fclk), but that feels a bit 
pointless as after the first reset the DSS is in a known state.


Also, if we don't do a reset at probe time, there are things we need to 
take care of: at least we need to mask the IRQs (presuming we register 
the DSS interrupt at probe time). But generally speaking, I feel a bit 
uncomfortable leaving an IP possibly running in an unknown state after 
probe. I'd much rather just reset it at probe.


 Tomi



Re: [PATCH 3/6] drm/amdgpu: Flush VM updates for split bindings eagerly.

2023-11-05 Thread Tatsuyuki Ishi

> On Oct 31, 2023, at 23:07, Christian König  wrote:
> 
> Am 31.10.23 um 14:59 schrieb Bas Nieuwenhuizen:
>> 
>> 
>> On Tue, Oct 31, 2023 at 2:57 PM Christian König > > wrote:
>>> Am 31.10.23 um 14:40 schrieb Tatsuyuki Ishi:
>>> > The current amdgpu_gem_va_update_vm only tries to perform updates for the
>>> > BO specified in the GEM ioctl; however, when a binding is split, the
>>> > adjacent bindings also need to be updated. Such updates currently ends up
>>> > getting deferred until next submission which causes stalls.
>>> 
>>> Yeah, that is a necessity. The hardware simply doesn't support what you 
>>> try to do here in all cases.
>> 
>> What can the hardware not do here? Is this just needing to wait for TLB 
>> flushes before we can free pagetables, can we just delay that?
> 
> On some hardware generations (especially Navi1x, but also everything older 
> than Polaris) you can't invalidate the TLB while it is in use.
> 
> For Polaris and older it just means that you don't have a guarantee that the 
> shader can't access the memory any more. So delaying the free operation helps 
> here.
> 
> But for Navi1x it's a workaround for a hardware bug. If you try to invalidate 
> the TLB while it is in use you can potentially triggering memory accesses to 
> random addresses.
> 
> That's why we still delay TLB invalidation's to the next CS and use a new 
> VMID for each submission instead of invalidating the old one.

Thanks for the information. I looked into the VMID allocation logic and I see 
that if concurrent_flush is false, then we defer any flush (or VMID reuse that 
requires a flush) until that VMID is idle.

What patch #3 ends up doing is just performing the PT update right away. Any 
required TLB update is deferred by amdgpu_vm_update_range through the increment 
of tlb_seq, and amdgpu_vmid.c is responsible for doing the actual TLB flush in 
a manner that does not trigger the bug.

Can you confirm that this would be fine for the current hardware?

Tatsuyuki.

> 
> I'm currently working on changing that for Navi2x and newer (maybe Vega as 
> well), but this is something you can really only do on some hw generations 
> after validating that it works.
> 
> Regards,
> Christian. 
> 
>>  
>>> 
>>> So this approach won't work in general.
>>> 
>>> Regards,
>>> Christian.
>>> 
>>> >
>>> > Introduce a new state "dirty", shared between per-VM BOs and traditional
>>> > BOs, containing all BOs that have pending updates in `invalids`.
>>> > amdgpu_gem_va_update_vm will now simply flush any pending updates for BOs
>>> > in the dirty state.
>>> >
>>> > Signed-off-by: Tatsuyuki Ishi >> > >
>>> > ---
>>> >   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 18 ---
>>> >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c  | 66 ++---
>>> >   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h  |  3 ++
>>> >   3 files changed, 63 insertions(+), 24 deletions(-)
>>> >
>>> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
>>> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> > index a1b15d0d6c48..01d3a97248b0 100644
>>> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>> > @@ -604,10 +604,9 @@ int amdgpu_gem_metadata_ioctl(struct drm_device 
>>> > *dev, void *data,
>>> >* vital here, so they are not reported back to userspace.
>>> >*/
>>> >   static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
>>> > - struct amdgpu_vm *vm,
>>> > - struct amdgpu_bo_va *bo_va,
>>> > - uint32_t operation)
>>> > + struct amdgpu_vm *vm)
>>> >   {
>>> > + struct amdgpu_bo_va *bo_va;
>>> >   int r;
>>> >   
>>> >   if (!amdgpu_vm_ready(vm))
>>> > @@ -617,12 +616,18 @@ static void amdgpu_gem_va_update_vm(struct 
>>> > amdgpu_device *adev,
>>> >   if (r)
>>> >   goto error;
>>> >   
>>> > - if (operation == AMDGPU_VA_OP_MAP ||
>>> > - operation == AMDGPU_VA_OP_REPLACE) {
>>> > + spin_lock(&vm->status_lock);
>>> > + while (!list_empty(&vm->dirty)) {
>>> > + bo_va = list_first_entry(&vm->dirty, struct amdgpu_bo_va,
>>> > +  base.vm_status);
>>> > + spin_unlock(&vm->status_lock);
>>> > +
>>> >   r = amdgpu_vm_bo_update(adev, bo_va, false);
>>> >   if (r)
>>> >   goto error;
>>> > + spin_lock(&vm->status_lock);
>>> >   }
>>> > + spin_unlock(&vm->status_lock);
>>> >   
>>> >   r = amdgpu_vm_update_pdes(adev, vm, false);
>>> >   
>>> > @@ -792,8 +797,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void 
>>> > *data,
>>> >   break;
>>> >   }
>>> >   if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && 
>>> > !amdgpu_vm_debug)
>>> > - amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
>>> > -