diff mbox

[PATCHv2,45/45] drm: omapdrm: add lock for fb pinning

Message ID 1433408582-9828-46-git-send-email-tomi.valkeinen@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomi Valkeinen June 4, 2015, 9:03 a.m. UTC
Before atomic modesetting omap_framebuffer_pin() and
omap_framebuffer_unpin() were always called with modesetting locks
taken. With atomic modesetting support this is no longer the case, and
we need locking to protect the pin_count and the paddr, as multiple
threads may pin the same fb concurrently.

This patch adds a mutex to struct omap_framebuffer, and uses it in
omap_framebuffer_pin() and omap_framebuffer_unpin().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_fb.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

Comments

Laurent Pinchart June 6, 2015, 4:30 a.m. UTC | #1
Hi Tomi,

Thank you for the patch.

On Thursday 04 June 2015 12:03:02 Tomi Valkeinen wrote:
> Before atomic modesetting omap_framebuffer_pin() and
> omap_framebuffer_unpin() were always called with modesetting locks
> taken. With atomic modesetting support this is no longer the case, and
> we need locking to protect the pin_count and the paddr, as multiple
> threads may pin the same fb concurrently.
> 
> This patch adds a mutex to struct omap_framebuffer, and uses it in
> omap_framebuffer_pin() and omap_framebuffer_unpin().
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  drivers/gpu/drm/omapdrm/omap_fb.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c
> b/drivers/gpu/drm/omapdrm/omap_fb.c index e505140a8782..0b967e76df1a 100644
> --- a/drivers/gpu/drm/omapdrm/omap_fb.c
> +++ b/drivers/gpu/drm/omapdrm/omap_fb.c
> @@ -89,6 +89,8 @@ struct omap_framebuffer {
>  	int pin_count;
>  	const struct format *format;
>  	struct plane planes[4];
> +	/* lock for pinning (pin_count and planes.paddr) */
> +	struct mutex lock;
>  };
> 
>  static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
> @@ -250,8 +252,11 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
>  	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
>  	int ret, i, n = drm_format_num_planes(fb->pixel_format);
> 
> +	mutex_lock(&omap_fb->lock);
> +
>  	if (omap_fb->pin_count > 0) {
>  		omap_fb->pin_count++;
> +		mutex_unlock(&omap_fb->lock);
>  		return 0;
>  	}
> 
> @@ -265,6 +270,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
> 
>  	omap_fb->pin_count++;
> 
> +	mutex_unlock(&omap_fb->lock);
> +
>  	return 0;
> 
>  fail:
> @@ -274,6 +281,8 @@ fail:
>  		plane->paddr = 0;
>  	}
> 
> +	mutex_unlock(&omap_fb->lock);
> +
>  	return ret;
>  }
> 
> @@ -283,10 +292,14 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
> struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
>  	int ret, i, n = drm_format_num_planes(fb->pixel_format);
> 
> +	mutex_lock(&omap_fb->lock);
> +
>  	omap_fb->pin_count--;
> 
> -	if (omap_fb->pin_count > 0)
> +	if (omap_fb->pin_count > 0) {
> +		mutex_unlock(&omap_fb->lock);
>  		return 0;
> +	}
> 
>  	for (i = 0; i < n; i++) {
>  		struct plane *plane = &omap_fb->planes[i];
> @@ -296,9 +309,12 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
>  		plane->paddr = 0;
>  	}
> 
> +	mutex_unlock(&omap_fb->lock);
> +
>  	return 0;
> 
>  fail:
> +	mutex_unlock(&omap_fb->lock);
>  	return ret;
>  }
> 
> @@ -411,6 +427,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct
> drm_device *dev,
> 
>  	fb = &omap_fb->base;
>  	omap_fb->format = format;
> +	mutex_init(&omap_fb->lock);
> 
>  	for (i = 0; i < n; i++) {
>  		struct plane *plane = &omap_fb->planes[i];
diff mbox

Patch

diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index e505140a8782..0b967e76df1a 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -89,6 +89,8 @@  struct omap_framebuffer {
 	int pin_count;
 	const struct format *format;
 	struct plane planes[4];
+	/* lock for pinning (pin_count and planes.paddr) */
+	struct mutex lock;
 };
 
 static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -250,8 +252,11 @@  int omap_framebuffer_pin(struct drm_framebuffer *fb)
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
 	int ret, i, n = drm_format_num_planes(fb->pixel_format);
 
+	mutex_lock(&omap_fb->lock);
+
 	if (omap_fb->pin_count > 0) {
 		omap_fb->pin_count++;
+		mutex_unlock(&omap_fb->lock);
 		return 0;
 	}
 
@@ -265,6 +270,8 @@  int omap_framebuffer_pin(struct drm_framebuffer *fb)
 
 	omap_fb->pin_count++;
 
+	mutex_unlock(&omap_fb->lock);
+
 	return 0;
 
 fail:
@@ -274,6 +281,8 @@  fail:
 		plane->paddr = 0;
 	}
 
+	mutex_unlock(&omap_fb->lock);
+
 	return ret;
 }
 
@@ -283,10 +292,14 @@  int omap_framebuffer_unpin(struct drm_framebuffer *fb)
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
 	int ret, i, n = drm_format_num_planes(fb->pixel_format);
 
+	mutex_lock(&omap_fb->lock);
+
 	omap_fb->pin_count--;
 
-	if (omap_fb->pin_count > 0)
+	if (omap_fb->pin_count > 0) {
+		mutex_unlock(&omap_fb->lock);
 		return 0;
+	}
 
 	for (i = 0; i < n; i++) {
 		struct plane *plane = &omap_fb->planes[i];
@@ -296,9 +309,12 @@  int omap_framebuffer_unpin(struct drm_framebuffer *fb)
 		plane->paddr = 0;
 	}
 
+	mutex_unlock(&omap_fb->lock);
+
 	return 0;
 
 fail:
+	mutex_unlock(&omap_fb->lock);
 	return ret;
 }
 
@@ -411,6 +427,7 @@  struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 
 	fb = &omap_fb->base;
 	omap_fb->format = format;
+	mutex_init(&omap_fb->lock);
 
 	for (i = 0; i < n; i++) {
 		struct plane *plane = &omap_fb->planes[i];