[PATCH 6/6] drm/udl: Move vmap out of commit tail

2021-02-04 Thread Thomas Zimmermann
Vmap operations may acquire the dmabuf reservation lock, which is not
allowed within atomic commit-tail functions. Therefore move vmap and
vunmap from the damage handler into prepare_fb and cleanup_fb callbacks.

The mapping is provided as GEM shadow-buffered plane. The functions in
the commit tail use the pre-established mapping for damage handling.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/udl/udl_modeset.c | 34 ---
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
b/drivers/gpu/drm/udl/udl_modeset.c
index 9d34ec9d03f6..8d98bf69d075 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -266,18 +267,17 @@ static int udl_aligned_damage_clip(struct drm_rect *clip, 
int x, int y,
return 0;
 }
 
-static int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
-int width, int height)
+static int udl_handle_damage(struct drm_framebuffer *fb, const struct 
dma_buf_map *map,
+int x, int y, int width, int height)
 {
struct drm_device *dev = fb->dev;
struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
+   void *vaddr = map->vaddr; /* TODO: Use mapping abstraction properly */
int i, ret, tmp_ret;
char *cmd;
struct urb *urb;
struct drm_rect clip;
int log_bpp;
-   struct dma_buf_map map;
-   void *vaddr;
 
ret = udl_log_cpp(fb->format->cpp[0]);
if (ret < 0)
@@ -297,17 +297,10 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
return ret;
}
 
-   ret = drm_gem_shmem_vmap(fb->obj[0], );
-   if (ret) {
-   DRM_ERROR("failed to vmap fb\n");
-   goto out_dma_buf_end_cpu_access;
-   }
-   vaddr = map.vaddr; /* TODO: Use mapping abstraction properly */
-
urb = udl_get_urb(dev);
if (!urb) {
ret = -ENOMEM;
-   goto out_drm_gem_shmem_vunmap;
+   goto out_dma_buf_end_cpu_access;
}
cmd = urb->transfer_buffer;
 
@@ -320,7 +313,7 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
   , byte_offset, dev_byte_offset,
   byte_width);
if (ret)
-   goto out_drm_gem_shmem_vunmap;
+   goto out_dma_buf_end_cpu_access;
}
 
if (cmd > (char *)urb->transfer_buffer) {
@@ -336,8 +329,6 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
 
ret = 0;
 
-out_drm_gem_shmem_vunmap:
-   drm_gem_shmem_vunmap(fb->obj[0], );
 out_dma_buf_end_cpu_access:
if (import_attach) {
tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf,
@@ -375,6 +366,7 @@ udl_simple_display_pipe_enable(struct 
drm_simple_display_pipe *pipe,
struct drm_framebuffer *fb = plane_state->fb;
struct udl_device *udl = to_udl(dev);
struct drm_display_mode *mode = _state->mode;
+   struct drm_shadow_plane_state *shadow_plane_state = 
to_drm_shadow_plane_state(plane_state);
char *buf;
char *wrptr;
int color_depth = UDL_COLOR_DEPTH_16BPP;
@@ -400,7 +392,7 @@ udl_simple_display_pipe_enable(struct 
drm_simple_display_pipe *pipe,
 
udl->mode_buf_len = wrptr - buf;
 
-   udl_handle_damage(fb, 0, 0, fb->width, fb->height);
+   udl_handle_damage(fb, _plane_state->map[0], 0, 0, fb->width, 
fb->height);
 
if (!crtc_state->mode_changed)
return;
@@ -435,6 +427,7 @@ udl_simple_display_pipe_update(struct 
drm_simple_display_pipe *pipe,
   struct drm_plane_state *old_plane_state)
 {
struct drm_plane_state *state = pipe->plane.state;
+   struct drm_shadow_plane_state *shadow_plane_state = 
to_drm_shadow_plane_state(state);
struct drm_framebuffer *fb = state->fb;
struct drm_rect rect;
 
@@ -442,17 +435,16 @@ udl_simple_display_pipe_update(struct 
drm_simple_display_pipe *pipe,
return;
 
if (drm_atomic_helper_damage_merged(old_plane_state, state, ))
-   udl_handle_damage(fb, rect.x1, rect.y1, rect.x2 - rect.x1,
- rect.y2 - rect.y1);
+   udl_handle_damage(fb, _plane_state->map[0], rect.x1, 
rect.y1,
+ rect.x2 - rect.x1, rect.y2 - rect.y1);
 }
 
-static const
-struct drm_simple_display_pipe_funcs udl_simple_display_pipe_funcs = {
+static const struct drm_simple_display_pipe_funcs 
udl_simple_display_pipe_funcs = {
.mode_valid = udl_simple_display_pipe_mode_valid,
.enable = udl_simple_display_pipe_enable,
.disable = udl_simple_display_pipe_disable,
   

[PATCH 6/6] drm/udl: Move vmap out of commit tail

2021-02-03 Thread Thomas Zimmermann
Vmap operations may acquire the dmabuf reservation lock, which is not
allowed within atomic commit-tail functions. Therefore move vmap and
vunmap from the damage handler into prepare_fb and cleanup_fb callbacks.

The mapping is provided as GEM SHMEM shadow plane. The enable and prepare
callbacks use the established mapping for damage handling.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/udl/Kconfig   |  1 +
 drivers/gpu/drm/udl/udl_modeset.c | 36 +--
 2 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig
index 1f497d8f1ae5..1b46d93ca61c 100644
--- a/drivers/gpu/drm/udl/Kconfig
+++ b/drivers/gpu/drm/udl/Kconfig
@@ -5,6 +5,7 @@ config DRM_UDL
depends on USB
depends on USB_ARCH_HAS_HCD
select DRM_GEM_SHMEM_HELPER
+   select DRM_GEM_SHMEM_KMS_HELPER
select DRM_KMS_HELPER
help
  This is a KMS driver for the USB displaylink video adapters.
diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
b/drivers/gpu/drm/udl/udl_modeset.c
index 9d34ec9d03f6..974dffe86a44 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -266,18 +267,17 @@ static int udl_aligned_damage_clip(struct drm_rect *clip, 
int x, int y,
return 0;
 }
 
-static int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
-int width, int height)
+static int udl_handle_damage(struct drm_framebuffer *fb, const struct 
dma_buf_map *map,
+int x, int y, int width, int height)
 {
struct drm_device *dev = fb->dev;
struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
+   void *vaddr = map->vaddr; /* TODO: Use mapping abstraction properly */
int i, ret, tmp_ret;
char *cmd;
struct urb *urb;
struct drm_rect clip;
int log_bpp;
-   struct dma_buf_map map;
-   void *vaddr;
 
ret = udl_log_cpp(fb->format->cpp[0]);
if (ret < 0)
@@ -297,17 +297,10 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
return ret;
}
 
-   ret = drm_gem_shmem_vmap(fb->obj[0], );
-   if (ret) {
-   DRM_ERROR("failed to vmap fb\n");
-   goto out_dma_buf_end_cpu_access;
-   }
-   vaddr = map.vaddr; /* TODO: Use mapping abstraction properly */
-
urb = udl_get_urb(dev);
if (!urb) {
ret = -ENOMEM;
-   goto out_drm_gem_shmem_vunmap;
+   goto out_dma_buf_end_cpu_access;
}
cmd = urb->transfer_buffer;
 
@@ -320,7 +313,7 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
   , byte_offset, dev_byte_offset,
   byte_width);
if (ret)
-   goto out_drm_gem_shmem_vunmap;
+   goto out_dma_buf_end_cpu_access;
}
 
if (cmd > (char *)urb->transfer_buffer) {
@@ -336,8 +329,6 @@ static int udl_handle_damage(struct drm_framebuffer *fb, 
int x, int y,
 
ret = 0;
 
-out_drm_gem_shmem_vunmap:
-   drm_gem_shmem_vunmap(fb->obj[0], );
 out_dma_buf_end_cpu_access:
if (import_attach) {
tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf,
@@ -375,6 +366,8 @@ udl_simple_display_pipe_enable(struct 
drm_simple_display_pipe *pipe,
struct drm_framebuffer *fb = plane_state->fb;
struct udl_device *udl = to_udl(dev);
struct drm_display_mode *mode = _state->mode;
+   struct drm_gem_shmem_shadow_plane_state *shadow_plane_state =
+   to_drm_gem_shmem_shadow_plane_state(plane_state);
char *buf;
char *wrptr;
int color_depth = UDL_COLOR_DEPTH_16BPP;
@@ -400,7 +393,7 @@ udl_simple_display_pipe_enable(struct 
drm_simple_display_pipe *pipe,
 
udl->mode_buf_len = wrptr - buf;
 
-   udl_handle_damage(fb, 0, 0, fb->width, fb->height);
+   udl_handle_damage(fb, _plane_state->map[0], 0, 0, fb->width, 
fb->height);
 
if (!crtc_state->mode_changed)
return;
@@ -435,6 +428,8 @@ udl_simple_display_pipe_update(struct 
drm_simple_display_pipe *pipe,
   struct drm_plane_state *old_plane_state)
 {
struct drm_plane_state *state = pipe->plane.state;
+   struct drm_gem_shmem_shadow_plane_state *shadow_plane_state =
+   to_drm_gem_shmem_shadow_plane_state(state);
struct drm_framebuffer *fb = state->fb;
struct drm_rect rect;
 
@@ -442,17 +437,16 @@ udl_simple_display_pipe_update(struct 
drm_simple_display_pipe *pipe,
return;
 
if (drm_atomic_helper_damage_merged(old_plane_state, state, ))
-   udl_handle_damage(fb, rect.x1, rect.y1, rect.x2 -