Commit 798ce3fe authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/udl: Begin/end access to imported buffers in damage-handler

The damage-handler code now invokes dma_buf_{begin,end}_access()
for imported buffers. These calls were missing from the page-flip
and modesetting code paths. The patch also fixes an bug in the
original where an error code was overwritten by the result of
dma_buf_end_cpu_access().

v2:
	* only return an error code from dma_buf_end_cpu_access() if
	  no other error code has been set before
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarEmil Velikov <emil.velikov@collabora.com>
Acked-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-7-tzimmermann@suse.de
parent cd45e30a
...@@ -92,7 +92,8 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, ...@@ -92,7 +92,8 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
{ {
struct drm_device *dev = fb->dev; struct drm_device *dev = fb->dev;
struct udl_device *udl = to_udl(dev); struct udl_device *udl = to_udl(dev);
int i, ret; struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach;
int i, ret, tmp_ret;
char *cmd; char *cmd;
struct urb *urb; struct urb *urb;
struct drm_rect clip; struct drm_rect clip;
...@@ -117,15 +118,22 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, ...@@ -117,15 +118,22 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) else if ((clip.x2 > fb->width) || (clip.y2 > fb->height))
return -EINVAL; return -EINVAL;
if (import_attach) {
ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
DMA_FROM_DEVICE);
if (ret)
return ret;
}
vaddr = drm_gem_shmem_vmap(fb->obj[0]); vaddr = drm_gem_shmem_vmap(fb->obj[0]);
if (IS_ERR(vaddr)) { if (IS_ERR(vaddr)) {
DRM_ERROR("failed to vmap fb\n"); DRM_ERROR("failed to vmap fb\n");
return 0; goto out_dma_buf_end_cpu_access;
} }
urb = udl_get_urb(dev); urb = udl_get_urb(dev);
if (!urb) if (!urb)
goto out; goto out_drm_gem_shmem_vunmap;
cmd = urb->transfer_buffer; cmd = urb->transfer_buffer;
for (i = clip.y1; i < clip.y2; i++) { for (i = clip.y1; i < clip.y2; i++) {
...@@ -136,7 +144,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, ...@@ -136,7 +144,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr,
&cmd, byte_offset, dev_byte_offset, &cmd, byte_offset, dev_byte_offset,
byte_width)) byte_width))
goto out; goto out_drm_gem_shmem_vunmap;
} }
if (cmd > (char *) urb->transfer_buffer) { if (cmd > (char *) urb->transfer_buffer) {
...@@ -149,10 +157,19 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, ...@@ -149,10 +157,19 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y,
} else } else
udl_urb_completion(urb); udl_urb_completion(urb);
out: ret = 0;
out_drm_gem_shmem_vunmap:
drm_gem_shmem_vunmap(fb->obj[0], vaddr); drm_gem_shmem_vunmap(fb->obj[0], vaddr);
out_dma_buf_end_cpu_access:
if (import_attach) {
tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf,
DMA_FROM_DEVICE);
if (tmp_ret && !ret)
ret = tmp_ret; /* only update ret if not set yet */
}
return 0; return ret;
} }
static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
...@@ -162,7 +179,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, ...@@ -162,7 +179,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
unsigned num_clips) unsigned num_clips)
{ {
struct udl_device *udl = fb->dev->dev_private; struct udl_device *udl = fb->dev->dev_private;
struct dma_buf_attachment *import_attach;
int i; int i;
int ret = 0; int ret = 0;
...@@ -175,15 +191,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, ...@@ -175,15 +191,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
} }
spin_unlock(&udl->active_fb_16_lock); spin_unlock(&udl->active_fb_16_lock);
import_attach = fb->obj[0]->import_attach;
if (import_attach) {
ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
DMA_FROM_DEVICE);
if (ret)
goto unlock;
}
for (i = 0; i < num_clips; i++) { for (i = 0; i < num_clips; i++) {
ret = udl_handle_damage(fb, clips[i].x1, clips[i].y1, ret = udl_handle_damage(fb, clips[i].x1, clips[i].y1,
clips[i].x2 - clips[i].x1, clips[i].x2 - clips[i].x1,
...@@ -192,10 +199,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, ...@@ -192,10 +199,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
break; break;
} }
if (import_attach)
ret = dma_buf_end_cpu_access(import_attach->dmabuf,
DMA_FROM_DEVICE);
unlock: unlock:
drm_modeset_unlock_all(fb->dev); drm_modeset_unlock_all(fb->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment