[PATCH v2] drm/doc: Add in introduction sections about tiny drivers and external refs

2022-04-17 Thread Javier Martinez Canillas
Learning about the DRM subsystem could be quite overwhelming for newcomers
but there are lots of useful talks, slides and articles available that can
help to understand the needed concepts and ease the learning curve.

There are also simple DRM drivers that can be used as example about how a
DRM driver should look like.

Add sections to the introduction page, that contains references to these.

Suggested-by: Daniel Vetter 
Signed-off-by: Javier Martinez Canillas 
Acked-by: Pekka Paalanen 
Acked-by: Thomas Zimmermann 
---

Changes in v2:
- Remove paragraph that gave wrong impression that DRM is complex (Pekka 
Paalanen).
- Add Thomas Zimmermann's and Pekka Paalanen's Acked-by tags.
- Replace "Learning material" title with "External References" (Thomas 
Zimmermann).
- Add a section about tiny DRM drivers being a good first example (Daniel 
Vetter).
- Add some more external references that I found interesting since v1 was 
posted.

 Documentation/gpu/introduction.rst | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/Documentation/gpu/introduction.rst 
b/Documentation/gpu/introduction.rst
index 25a56e9c0cfd..574f478c3674 100644
--- a/Documentation/gpu/introduction.rst
+++ b/Documentation/gpu/introduction.rst
@@ -112,3 +112,63 @@ Please conduct yourself in a respectful and civilised 
manner when
 interacting with community members on mailing lists, IRC, or bug
 trackers. The community represents the project as a whole, and abusive
 or bullying behaviour is not tolerated by the project.
