summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/rcar-du/rcar_du_plane.h
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-02-25 18:27:19 +0200
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-03-03 16:16:30 +0200
commit5ee5a81df57ea3a19a5e306fdf8244ab696c8916 (patch)
tree3ad94723cd456fccf232536326ba303aad9a3595 /drivers/gpu/drm/rcar-du/rcar_du_plane.h
parent48596d502e93a62fd1adab42b0a923709cd1c115 (diff)
downloadlinux-5ee5a81df57ea3a19a5e306fdf8244ab696c8916.tar.gz
drm: rcar-du: Fix race condition in hardware plane allocator
The plane allocator has been inherently racy since the beginning of the transition to atomic updates, as the allocator lock is released between free plane check (at .atomic_check() time) and the reservation (at .atomic_update() time). To fix it, create a new allocator solely based on the atomic plane states without keeping any external state and perform allocation in the .atomic_check() handler. The core idea is to replace the free planes bitmask with a collective knowledge based on the allocated hardware plane(s) for each KMS plane. The allocator then loops over all plane states to compute the free planes bitmask, allocates hardware planes based on that bitmask, and stores the result back in the plane states. For this to work we need to access the current state of planes not touched by the atomic update. To ensure that it won't be modified, we need to lock all planes using drm_atomic_get_plane_state(). This effectively serializes atomic updates from .atomic_check() up to completion, either when swapping the states if the check step has succeeded, or when freeing the states if the check step has failed. Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/rcar-du/rcar_du_plane.h')
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 0941c4830edd..abff0ebeb195 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -14,8 +14,6 @@
#ifndef __RCAR_DU_PLANE_H__
#define __RCAR_DU_PLANE_H__
-#include <linux/mutex.h>
-
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
@@ -33,13 +31,15 @@ struct rcar_du_group;
struct rcar_du_plane {
struct drm_plane plane;
struct rcar_du_group *group;
- int hwindex; /* 0-based, -1 means unused */
};
+static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
+{
+ return container_of(plane, struct rcar_du_plane, plane);
+}
+
struct rcar_du_planes {
struct rcar_du_plane planes[RCAR_DU_NUM_KMS_PLANES];
- unsigned int free;
- struct mutex lock;
struct drm_property *alpha;
struct drm_property *colorkey;
@@ -50,6 +50,7 @@ struct rcar_du_plane_state {
struct drm_plane_state state;
const struct rcar_du_format_info *format;
+ int hwindex; /* 0-based, -1 means unused */
unsigned int alpha;
unsigned int colorkey;