+
+Simple DRM drivers to use as examples
+=
+
+The DRM subsystem contains a lot of helper functions to ease writing drivers 
for
+simple graphic devices. For example, the `drivers/gpu/drm/tiny/` directory has 
a
+set of DRM drivers that are simple enough to be implemented in a single file.
+
+These drivers make use of the `struct drm_simple_display_pipe_funcs`, that 
hides
+any complexity of the DRM subsystem and just requires drivers to implement a 
few
+functions needed to operate the device. This could be used for devices that 
just
+need a display pipeline with one full-screen scanout buffer feeding one output.
+
+The tiny DRM drivers are good examples to understand how DRM drivers should 
look
+like since are written as a few hundreds line of code contained in a single 
file.
+
+External References
+===
+
+Delving into a Linux kernel subsystem for the first time can be an overwhelming
+experience, one need to get familiar with all the needed concepts and learn the
+subsystem's internals.
+
+To shallow the learning curve, this section contains a list of presentations
+and documents that can be used to learn about DRM/KMS and graphics in general.
+
+There are different reasons why someone might want to get into DRM: porting an
+existing fbdev driver, write a DRM driver for a new hardware, fixing bugs that
+may face when working on the graphics user-space stack, etc. For this reason,
+the learning material covers many aspects of the Linux graphics stack. From an
+overview of the kernel and user-space stacks to very specific topics.
+
+The list is sorted in reverse chronological order, to keep the most up-to-date
+material at the top. But all of them contain useful information, and it can be
+valuable to go through older material to understand the rationale and context
+in which the recent changes to the DRM subsystem were made.
+
+Conference talks
+
+
+* `An Overview of the Linux and Userspace Graphics Stack 
`_ - Paul Kocialkowski (2020)
+* `Getting pixels on screen on Linux: introduction to Kernel Mode Setting 
`_ - Simon Ser (2020)
+* `Everything Great about Upstream Graphics 
`_ - Daniel Vetter (2019)
+* `An introduction to the Linux DRM subsystem 
`_ - Maxime Ripard (2017)
+* `Embrace the Atomic (Display) Age 
`_ - Daniel Vetter (2016)
+* `Anatomy of an Atomic KMS Driver 
`_ - Laurent Pinchart (2015)
+* `Atomic Modesetting for Drivers 
`_ - Daniel Vetter (2015)
+* `Anatomy of an Embedded KMS Driver 
`_ - Laurent Pinchart (2013)
+
+Slides and articles
+---
+
+* `Understanding the Linux Graphics Stack 
`_ - Bootlin 
(2022)
+* `DRM KMS overview `_ - 
STMicroelectronics (2021)
+* `Linux graphic stack 
`_ - Nathan 
Gauër (2017)
+* `Atomic mode setting design overview, part 1 
`_ - Daniel Vetter (2015)
+* `Atomic mode setting design overview, part 

[PATCH] drm/bridge: fix anx6345 power up sequence

2022-04-17 Thread Torsten Duwe
Align the power-up sequence with the known-good procedure documented in [1]:
un-swap dvdd12 and dvdd25, and allow a little extra time for them to settle
before de-asserting reset.
Fixes: 6aa192698089b ("drm/bridge: Add Analogix anx6345 support")

[1] https://github.com/OLIMEX/DIY-LAPTOP/blob/master/
HARDWARE/A64-TERES/TERES-PCB1-A64-MAIN/Rev.C/TERES_PCB1-A64-MAIN_Rev.C.pdf
(page 5, blue comment down left)

Reported-by: Harald Geyer 
Signed-off-by: Torsten Duwe 
Cc: sta...@vger.kernel.org

---

This fixes the problem that e.g. X screensaver turns the screen black,
and it stays black until the next reboot; definitely on the Teres-I,
probably on the pinebook64, too.

--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -309,27 +309,27 @@ static void anx6345_poweron(struct anx63
gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
usleep_range(1000, 2000);
 
-   err = regulator_enable(anx6345->dvdd12);
+   err = regulator_enable(anx6345->dvdd25);
if (err) {
-   DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
+   DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
  err);
return;
}
 
-   /* T1 - delay between VDD12 and VDD25 should be 0-2ms */
+   /* T1 - delay between VDD25 and VDD12 should be 0-2ms */
usleep_range(1000, 2000);
 
-   err = regulator_enable(anx6345->dvdd25);
+   err = regulator_enable(anx6345->dvdd12);
if (err) {
-   DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
+   DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
  err);
return;
}
 
/* T2 - delay between RESETN and all power rail stable,
-* should be 2-5ms
+* should be at least 2-5ms, 10ms to be safe.
 */
-   usleep_range(2000, 5000);
+   usleep_range(9000, 11000);
 
gpiod_set_value_cansleep(anx6345->gpiod_reset, 0);
 


[PATCH] drm/malidp: convert sysfs snprintf to sysfs_emit

2022-04-17 Thread Xuezhi Zhang
Fix the following coccicheck warning:
drivers/gpu/drm/arm/malidp_drv.c:658:8-16:
WARNING: use scnprintf or sprintf

Signed-off-by: Xuezhi Zhang 
---
 drivers/gpu/drm/arm/malidp_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index d5aef21426cf..b1ffd5ba27d9 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -655,7 +655,7 @@ static ssize_t core_id_show(struct device *dev, struct 
device_attribute *attr,
struct drm_device *drm = dev_get_drvdata(dev);
struct malidp_drm *malidp = drm->dev_private;
 
-   return snprintf(buf, PAGE_SIZE, "%08x\n", malidp->core_id);
+   return sysfs_emit(buf, "%08x\n", malidp->core_id);
 }
 
 static DEVICE_ATTR_RO(core_id);
-- 
2.25.1



Re: [PATCH 2/2] MAINTAINERS: add docs entry to AMDGPU

2022-04-17 Thread Bagas Sanjaya
On 4/16/22 02:50, Tales Lelo da Aparecida wrote:
> To make sure maintainers of amdgpu drivers are aware of any changes
>  in their documentation, add its entry to MAINTAINERS.
> 

Did you mean the Documentation/gpu/amdgpu/ is maintained by dri-devel?

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


Re: [PATCH] drm/bridge: fix anx6345 power up sequence

2022-04-17 Thread Vasily Khoruzhick
On Sun, Apr 17, 2022 at 9:15 AM Torsten Duwe  wrote:
>
> Align the power-up sequence with the known-good procedure documented in [1]:
> un-swap dvdd12 and dvdd25, and allow a little extra time for them to settle
> before de-asserting reset.

Hi Torsten,

Interesting find! I tried to fix the issue several times by playing
with the delays to no avail.

What's interesting, ANX6345 datasheet allows DVDD12 to come up either
earlier or later than DVDD25 with the delay of T1 (2ms typical)
between them, and actually bringing up DVDD12 first works fine in
u-boot.

The datasheet also requires reset to be deasserted no earlier than T2
(2-5ms) after all the rails are stable.

Another thing it mentions is that the system clock must be stable for
T3 (1-3ms) before reset is deasserted, T3 is already a part of T2,
however it cannot be gated on Pinebook, see [1], page 15

The change looks good to me, but I'll need some time to actually test
it. If you don't hear from me for longer than a week please ping me.

[1] https://files.pine64.org/doc/pinebook/pinebook_mainboard_schematic_3.0.pdf

Regards,
Vasily

> Fixes: 6aa192698089b ("drm/bridge: Add Analogix anx6345 support")
>
> [1] https://github.com/OLIMEX/DIY-LAPTOP/blob/master/
> HARDWARE/A64-TERES/TERES-PCB1-A64-MAIN/Rev.C/TERES_PCB1-A64-MAIN_Rev.C.pdf
> (page 5, blue comment down left)
>
> Reported-by: Harald Geyer 
> Signed-off-by: Torsten Duwe 
> Cc: sta...@vger.kernel.org
> ---
>
> This fixes the problem that e.g. X screensaver turns the screen black,
> and it stays black until the next reboot; definitely on the Teres-I,
> probably on the pinebook64, too.

You should probably move this comment up to be included in the commit message.



>
> --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> @@ -309,27 +309,27 @@ static void anx6345_poweron(struct anx63
> gpiod_set_value_cansleep(anx6345->gpiod_reset, 1);
> usleep_range(1000, 2000);
>
> -   err = regulator_enable(anx6345->dvdd12);
> +   err = regulator_enable(anx6345->dvdd25);
> if (err) {
> -   DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
> +   DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
>   err);
> return;
> }
>
> -   /* T1 - delay between VDD12 and VDD25 should be 0-2ms */
> +   /* T1 - delay between VDD25 and VDD12 should be 0-2ms */
> usleep_range(1000, 2000);
>
> -   err = regulator_enable(anx6345->dvdd25);
> +   err = regulator_enable(anx6345->dvdd12);
> if (err) {
> -   DRM_ERROR("Failed to enable dvdd25 regulator: %d\n",
> +   DRM_ERROR("Failed to enable dvdd12 regulator: %d\n",
>   err);
> return;
> }
>
> /* T2 - delay between RESETN and all power rail stable,
> -* should be 2-5ms
> +* should be at least 2-5ms, 10ms to be safe.
>  */
> -   usleep_range(2000, 5000);
> +   usleep_range(9000, 11000);
>
> gpiod_set_value_cansleep(anx6345->gpiod_reset, 0);
>


Re: [PATCH v2] drm: mxsfb: Obtain bus flags from bridge state

2022-04-17 Thread Lucas Stach
Am Sonntag, dem 17.04.2022 um 04:10 +0200 schrieb Marek Vasut:
> In case the MXSFB is connected to a bridge, attempt to obtain bus flags
> from that bridge state too. The bus flags may specify e.g. the DE signal
> polarity.
> 
> Acked-by: Alexander Stein 
> Signed-off-by: Marek Vasut 
> Cc: Alexander Stein 
> Cc: Laurent Pinchart 
> Cc: Lucas Stach 
> Cc: Peng Fan 
> Cc: Robby Cai 
> Cc: Sam Ravnborg 
> Cc: Stefan Agner 

Reviewed-by: Lucas Stach 

> ---
> V2: Add AB from Alexander
> ---
>  drivers/gpu/drm/mxsfb/mxsfb_kms.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c 
> b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> index b7c70d269d2cb..cd2a59e110c3a 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> @@ -275,6 +275,7 @@ static int mxsfb_reset_block(struct mxsfb_drm_private 
> *mxsfb)
>  }
>  
>  static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb,
> +  struct drm_bridge_state *bridge_state,
>const u32 bus_format)
>  {
>   struct drm_device *drm = mxsfb->crtc.dev;
> @@ -284,6 +285,8 @@ static void mxsfb_crtc_mode_set_nofb(struct 
> mxsfb_drm_private *mxsfb,
>  
>   if (mxsfb->bridge && mxsfb->bridge->timings)
>   bus_flags = mxsfb->bridge->timings->input_bus_flags;
> + else if (bridge_state)
> + bus_flags = bridge_state->input_bus_cfg.flags;
>  
>   DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
>m->crtc_clock,
> @@ -345,7 +348,7 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc 
> *crtc,
>   struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev);
>   struct drm_plane_state *new_pstate = 
> drm_atomic_get_new_plane_state(state,
>   
> crtc->primary);
> - struct drm_bridge_state *bridge_state;
> + struct drm_bridge_state *bridge_state = NULL;
>   struct drm_device *drm = mxsfb->drm;
>   u32 bus_format = 0;
>   dma_addr_t paddr;
> @@ -381,7 +384,7 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc 
> *crtc,
>   if (!bus_format)
>   bus_format = MEDIA_BUS_FMT_RGB888_1X24;
>  
> - mxsfb_crtc_mode_set_nofb(mxsfb, bus_format);
> + mxsfb_crtc_mode_set_nofb(mxsfb, bridge_state, bus_format);
>  
>   /* Write cur_buf as well to avoid an initial corrupt frame */
>   paddr = drm_fb_cma_get_gem_addr(new_pstate->fb, new_pstate, 0);




[PATCH v4 00/15] Add generic memory shrinker to VirtIO-GPU and Panfrost DRM drivers

2022-04-17 Thread Dmitry Osipenko
Hello,

This patchset introduces memory shrinker for the VirtIO-GPU DRM driver.
During OOM, the shrinker will release BOs that are marked as "not needed"
by userspace using the new madvise IOCTL, it will also evict idling BOs
to SWAP. The userspace in this case is the Mesa VirGL driver, it will mark
the cached BOs as "not needed", allowing kernel driver to release memory
of the cached shmem BOs on lowmem situations, preventing OOM kills.

This patchset adds memory purging and eviction support to VirtIO-GPU driver.

The Panfrost driver is switched to use generic memory shrinker. Eviction
support will come later on, after resolving the blocker bug in Panfrost.

This patchset also includes couple improvements and fixes for various
minor things that I found while was working on the shrinker.

The Mesa and IGT patches will be kept on hold until this kernel series
will be approved and merged.

This patchset was tested using Qemu and crosvm, including both cases of
IOMMU off/on.

Mesa: https://gitlab.freedesktop.org/digetx/mesa/-/commits/virgl-madvise
IGT:  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/virtio-madvise
  
https://gitlab.freedesktop.org/digetx/igt-gpu-tools/-/commits/panfrost-madvise

Changelog:

v4: - Corrected minor W=1 warnings reported by kernel test robot for v3.

- Renamed DRM_GEM_SHMEM_PAGES_STATE_ACTIVE/INACTIVE to PINNED/UNPINNED,
  for more clarity.

v3: - Hardened shrinker's count() with usage of READ_ONCE() since we don't
  use atomic type for counting and technically compiler is free to
  re-fetch counter's variable.

- "Correct drm_gem_shmem_get_sg_table() error handling" now uses
  PTR_ERR_OR_ZERO(), fixing typo that was made in v2.

- Removed obsoleted shrinker from the Panfrost driver, which I missed to
  do in v2 by accident and Alyssa Rosenzweig managed to notice it.

- CCed stable kernels in all patches that make fixes, even the minor ones,
  like was suggested by Emil Velikov and added his r-b to the patches.

- Added t-b from Steven Price to the Panfrost's shrinker patch.

- Corrected doc-comment of drm_gem_shmem_object.madv, like was suggested
  by Steven Price. Comment now says that madv=1 means "object is purged"
  instead of saying that value is unused.

- Added more doc-comments to the new shmem shrinker API.

- The "Improve DMA API usage for shmem BOs" patch got more improvements
  by removing the obsoleted drm_dev_set_unique() quirk and its comment.

- Added patch that makes Virtio-GPU driver to use common dev_is_pci()
  helper, which was suggested by Robin Murphy.

- Added new "drm/shmem-helper: Take GEM reservation lock instead of
  drm_gem_shmem locks" patch, which was suggested by Daniel Vetter.

- Added new "drm/virtio: Simplify error handling of
  virtio_gpu_object_create()" patch.

- Improved "Correct doc-comment of drm_gem_shmem_get_sg_table()" patch,
  like was suggested by Daniel Vetter, by saying that function returns
  ERR_PTR() and not errno.

- virtio_gpu_purge_object() is fenced properly now, turned out
  virtio_gpu_notify() doesn't do fencing as I was supposing before.
  Stress testing of memory eviction revealed that.

- Added new patch that corrects virtio_gpu_plane_cleanup_fb() to use
  appropriate atomic plane state.

- SHMEM shrinker got eviction support.

- VirtIO-GPU driver now supports memory eviction. It's enabled for a
  non-blob GEMs only, i.e. for VirGL. The blobs don't support dynamic
  attaching/detaching of guest's memory, so it's not trivial to enable
  them.

- Added patch that removes obsoleted drm_gem_shmem_purge()

- Added patch that makes drm_gem_shmem_get_pages() private.

- Added patch that fixes lockup on dma_resv_reserve_fences() error.

v2: - Improved shrinker by using a more fine-grained locking to reduce
  contention during scan of objects and dropped locking from the
  'counting' callback by tracking count of shrinkable pages. This
  was suggested by Rob Clark in the comment to v1.

- Factored out common shrinker code into drm_gem_shmem_helper.c
  and switched Panfrost driver to use the new common memory shrinker.
  This was proposed by Thomas Zimmermann in his prototype series that
  he shared with us in the comment to v1. Note that I only compile-tested
  the Panfrost driver.

- Shrinker now takes object_name_lock during scan to prevent racing
  with dma-buf exporting.

- Shrinker now takes vmap_lock during scan to prevent racing with shmem
  vmap/unmap code.

- Added "Correct doc-comment of drm_gem_shmem_get_sg_table()" patch,
  which I sent out previously as a standalone change, since the
  drm_gem_shmem_helper.c is now touched by this patchset anyways and
  it doesn't hurt to group all the patches together.

Dmitry Osipenko (15):
  drm/virtio: Correct drm_gem_shmem_get_sg_table() error

[PATCH v4 02/15] drm/virtio: Check whether transferred 2D BO is shmem

2022-04-17 Thread Dmitry Osipenko
Transferred 2D BO always must be a shmem BO. Add check for that to prevent
NULL dereference if userspace passes a VRAM BO.

Cc: sta...@vger.kernel.org
Reviewed-by: Emil Velikov 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_vq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c 
b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 7c052efe8836..2edf31806b74 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -595,7 +595,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct 
virtio_gpu_device *vgdev,
bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo);
 
-   if (use_dma_api)
+   if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
shmem->pages, DMA_TO_DEVICE);
 
-- 
2.35.1



[PATCH v4 01/15] drm/virtio: Correct drm_gem_shmem_get_sg_table() error handling

2022-04-17 Thread Dmitry Osipenko
drm_gem_shmem_get_sg_table() never ever returned NULL on error. Correct
the error handling to avoid crash on OOM.

Cc: sta...@vger.kernel.org
Reviewed-by: Emil Velikov 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_object.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
b/drivers/gpu/drm/virtio/virtgpu_object.c
index f293e6ad52da..3d0c8d4d1c20 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -168,9 +168,11 @@ static int virtio_gpu_object_shmem_init(struct 
virtio_gpu_device *vgdev,
 * since virtio_gpu doesn't support dma-buf import from other devices.
 */
shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
-   if (!shmem->pages) {
+   ret = PTR_ERR_OR_ZERO(shmem->pages);
+   if (ret) {
drm_gem_shmem_unpin(&bo->base);
-   return -EINVAL;
+   shmem->pages = NULL;
+   return ret;
}
 
if (use_dma_api) {
-- 
2.35.1



[PATCH v4 05/15] drm/virtio: Use appropriate atomic state in virtio_gpu_plane_cleanup_fb()

2022-04-17 Thread Dmitry Osipenko
Make virtio_gpu_plane_cleanup_fb() to clean the state which DRM core
wants to clean up and not the current plane's state. Normally the older
atomic state is cleaned up, but the newer state could also be cleaned up
in case of aborted commits.

Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_plane.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c 
b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 6d3cc9e238a4..7148f3813d8b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -266,14 +266,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane 
*plane,
 }
 
 static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
-   struct drm_plane_state *old_state)
+   struct drm_plane_state *state)
 {
struct virtio_gpu_framebuffer *vgfb;
 
-   if (!plane->state->fb)
+   if (!state->fb)
return;
 
-   vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
+   vgfb = to_virtio_gpu_framebuffer(state->fb);
if (vgfb->fence) {
dma_fence_put(&vgfb->fence->f);
vgfb->fence = NULL;
-- 
2.35.1



[PATCH v4 03/15] drm/virtio: Unlock GEM reservations on virtio_gpu_object_shmem_init() error

2022-04-17 Thread Dmitry Osipenko
Unlock reservations in the error code path of virtio_gpu_object_create()
to silence debug warning splat produced by ww_mutex_destroy(&obj->lock)
when GEM is released with the held lock.

Cc: sta...@vger.kernel.org
Reviewed-by: Emil Velikov 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_object.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
b/drivers/gpu/drm/virtio/virtgpu_object.c
index 3d0c8d4d1c20..21c19cdedce0 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -250,6 +250,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
 
ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
if (ret != 0) {
+   if (fence)
+   virtio_gpu_array_unlock_resv(objs);
virtio_gpu_array_put_free(objs);
virtio_gpu_free_object(&shmem_obj->base);
return ret;
-- 
2.35.1



[PATCH v4 04/15] drm/virtio: Unlock reservations on dma_resv_reserve_fences() error

2022-04-17 Thread Dmitry Osipenko
Unlock reservations on dma_resv_reserve_fences() error to fix recursive
locking of the reservations when this error happens.

Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_gem.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 580a78809836..7db48d17ee3a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -228,8 +228,10 @@ int virtio_gpu_array_lock_resv(struct 
virtio_gpu_object_array *objs)
 
for (i = 0; i < objs->nents; ++i) {
ret = dma_resv_reserve_fences(objs->objs[i]->resv, 1);
-   if (ret)
+   if (ret) {
+   virtio_gpu_array_unlock_resv(objs);
return ret;
+   }
}
return ret;
 }
-- 
2.35.1



[PATCH v4 06/15] drm/virtio: Simplify error handling of virtio_gpu_object_create()

2022-04-17 Thread Dmitry Osipenko
Change the order of SHMEM initialization and reservation locking to
make code cleaner a tad and to prepare to transitioning of the common
GEM SHMEM code to use the GEM's reservation lock instead of the
shmem.page_lock.

There is no need to lock reservation during allocation of the SHMEM pages
because the lock is needed only to avoid racing with the async host-side
allocation. Hence we can safely move the SHMEM initialization out of the
reservation lock.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_object.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c 
b/drivers/gpu/drm/virtio/virtgpu_object.c
index 21c19cdedce0..18f70ef6b4d0 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -236,6 +236,10 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
 
bo->dumb = params->dumb;
 
+   ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
+   if (ret != 0)
+   goto err_put_id;
+
if (fence) {
ret = -ENOMEM;
objs = virtio_gpu_array_alloc(1);
@@ -248,15 +252,6 @@ int virtio_gpu_object_create(struct virtio_gpu_device 
*vgdev,
goto err_put_objs;
}
 
-   ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
-   if (ret != 0) {
-   if (fence)
-   virtio_gpu_array_unlock_resv(objs);
-   virtio_gpu_array_put_free(objs);
-   virtio_gpu_free_object(&shmem_obj->base);
-   return ret;
-   }
-
if (params->blob) {
if (params->blob_mem == VIRTGPU_BLOB_MEM_GUEST)
bo->guest_blob = true;
-- 
2.35.1



[PATCH v4 09/15] drm/shmem-helper: Correct doc-comment of drm_gem_shmem_get_sg_table()

2022-04-17 Thread Dmitry Osipenko
drm_gem_shmem_get_sg_table() never returns NULL on error, but a ERR_PTR.
Correct the doc comment which says that it returns NULL on error.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 8ad0e02991ca..30ee46348a99 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -662,7 +662,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
  * drm_gem_shmem_get_pages_sgt() instead.
  *
  * Returns:
- * A pointer to the scatter/gather table of pinned pages or NULL on failure.
+ * A pointer to the scatter/gather table of pinned pages or errno on failure.
  */
 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem)
 {
@@ -688,7 +688,8 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
  * drm_gem_shmem_get_sg_table() should not be directly called by drivers.
  *
  * Returns:
- * A pointer to the scatter/gather table of pinned pages or errno on failure.
+ * A pointer to the scatter/gather table of pinned pages ERR_PTR()-encoded
+ * error code on failure.
  */
 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object 
*shmem)
 {
-- 
2.35.1



[PATCH v4 12/15] drm/virtio: Support memory shrinking

2022-04-17 Thread Dmitry Osipenko
Support generic DRM SHMEM memory shrinker and add new madvise IOCTL
to the VirtIO-GPU driver. Userspace (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. Altogether this allows to prevent OOM
kills of guest applications that use VirGL by lowering memory pressure.

Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.h|  15 ++-
 drivers/gpu/drm/virtio/virtgpu_gem.c|  46 
 drivers/gpu/drm/virtio/virtgpu_ioctl.c  |  37 +++
 drivers/gpu/drm/virtio/virtgpu_kms.c|   9 ++
 drivers/gpu/drm/virtio/virtgpu_object.c | 139 +++-
 drivers/gpu/drm/virtio/virtgpu_plane.c  |  17 ++-
 drivers/gpu/drm/virtio/virtgpu_vq.c |  40 +++
 include/uapi/drm/virtgpu_drm.h  |  14 +++
 8 files changed, 288 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index b2d93cb12ebf..c8918a271e1c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -274,7 +274,7 @@ struct virtio_gpu_fpriv {
 };
 
 /* virtgpu_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 12
+#define DRM_VIRTIO_NUM_IOCTLS 13
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
 
@@ -310,6 +310,10 @@ void virtio_gpu_array_put_free(struct 
virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object_array *objs);
 void virtio_gpu_array_put_free_work(struct work_struct *work);
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs);
+int virtio_gpu_gem_host_mem_release(struct virtio_gpu_object *bo);
+bool virtio_gpu_gem_madvise(struct virtio_gpu_object *obj, int madv);
 
 /* virtgpu_vq.c */
 int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
@@ -321,6 +325,8 @@ void virtio_gpu_cmd_create_resource(struct 
virtio_gpu_device *vgdev,
struct virtio_gpu_fence *fence);
 void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
   struct virtio_gpu_object *bo);
+int virtio_gpu_cmd_release_resource(struct virtio_gpu_device *vgdev,
+   struct virtio_gpu_object *bo);
 void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
uint64_t offset,
uint32_t width, uint32_t height,
@@ -341,6 +347,9 @@ void virtio_gpu_object_attach(struct virtio_gpu_device 
*vgdev,
  struct virtio_gpu_object *obj,
  struct virtio_gpu_mem_entry *ents,
  unsigned int nents);
+void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
+ struct virtio_gpu_object *obj,
+ struct virtio_gpu_fence *fence);
 int virtio_gpu_attach_status_page(struct virtio_gpu_device *vgdev);
 int virtio_gpu_detach_status_page(struct virtio_gpu_device *vgdev);
 void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
@@ -483,4 +492,8 @@ void virtio_gpu_vram_unmap_dma_buf(struct device *dev,
   struct sg_table *sgt,
   enum dma_data_direction dir);
 
+/* virtgpu_gem_shrinker.c */
+int virtio_gpu_gem_shrinker_init(struct virtio_gpu_device *vgdev);
+void virtio_gpu_gem_shrinker_fini(struct virtio_gpu_device *vgdev);
+
 #endif
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c 
b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 7db48d17ee3a..08189ad43736 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -294,3 +294,49 @@ void virtio_gpu_array_put_free_work(struct work_struct 
*work)
}
spin_unlock(&vgdev->obj_free_lock);
 }
+
+int virtio_gpu_array_prepare(struct virtio_gpu_device *vgdev,
+struct virtio_gpu_object_array *objs)
+{
+   struct drm_gem_shmem_object *shmem;
+   int ret = 0;
+   u32 i;
+
+   for (i = 0; i < objs->nents; i++) {
+   shmem = to_drm_gem_shmem_obj(objs->objs[i]);
+   ret = drm_gem_shmem_swap_in_locked(shmem);
+   if (ret)
+   break;
+   }
+
+   return ret;
+}
+
+bool virtio_gpu_gem_madvise(struct virtio_gpu_object *bo, int madv)
+{
+   /*
+* For now we support only purging BOs that are backed by guest's
+* memory.
+*/
+   if (!virtio_gpu_is_shmem(bo))
+   return true;
+
+   return drm_gem_shmem_madvise(&bo->base, madv);
+}
+
+int virtio_gpu_gem_host

[PATCH v4 07/15] drm/virtio: Improve DMA API usage for shmem BOs

2022-04-17 Thread Dmitry Osipenko
DRM API requires the DRM's driver to be backed with the device that can
be used for generic DMA operations. The VirtIO-GPU device can't perform
DMA operations if it uses PCI transport because PCI device driver creates
a virtual VirtIO-GPU device that isn't associated with the PCI. Use PCI's
GPU device for the DRM's device instead of the VirtIO-GPU device and drop
DMA-related hacks from the VirtIO-GPU driver.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.c| 51 ++
 drivers/gpu/drm/virtio/virtgpu_drv.h|  5 +--
 drivers/gpu/drm/virtio/virtgpu_kms.c|  7 ++--
 drivers/gpu/drm/virtio/virtgpu_object.c | 56 +
 drivers/gpu/drm/virtio/virtgpu_vq.c | 13 +++---
 5 files changed, 32 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c 
b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 5f25a8d15464..0141b7df97ec 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -46,12 +46,11 @@ static int virtio_gpu_modeset = -1;
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, virtio_gpu_modeset, int, 0400);
 
-static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device 
*vdev)
+static int virtio_gpu_pci_quirk(struct drm_device *dev)
 {
-   struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
+   struct pci_dev *pdev = to_pci_dev(dev->dev);
const char *pname = dev_name(&pdev->dev);
bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
-   char unique[20];
int ret;
 
DRM_INFO("pci: %s detected at %s\n",
@@ -63,39 +62,7 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev, 
struct virtio_device *vd
return ret;
}
 
-   /*
-* Normally the drm_dev_set_unique() call is done by core DRM.
-* The following comment covers, why virtio cannot rely on it.
-*
-* Unlike the other virtual GPU drivers, virtio abstracts the
-* underlying bus type by using struct virtio_device.
-*
-* Hence the dev_is_pci() check, used in core DRM, will fail
-* and the unique returned will be the virtio_device "virtio0",
-* while a "pci:..." one is required.
-*
-* A few other ideas were considered:
-* - Extend the dev_is_pci() check [in drm_set_busid] to
-*   consider virtio.
-*   Seems like a bigger hack than what we have already.
-*
-* - Point drm_device::dev to the parent of the virtio_device
-*   Semantic changes:
-*   * Using the wrong device for i2c, framebuffer_alloc and
-* prime import.
-*   Visual changes:
-*   * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
-* will print the wrong information.
-*
-* We could address the latter issues, by introducing
-* drm_device::bus_dev, ... which would be used solely for this.
-*
-* So for the moment keep things as-is, with a bulky comment
-* for the next person who feels like removing this
-* drm_dev_set_unique() quirk.
-*/
-   snprintf(unique, sizeof(unique), "pci:%s", pname);
-   return drm_dev_set_unique(dev, unique);
+   return 0;
 }
 
 static int virtio_gpu_probe(struct virtio_device *vdev)
@@ -109,18 +76,24 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
if (virtio_gpu_modeset == 0)
return -EINVAL;
 
-   dev = drm_dev_alloc(&driver, &vdev->dev);
+   /*
+* The virtio-gpu device is a virtual device that doesn't have DMA
+* ops assigned to it, nor DMA mask set and etc. Its parent device
+* is actual GPU device we want to use it for the DRM's device in
+* order to benefit from using generic DRM APIs.
+*/
+   dev = drm_dev_alloc(&driver, vdev->dev.parent);
if (IS_ERR(dev))
return PTR_ERR(dev);
vdev->priv = dev;
 
if (!strcmp(vdev->dev.parent->bus->name, "pci")) {
-   ret = virtio_gpu_pci_quirk(dev, vdev);
+   ret = virtio_gpu_pci_quirk(dev);
if (ret)
goto err_free;
}
 
-   ret = virtio_gpu_init(dev);
+   ret = virtio_gpu_init(vdev, dev);
if (ret)
goto err_free;
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 0a194aaad419..b2d93cb12ebf 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -100,8 +100,6 @@ struct virtio_gpu_object {
 
 struct virtio_gpu_object_shmem {
struct virtio_gpu_object base;
-   struct sg_table *pages;
-   uint32_t mapped;
 };
 
 struct virtio_gpu_object_vram {
@@ -214,7 +212,6 @@ struct virtio_gpu_drv_cap_cache {
 };
 
 struct virtio_gpu_device {
-   struct device *dev;
struct drm_device *ddev;
 

[PATCH v4 15/15] drm/shmem-helper: Remove drm_gem_shmem_purge()

2022-04-17 Thread Dmitry Osipenko
The drm_gem_shmem_purge() was added back in 2019 and never had a user
since then. GEM's purging is now managed by the generic shrinker and
only the "locked" variant of the function is wanted. Remove the obsoleted
function.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ---
 include/drm/drm_gem_shmem_helper.h |  2 --
 2 files changed, 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 6d83d11211fc..3695fdb24ac8 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -991,17 +991,6 @@ void drm_gem_shmem_purge_locked(struct 
drm_gem_shmem_object *shmem)
 }
 EXPORT_SYMBOL(drm_gem_shmem_purge_locked);
 
-bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
-{
-   if (!dma_resv_trylock(shmem->base.resv))
-   return false;
-   drm_gem_shmem_purge_locked(shmem);
-   dma_resv_unlock(shmem->base.resv);
-
-   return true;
-}
-EXPORT_SYMBOL(drm_gem_shmem_purge);
-
 /**
  * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object
  * @file: DRM file structure to create the dumb buffer for
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index 84316c281292..91e97aa829a7 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -179,8 +179,6 @@ int drm_gem_shmem_swap_in_pages_locked(struct 
drm_gem_shmem_object *shmem);
 int drm_gem_shmem_swap_in_locked(struct drm_gem_shmem_object *shmem);
 
 void drm_gem_shmem_evict_locked(struct drm_gem_shmem_object *shmem);
-
-bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem);
 
 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object 
*shmem);
-- 
2.35.1



[PATCH v4 13/15] drm/panfrost: Switch to generic memory shrinker

2022-04-17 Thread Dmitry Osipenko
Replace Panfrost's memory shrinker with a generic DRM SHMEM memory
shrinker.

Tested-by: Steven Price 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/panfrost/Makefile |   1 -
 drivers/gpu/drm/panfrost/panfrost_device.h|   4 -
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  19 +--
 drivers/gpu/drm/panfrost/panfrost_gem.c   |  30 +++--
 drivers/gpu/drm/panfrost/panfrost_gem.h   |   9 --
 .../gpu/drm/panfrost/panfrost_gem_shrinker.c  | 122 --
 drivers/gpu/drm/panfrost/panfrost_job.c   |  18 ++-
 7 files changed, 39 insertions(+), 164 deletions(-)
 delete mode 100644 drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c

diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index b71935862417..ecf0864cb515 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -5,7 +5,6 @@ panfrost-y := \
panfrost_device.o \
panfrost_devfreq.o \
panfrost_gem.o \
-   panfrost_gem_shrinker.o \
panfrost_gpu.o \
panfrost_job.o \
panfrost_mmu.o \
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 8b25278f34c8..fe04b21fc044 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -115,10 +115,6 @@ struct panfrost_device {
atomic_t pending;
} reset;
 
-   struct mutex shrinker_lock;
-   struct list_head shrinker_list;
-   struct shrinker shrinker;
-
struct panfrost_devfreq pfdevfreq;
 };
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 7fcbc2a5b6cd..57a93555813f 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -160,7 +160,6 @@ panfrost_lookup_bos(struct drm_device *dev,
break;
}
 
-   atomic_inc(&bo->gpu_usecount);
job->mappings[i] = mapping;
}
 
@@ -391,7 +390,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 {
struct panfrost_file_priv *priv = file_priv->driver_priv;
struct drm_panfrost_madvise *args = data;
-   struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_object *gem_obj;
struct panfrost_gem_object *bo;
int ret = 0;
@@ -404,7 +402,6 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
bo = to_panfrost_bo(gem_obj);
 
-   mutex_lock(&pfdev->shrinker_lock);
mutex_lock(&bo->mappings.lock);
if (args->madv == PANFROST_MADV_DONTNEED) {
struct panfrost_gem_mapping *first;
@@ -430,17 +427,8 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, 
void *data,
 
args->retained = drm_gem_shmem_madvise(&bo->base, args->madv);
 
-   if (args->retained) {
-   if (args->madv == PANFROST_MADV_DONTNEED)
-   list_add_tail(&bo->base.madv_list,
- &pfdev->shrinker_list);
-   else if (args->madv == PANFROST_MADV_WILLNEED)
-   list_del_init(&bo->base.madv_list);
-   }
-
 out_unlock_mappings:
mutex_unlock(&bo->mappings.lock);
-   mutex_unlock(&pfdev->shrinker_lock);
 
drm_gem_object_put(gem_obj);
return ret;
@@ -571,9 +559,6 @@ static int panfrost_probe(struct platform_device *pdev)
ddev->dev_private = pfdev;
pfdev->ddev = ddev;
 
-   mutex_init(&pfdev->shrinker_lock);
-   INIT_LIST_HEAD(&pfdev->shrinker_list);
-
err = panfrost_device_init(pfdev);
if (err) {
if (err != -EPROBE_DEFER)
@@ -595,7 +580,7 @@ static int panfrost_probe(struct platform_device *pdev)
if (err < 0)
goto err_out1;
 
-   panfrost_gem_shrinker_init(ddev);
+   drm_gem_shmem_shrinker_register(ddev);
 
return 0;
 
@@ -613,8 +598,8 @@ static int panfrost_remove(struct platform_device *pdev)
struct panfrost_device *pfdev = platform_get_drvdata(pdev);
struct drm_device *ddev = pfdev->ddev;
 
+   drm_gem_shmem_shrinker_unregister(ddev);
drm_dev_unregister(ddev);
-   panfrost_gem_shrinker_cleanup(ddev);
 
pm_runtime_get_sync(pfdev->dev);
pm_runtime_disable(pfdev->dev);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 293e799e2fe8..b4a7ea7c8f00 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -19,16 +19,6 @@ static void panfrost_gem_free_object(struct drm_gem_object 
*obj)
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
struct panfrost_device *pfdev = obj->dev->dev_private;
 
-   /*
-* Make sure the BO is no longer inserted in the shrinker list before
-* taking care of the destruction itself. If we don't do that we 

[PATCH v4 08/15] drm/virtio: Use dev_is_pci()

2022-04-17 Thread Dmitry Osipenko
Use common dev_is_pci() helper to replace the strcmp("pci") used by driver.

Suggested-by: Robin Murphy 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/virtio/virtgpu_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c 
b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 0141b7df97ec..0035affc3e59 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -87,7 +87,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
return PTR_ERR(dev);
vdev->priv = dev;
 
-   if (!strcmp(vdev->dev.parent->bus->name, "pci")) {
+   if (dev_is_pci(vdev->dev.parent)) {
ret = virtio_gpu_pci_quirk(dev);
if (ret)
goto err_free;
-- 
2.35.1



[PATCH v4 14/15] drm/shmem-helper: Make drm_gem_shmem_get_pages() private

2022-04-17 Thread Dmitry Osipenko
VirtIO-GPU driver was the only user of drm_gem_shmem_get_pages()
and it now uses drm_gem_shmem_get_pages_sgt(). Make the get_pages()
private to drm_gem_shmem_helper.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 3 +--
 include/drm/drm_gem_shmem_helper.h | 1 -
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 3838fb8d6f3a..6d83d11211fc 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -537,7 +537,7 @@ static int drm_gem_shmem_get_pages_locked(struct 
drm_gem_shmem_object *shmem)
  * Returns:
  * 0 on success or a negative error code on failure.
  */
-int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
+static int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
 {
int ret;
 
@@ -554,7 +554,6 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object 
*shmem)
 
return ret;
 }
-EXPORT_SYMBOL(drm_gem_shmem_get_pages);
 
 static void drm_gem_shmem_get_pages_no_fail(struct drm_gem_shmem_object *shmem)
 {
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index a65557b446e6..84316c281292 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -144,7 +144,6 @@ struct drm_gem_shmem_object {
 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, 
size_t size);
 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
 
-int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem);
 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
-- 
2.35.1



[PATCH v4 11/15] drm/shmem-helper: Add generic memory shrinker

2022-04-17 Thread Dmitry Osipenko
Introduce a common DRM SHMEM shrinker. It allows to reduce code
duplication among DRM drivers that implement theirs own shrinkers.
This is initial version of the shrinker that covers basic needs of
GPU drivers, both purging and eviction of shmem objects are supported.

This patch is based on a couple ideas borrowed from Rob's Clark MSM
shrinker and Thomas' Zimmermann variant of SHMEM shrinker.

In order to start using DRM SHMEM shrinker drivers should:

1. Implement new purge(), evict() + swap_in() GEM callbacks.
2. Register shrinker using drm_gem_shmem_shrinker_register(drm_device).
3. Use drm_gem_shmem_set_purgeable_and_evictable(shmem) and alike API
   functions to activate shrinking of GEMs.

Signed-off-by: Daniel Almeida 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 765 -
 include/drm/drm_device.h   |   4 +
 include/drm/drm_gem.h  |  35 ++
 include/drm/drm_gem_shmem_helper.h | 105 +++-
 4 files changed, 877 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 3ecef571eff3..3838fb8d6f3a 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -88,6 +88,13 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
 
INIT_LIST_HEAD(&shmem->madv_list);
 
+   /*
+* Eviction and purging are disabled by default, shmem user must enable
+* them explicitly using drm_gem_shmem_set_evictable/purgeable().
+*/
+   shmem->eviction_disable_count = 1;
+   shmem->purging_disable_count = 1;
+
if (!private) {
/*
 * Our buffers are kept pinned, so allocating them
@@ -126,6 +133,107 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct 
drm_device *dev, size_t
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
 
+static void
+drm_gem_shmem_add_pages_to_shrinker(struct drm_gem_shmem_object *shmem)
+{
+   struct drm_gem_object *obj = &shmem->base;
+   struct drm_gem_shmem_shrinker *gem_shrinker = obj->dev->shmem_shrinker;
+   size_t page_count = obj->size >> PAGE_SHIFT;
+
+   if (!shmem->pages_shrinkable) {
+   WARN_ON(gem_shrinker->shrinkable_count + page_count < 
page_count);
+   gem_shrinker->shrinkable_count += page_count;
+   shmem->pages_shrinkable = true;
+   }
+}
+
+static void
+drm_gem_shmem_remove_pages_from_shrinker(struct drm_gem_shmem_object *shmem)
+{
+   struct drm_gem_object *obj = &shmem->base;
+   struct drm_gem_shmem_shrinker *gem_shrinker = obj->dev->shmem_shrinker;
+   size_t page_count = obj->size >> PAGE_SHIFT;
+
+   if (shmem->pages_shrinkable) {
+   WARN_ON(gem_shrinker->shrinkable_count < page_count);
+   gem_shrinker->shrinkable_count -= page_count;
+   shmem->pages_shrinkable = false;
+   }
+}
+
+static void
+drm_gem_shmem_set_pages_state_locked(struct drm_gem_shmem_object *shmem,
+enum drm_gem_shmem_pages_state new_state)
+{
+   struct drm_gem_object *obj = &shmem->base;
+   struct drm_gem_shmem_shrinker *gem_shrinker = obj->dev->shmem_shrinker;
+
+   lockdep_assert_held(&gem_shrinker->lock);
+   lockdep_assert_held(&obj->resv->lock.base);
+
+   if (new_state >= DRM_GEM_SHMEM_PAGES_STATE_PINNED) {
+   if (drm_gem_shmem_is_evictable(shmem))
+   new_state = DRM_GEM_SHMEM_PAGES_STATE_EVICTABLE;
+
+   if (drm_gem_shmem_is_purgeable(shmem))
+   new_state = DRM_GEM_SHMEM_PAGES_STATE_PURGEABLE;
+
+   if (!shmem->pages)
+   new_state = DRM_GEM_SHMEM_PAGES_STATE_UNPINNED;
+
+   if (shmem->evicted)
+   new_state = DRM_GEM_SHMEM_PAGES_STATE_EVICTED;
+   }
+
+   if (shmem->pages_state == new_state)
+   return;
+
+   switch (new_state) {
+   case DRM_GEM_SHMEM_PAGES_STATE_UNPINNED:
+   case DRM_GEM_SHMEM_PAGES_STATE_PURGED:
+   drm_gem_shmem_remove_pages_from_shrinker(shmem);
+   list_del_init(&shmem->madv_list);
+   break;
+
+   case DRM_GEM_SHMEM_PAGES_STATE_PINNED:
+   drm_gem_shmem_remove_pages_from_shrinker(shmem);
+   list_move_tail(&shmem->madv_list, &gem_shrinker->lru_active);
+   break;
+
+   case DRM_GEM_SHMEM_PAGES_STATE_PURGEABLE:
+   drm_gem_shmem_add_pages_to_shrinker(shmem);
+   list_move_tail(&shmem->madv_list, &gem_shrinker->lru_purgeable);
+   break;
+
+   case DRM_GEM_SHMEM_PAGES_STATE_EVICTABLE:
+   drm_gem_shmem_add_pages_to_shrinker(shmem);
+   list_move_tail(&shmem->madv_list, &gem_shrinker->lru_evictable);
+   break;
+
+   case DRM_GEM_SHMEM_PAGES_STATE_EVICTED:
+   drm_gem_shmem_remove_

[PATCH v4 10/15] drm/shmem-helper: Take reservation lock instead of drm_gem_shmem locks

2022-04-17 Thread Dmitry Osipenko
Replace drm_gem_shmem locks with the reservation lock to make GEM
lockings more consistent.

Previously drm_gem_shmem_vmap() and drm_gem_shmem_get_pages() were
protected by separate locks, now it's the same lock, but it doesn't
make any difference for the current GEM SHMEM users. Only Panfrost
and Lima drivers use vmap() and they do it in the slow code paths,
hence there was no practical justification for the usage of separate
lock in the vmap().

Suggested-by: Daniel Vetter 
Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c  | 38 -
 drivers/gpu/drm/lima/lima_gem.c |  8 +++---
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 15 ++
 include/drm/drm_gem_shmem_helper.h  | 10 ---
 4 files changed, 31 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 30ee46348a99..3ecef571eff3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -86,8 +86,6 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, 
bool private)
if (ret)
goto err_release;
 
-   mutex_init(&shmem->pages_lock);
-   mutex_init(&shmem->vmap_lock);
INIT_LIST_HEAD(&shmem->madv_list);
 
if (!private) {
@@ -157,8 +155,6 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
WARN_ON(shmem->pages_use_count);
 
drm_gem_object_release(obj);
-   mutex_destroy(&shmem->pages_lock);
-   mutex_destroy(&shmem->vmap_lock);
kfree(shmem);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
@@ -209,11 +205,11 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object 
*shmem)
 
WARN_ON(shmem->base.import_attach);
 
-   ret = mutex_lock_interruptible(&shmem->pages_lock);
+   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
ret = drm_gem_shmem_get_pages_locked(shmem);
-   mutex_unlock(&shmem->pages_lock);
+   dma_resv_unlock(shmem->base.resv);
 
return ret;
 }
@@ -248,9 +244,9 @@ static void drm_gem_shmem_put_pages_locked(struct 
drm_gem_shmem_object *shmem)
  */
 void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem)
 {
-   mutex_lock(&shmem->pages_lock);
+   dma_resv_lock(shmem->base.resv, NULL);
drm_gem_shmem_put_pages_locked(shmem);
-   mutex_unlock(&shmem->pages_lock);
+   dma_resv_unlock(shmem->base.resv);
 }
 EXPORT_SYMBOL(drm_gem_shmem_put_pages);
 
@@ -310,7 +306,7 @@ static int drm_gem_shmem_vmap_locked(struct 
drm_gem_shmem_object *shmem,
} else {
pgprot_t prot = PAGE_KERNEL;
 
-   ret = drm_gem_shmem_get_pages(shmem);
+   ret = drm_gem_shmem_get_pages_locked(shmem);
if (ret)
goto err_zero_use;
 
@@ -360,11 +356,11 @@ int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem,
 {
int ret;
 
-   ret = mutex_lock_interruptible(&shmem->vmap_lock);
+   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
if (ret)
return ret;
ret = drm_gem_shmem_vmap_locked(shmem, map);
-   mutex_unlock(&shmem->vmap_lock);
+   dma_resv_unlock(shmem->base.resv);
 
return ret;
 }
@@ -385,7 +381,7 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
dma_buf_vunmap(obj->import_attach->dmabuf, map);
} else {
vunmap(shmem->vaddr);
-   drm_gem_shmem_put_pages(shmem);
+   drm_gem_shmem_put_pages_locked(shmem);
}
 
shmem->vaddr = NULL;
@@ -406,9 +402,11 @@ static void drm_gem_shmem_vunmap_locked(struct 
drm_gem_shmem_object *shmem,
 void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem,
  struct iosys_map *map)
 {
-   mutex_lock(&shmem->vmap_lock);
+   dma_resv_lock(shmem->base.resv, NULL);
drm_gem_shmem_vunmap_locked(shmem, map);
-   mutex_unlock(&shmem->vmap_lock);
+   dma_resv_unlock(shmem->base.resv);
+
+   drm_gem_shmem_update_purgeable_status(shmem);
 }
 EXPORT_SYMBOL(drm_gem_shmem_vunmap);
 
@@ -442,14 +440,14 @@ drm_gem_shmem_create_with_handle(struct drm_file 
*file_priv,
  */
 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
 {
-   mutex_lock(&shmem->pages_lock);
+   dma_resv_lock(shmem->base.resv, NULL);
 
if (shmem->madv >= 0)
shmem->madv = madv;
 
madv = shmem->madv;
 
-   mutex_unlock(&shmem->pages_lock);
+   dma_resv_unlock(shmem->base.resv);
 
return (madv >= 0);
 }
@@ -487,10 +485,10 @@ EXPORT_SYMBOL(drm_gem_shmem_purge_locked);
 
 bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
 {
-   if (!mutex_trylock(&shmem->pages_lock))
+   if (!dma_resv_trylock(shmem->base.resv))
return false;
drm_gem_shmem_purge_locked(shmem);
-   mutex

Re: [PATCH v6 2/2] arm64: dts: mt8192: Add node for the Mali GPU

2022-04-17 Thread Fei Shao
On Thu, Apr 14, 2022 at 10:53 AM Nick Fan  wrote:
>
> Add a basic GPU node for mt8192.
>
> Signed-off-by: Nick Fan 

Reviewed-by: Fei Shao 


Re: [PATCH 3/4] dt-bindings: drm/bridge: anx7625: Change bus-type to 7 (DPI)

2022-04-17 Thread Chen-Yu Tsai
Hi,

On Thu, Apr 14, 2022 at 10:27 AM Xin Ji  wrote:
>
> On Wed, Apr 13, 2022 at 04:28:51PM +0200, Robert Foss wrote:
> > On Sat, 9 Apr 2022 at 06:47, Xin Ji  wrote:
> > >
> > > On Mon, Apr 04, 2022 at 12:52:14PM -0500, Rob Herring wrote:
> > > > On Mon, Mar 28, 2022 at 08:09:54PM +0800, Xin Ji wrote:
> > > > > Change bus-type define for DPI.
> > > > >
> > > > > Fixes: a43661e7e819 ("dt-bindings:drm/bridge:anx7625:add vendor 
> > > > > define")
> > > > >
> > > > > Signed-off-by: Xin Ji 
> > > > > ---
> > > > >  .../devicetree/bindings/display/bridge/analogix,anx7625.yaml  | 4 
> > > > > ++--
> > > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git 
> > > > > a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > >  
> > > > > b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > index 0d38d6fe3983..4590186c4a0b 100644
> > > > > --- 
> > > > > a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > +++ 
> > > > > b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> > > > > @@ -106,7 +106,7 @@ properties:
> > > > >remote-endpoint: true
> > > > >
> > > > >bus-type:
> > > > > -enum: [1, 5]
> > > > > +enum: [7]
> > > >
> > > > Changing is an ABI break, but didn't we revert adding this?
> > > Hi Rob, sorry, what do you mean about ABI break? Do I need remove this
> > > patch in this serial? Or do I need revert patch
> > > https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.freedesktop.org%2Fpatch%2F462331%2F&data=04%7C01%7Cxji%40analogixsemi.com%7C10f5b0213f434592936008da1d59f566%7Cb099b0b4f26c4cf59a0fd5be9acab205%7C0%7C0%7C637854569490105386%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=vK0Vmb9S425kHZc1WurfnNhnoXDMbUGkkdY1PVnfS9g%3D&reserved=0,
> > >  I don't know how to do
> > > it.
> > >
> >
> > I contributed to the confusion about this, let's see if we can clear it up.
> >
> > An issue was found related to which enum values were used to represent
> > what late in the last release cycle. As a result a revert[1] patch for
> > everything touching bus-type in anx7625 was merged.
> >
> > This patch, does not apply to drm-misc-next due to the revert, and if
> > Xin Ji rebases his work on the drm-misc-next there should be no
> > ABI-change as this patch when fixed up will introduce bus-type to the
> > nax7625 ABI.
> >
> > Xin: Does this make sense to you?
> Hi Robert Foss, yes, my work is based on drm-misc-next, all I can do,
> just make a fix up patch(this patch) to change the bus-type define.

The revert was applied to the soc tree and merged into Linus's tree
in v5.17-rc8. It was not present in drm-misc-next until April 5 with
commit 9cbbd694a58b ("Merge drm/drm-next into drm-misc-next").

So please fetch the latest drm-misc-next, rebase your patches on top, and
resend.


Thanks
ChenYu