All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers
@ 2016-05-29 18:34 Daniel Vetter
  2016-05-29 18:34 ` [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
                   ` (28 more replies)
  0 siblings, 29 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:34 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

So I finally unlazied and implemented generic nonblocking atomic commit support
in the atomic helpers. Still an early draft, but stopped being a fireworks show
on i915 at least. Rockchip still oopses somewhere, virtio conversion is entirely
untested. Same for arc/hdlcd/fsl-du/sun4i. All these untested drivers must be
converted since they've been a bit too lazy in their atomic implementations and
simply didn't bother implementing nonblocking.

The main patch adding the helpers explains the design, I just want to highlight
one key aspect: This code fully relies on correct handling of crtc_state->event,
drivers which don't get this right will fall over. To avoid too much trouble the
helpers all have a 10s timeout, in case of broken drivers. This is both good -
hopefully no more atomic drivers that just outright forget to implement drm
event handling. And also a bit annoying for getting this series in since the
above mentioned 5 atomic drivers all look like they haven't been properly tested
with events.

Stuff left to do:
- Debug at least rockchip&virtio I'd say to make sure it works there flawlessly.
  Would be good to also convert some other drivers.
- Get as much debugging on the other 4 drivers which have to be converted. Otoh
  they already have a broken atomic implementation in-tree, so me.
- Kerneldoc for a bunch of functions is still missing, plus the updated overview
  section for nonblocking commits.
- Bugfixing, but I hope that the helpers themselves are solid now.

Cheers, Daniel

Daniel Vetter (25):
  drm/atomic-helper: use for_each_*_in_state more
  drm/i915: Use drm_atomic_get_existing_plane_state
  drm/msm: Use for_each_*_in_state
  drm/rcar-du: Use for_each_*_in_state
  drm/vc4: Use for_each_plane_in_state
  drm/atomic: Add __drm_atomic_get_current_plane_state
  drm/exynos: Use for_each_crtc_in_state
  drm: Consolidate connector arrays in drm_atomic_state
  drm: Consolidate plane arrays in drm_atomic_state
  drm: Consolidate crtc arrays in drm_atomic_state
  drm/atomic-helper: Massage swap_state signature somewhat
  drm/arc: Nuke event_list
  drm/arc: Actually bother with handling atomic events.
  drm/arc: Implement nonblocking commit correctly
  drm/hdlcd: Use helper support for nonblocking commits
  drm/fsl-du: Implement some semblance of vblank event handling
  drm/hisilicon: Implement some semblance of vblank event handling
  drm/sun4i: Implement some semblance of vblank event handling
  drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
  drm/atomic-helper: nonblocking commit support
  drm/i915: Signal drm events for atomic
  drm/i915: Roll out the helper nonblock tracking
  drm/rockchip: convert to helper nonblocking atomic commit
  drm/rockchip: Nuke pending event handling in preclose
  drm/virtio: Don't reinvent a flipping wheel

Gustavo Padovan (1):
  drm/fence: add fence to drm_pending_event

 drivers/gpu/drm/arc/arcpgu.h                    |   1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c               |  19 +-
 drivers/gpu/drm/arc/arcpgu_drv.c                |  27 +-
 drivers/gpu/drm/arm/hdlcd_drv.c                 |   8 +-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c    |   2 +-
 drivers/gpu/drm/drm_atomic.c                    | 102 +++---
 drivers/gpu/drm/drm_atomic_helper.c             | 421 ++++++++++++++++++++----
 drivers/gpu/drm/drm_crtc.c                      |   3 +
 drivers/gpu/drm/drm_fops.c                      |  22 +-
 drivers/gpu/drm/exynos/exynos_drm_drv.c         |  10 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c      |  23 +-
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c |  20 +-
 drivers/gpu/drm/i915/intel_atomic.c             |   6 +-
 drivers/gpu/drm/i915/intel_display.c            |  25 +-
 drivers/gpu/drm/i915/intel_sprite.c             |  14 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c          |   2 +-
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c         |  20 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c        |  10 +-
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c         |  12 +-
 drivers/gpu/drm/msm/msm_atomic.c                |  37 +--
 drivers/gpu/drm/nouveau/nouveau_usif.c          |   1 -
 drivers/gpu/drm/omapdrm/omap_drv.c              |   2 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c           |  10 +-
 drivers/gpu/drm/rcar-du/rcar_du_plane.c         |  20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c     |  25 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h     |  11 -
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  73 +---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c     |  35 +-
 drivers/gpu/drm/sti/sti_drv.c                   |   2 +-
 drivers/gpu/drm/sun4i/sun4i_crtc.c              |  12 +
 drivers/gpu/drm/tegra/drm.c                     |   2 +-
 drivers/gpu/drm/vc4/vc4_crtc.c                  |  11 +-
 drivers/gpu/drm/vc4/vc4_drv.h                   |   2 +-
 drivers/gpu/drm/vc4/vc4_kms.c                   |  12 +-
 drivers/gpu/drm/vc4/vc4_plane.c                 |   5 +-
 drivers/gpu/drm/virtio/virtgpu_display.c        |  48 +--
 include/drm/drmP.h                              |   4 +-
 include/drm/drm_atomic.h                        |  79 ++++-
 include/drm/drm_atomic_helper.h                 |  12 +-
 include/drm/drm_crtc.h                          | 149 ++++++++-
 include/drm/drm_modeset_helper_vtables.h        |  36 ++
 41 files changed, 847 insertions(+), 488 deletions(-)

-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
@ 2016-05-29 18:34 ` Daniel Vetter
  2016-05-30 12:17   ` Maarten Lankhorst
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:34 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This avois leaking drm_atomic_state internals into the helpers. The
only place where this still happens after this patch is drm_atomic_helper_swap_state().
It's unavoidable there, and maybe a good indicator we should actually
move that function into drm_atomic.c.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic_helper.c | 47 +++++++++++++------------------------
 1 file changed, 16 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index ddfa0d120e39..464541c87c40 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -611,7 +611,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
 		if (!funcs || !funcs->atomic_check)
 			continue;
 
-		ret = funcs->atomic_check(crtc, state->crtc_states[i]);
+		ret = funcs->atomic_check(crtc, crtc_state);
 		if (ret) {
 			DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
 					 crtc->base.id, crtc->name);
@@ -1249,16 +1249,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 				     struct drm_atomic_state *state)
 {
-	int nplanes = dev->mode_config.num_total_plane;
-	int ret, i;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
+	int ret, i, j;
 
-	for (i = 0; i < nplanes; i++) {
+	for_each_plane_in_state(state, plane, plane_state, i) {
 		const struct drm_plane_helper_funcs *funcs;
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
 
 		funcs = plane->helper_private;
 
@@ -1272,12 +1268,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
 	return 0;
 
 fail:
-	for (i--; i >= 0; i--) {
+	for_each_plane_in_state(state, plane, plane_state, j) {
 		const struct drm_plane_helper_funcs *funcs;
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
 
-		if (!plane)
+		if (j >= i)
 			continue;
 
 		funcs = plane->helper_private;
@@ -1564,35 +1558,26 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 				  struct drm_atomic_state *state)
 {
 	int i;
+	struct drm_connector *connector;
+	struct drm_connector_state *conn_state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 
-	for (i = 0; i < state->num_connector; i++) {
-		struct drm_connector *connector = state->connectors[i];
-
-		if (!connector)
-			continue;
-
+	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
 		swap(state->connector_states[i], connector->state);
 		connector->state->state = NULL;
 	}
 
-	for (i = 0; i < dev->mode_config.num_crtc; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-
-		if (!crtc)
-			continue;
-
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		crtc->state->state = state;
 		swap(state->crtc_states[i], crtc->state);
 		crtc->state->state = NULL;
 	}
 
-	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
-
-		if (!plane)
-			continue;
-
+	for_each_plane_in_state(state, plane, plane_state, i) {
 		plane->state->state = state;
 		swap(state->plane_states[i], plane->state);
 		plane->state->state = NULL;
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
  2016-05-29 18:34 ` [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
@ 2016-05-29 18:34 ` Daniel Vetter
  2016-05-30 13:10   ` [Intel-gfx] " Maarten Lankhorst
  2016-05-29 18:35 ` [PATCH 03/26] drm/msm: Use for_each_*_in_state Daniel Vetter
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:34 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to encapsulate the drm_atomic_state internals.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 50ff90aea721..3e6d9ff8840a 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 				continue;
 			}
 
-			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
+			plane_state = to_intel_plane_state(
+				drm_atomic_get_existing_plane_state(drm_state,
+								    plane));
 			scaler_id = &plane_state->scaler_id;
 		}
 
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 03/26] drm/msm: Use for_each_*_in_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
  2016-05-29 18:34 ` [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 04/26] drm/rcar-du: " Daniel Vetter
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to hide drm_atomic_state internals

Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c    | 20 +++++++----------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c    | 12 +++-------
 drivers/gpu/drm/msm/msm_atomic.c           | 35 ++++++++++--------------------
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c |  1 +
 4 files changed, 23 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 67442d50a6c2..f145d256e332 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -106,31 +106,27 @@ out:
 static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-	int i, ncrtcs = state->dev->mode_config.num_crtc;
+	int i;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 
 	mdp4_enable(mdp4_kms);
 
 	/* see 119ecb7fd */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		drm_crtc_vblank_get(crtc);
-	}
 }
 
 static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
-	int i, ncrtcs = state->dev->mode_config.num_crtc;
+	int i;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 
 	/* see 119ecb7fd */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		drm_crtc_vblank_put(crtc);
-	}
 
 	mdp4_disable(mdp4_kms);
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 484b4d15e71d..f0c285b1c027 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
 {
 	int i;
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-	int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
-
-	for (i = 0; i < nplanes; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *plane_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 
+	for_each_plane_in_state(state, plane, plane_state, i)
 		mdp5_plane_complete_commit(plane, plane_state);
-	}
 
 	mdp5_disable(mdp5_kms);
 }
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e3892c263f27..9c0e4261dbba 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
 		struct drm_atomic_state *old_state)
 {
 	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	struct msm_drm_private *priv = old_state->dev->dev_private;
 	struct msm_kms *kms = priv->kms;
-	int ncrtcs = old_state->dev->mode_config.num_crtc;
 	int i;
 
-	for (i = 0; i < ncrtcs; i++) {
-		crtc = old_state->crtcs[i];
-
-		if (!crtc)
-			continue;
-
+	for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
 		if (!crtc->state->enable)
 			continue;
 
@@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
 		struct drm_atomic_state *state, bool nonblock)
 {
 	struct msm_drm_private *priv = dev->dev_private;
-	int nplanes = dev->mode_config.num_total_plane;
-	int ncrtcs = dev->mode_config.num_crtc;
 	struct msm_commit *c;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_plane *plane;
+	struct drm_plane_state *plane_state;
 	int i, ret;
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
 	/*
 	 * Figure out what crtcs we have:
 	 */
-	for (i = 0; i < ncrtcs; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
-		if (!crtc)
-			continue;
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
 		c->crtc_mask |= (1 << drm_crtc_index(crtc));
-	}
 
 	/*
 	 * Figure out what fence to wait for:
 	 */
-	for (i = 0; i < nplanes; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *new_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
-
-		if ((plane->state->fb != new_state->fb) && new_state->fb) {
-			struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0);
+	for_each_plane_in_state(state, plane, plane_state, i) {
+		if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
+			struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
 			struct msm_gem_object *msm_obj = to_msm_bo(obj);
 
-			new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
+			plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
 		}
 	}
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 755cfdba61cd..03913b483506 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -197,6 +197,7 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_stat
 	struct drm_crtc *crtc;
 	int i, ret;
 
+
 	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
 		/* No one cares about the old state, so abuse it for tracking
 		 * and store whether we hold a vblank reference (and should do a
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (2 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 03/26] drm/msm: Use for_each_*_in_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-30  9:18   ` Laurent Pinchart
  2016-05-29 18:35 ` [PATCH 05/26] drm/vc4: Use for_each_plane_in_state Daniel Vetter
                   ` (24 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	Daniel Vetter

We want to hide drm_atomic_state internals better.

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
 drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index e70a4f33d970..f315c55c1f65 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 {
 	struct rcar_du_device *rcdu = dev->dev_private;
 	struct rcar_du_commit *commit;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	unsigned int i;
 	int ret;
 
@@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 	/* Wait until all affected CRTCs have completed previous commits and
 	 * mark them as pending.
 	 */
-	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-		if (state->crtcs[i])
-			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-	}
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
+		commit->crtcs |= 1 << drm_crtc_index(crtc);
 
 	spin_lock(&rcdu->commit.wait.lock);
 	ret = wait_event_interruptible_locked(rcdu->commit.wait,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index d445e67f78e1..bfe31ca870cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
 	bool needs_realloc = false;
 	unsigned int groups = 0;
 	unsigned int i;
+	struct drm_plane *drm_plane;
+	struct drm_plane_state *drm_plane_state;
 
 	/* Check if hardware planes need to be reallocated. */
-	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane *plane;
 		unsigned int index;
 
-		if (!state->planes[i])
-			continue;
-
-		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_plane_state(state->plane_states[i]);
+		plane = to_rcar_plane(drm_plane);
+		plane_state = to_rcar_plane_state(drm_plane_state);
 
 		dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
 			plane->group->index, plane - plane->group->planes);
@@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
 	}
 
 	/* Reallocate hardware planes for each plane that needs it. */
-	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
+	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
 		struct rcar_du_plane_state *plane_state;
 		struct rcar_du_plane *plane;
 		unsigned int crtc_planes;
 		unsigned int free;
 		int idx;
 
-		if (!state->planes[i])
-			continue;
-
-		plane = to_rcar_plane(state->planes[i]);
-		plane_state = to_rcar_plane_state(state->plane_states[i]);
+		plane = to_rcar_plane(drm_plane);
+		plane_state = to_rcar_plane_state(drm_plane_state);
 
 		dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
 			plane->group->index, plane - plane->group->planes);
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 05/26] drm/vc4: Use for_each_plane_in_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (3 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 04/26] drm/rcar-du: " Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

We want to hide drm_atomic_stat internals a bit better.

Cc: Eric Anholt <eric@anholt.net>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index cb37751bc99f..39c0b2048bfd 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -111,6 +111,8 @@ static int vc4_atomic_commit(struct drm_device *dev,
 	int i;
 	uint64_t wait_seqno = 0;
 	struct vc4_commit *c;
+	struct drm_plane *plane;
+	struct drm_plane_state *new_state;
 
 	c = commit_init(state);
 	if (!c)
@@ -130,13 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
 		return ret;
 	}
 
-	for (i = 0; i < dev->mode_config.num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
-		struct drm_plane_state *new_state = state->plane_states[i];
-
-		if (!plane)
-			continue;
-
+	for_each_plane_in_state(state, plane, new_state, i) {
 		if ((plane->state->fb != new_state->fb) && new_state->fb) {
 			struct drm_gem_cma_object *cma_bo =
 				drm_fb_cma_get_gem_obj(new_state->fb, 0);
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (4 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 05/26] drm/vc4: Use for_each_plane_in_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-30 11:42   ` [Intel-gfx] " Maarten Lankhorst
  2016-05-29 18:35 ` [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
                   ` (22 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

... and use it in msm&vc4. Again just want to encapsulate
drm_atomic_state internals a bit.

The const threading is a bit awkward in vc4 since C sucks, but I still
think it's worth to enforce this. Eventually I want to make all the
obj->state pointers const too, but that's a lot more work ...

Cc: Eric Anholt <eric@anholt.net>
Cc: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++------
 drivers/gpu/drm/vc4/vc4_crtc.c           | 11 +++-------
 drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
 drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
 include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
 5 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 88fe256c1931..6d4086ee0503 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
 	 */
 	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
 	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *pstate;
+		const struct drm_plane_state *pstate;
 		if (cnt >= (hw_cfg->lm.nb_stages)) {
 			dev_err(dev->dev, "too many planes!\n");
 			return -EINVAL;
 		}
 
-		pstate = state->state->plane_states[drm_plane_index(plane)];
+		pstate = __drm_atomic_get_current_plane_state(state->state,
+							      plane);
 
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!pstate)
-			pstate = plane->state;
 		pstates[cnt].plane = plane;
 		pstates[cnt].state = to_mdp5_plane_state(pstate);
 
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 904d0754ad78..703bda170105 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
 		return -EINVAL;
 
 	drm_atomic_crtc_state_for_each_plane(plane, state) {
-		struct drm_plane_state *plane_state =
-			state->state->plane_states[drm_plane_index(plane)];
-
-		/* plane might not have changed, in which case take
-		 * current state:
-		 */
-		if (!plane_state)
-			plane_state = plane->state;
+		const struct drm_plane_state *plane_state =
+			__drm_atomic_get_current_plane_state(state->state,
+							     plane);
 
 		dlist_count += vc4_plane_dlist_size(plane_state);
 	}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37cac59401d7..c799baabc008 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
 				 enum drm_plane_type type);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
-u32 vc4_plane_dlist_size(struct drm_plane_state *state);
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
 void vc4_plane_async_set_fb(struct drm_plane *plane,
 			    struct drm_framebuffer *fb);
 
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4037b52fde31..5d2c3d9fd17a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
 	return vc4_state->dlist_count;
 }
 
-u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
 {
-	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+	const struct vc4_plane_state *vc4_state =
+		container_of(state, typeof(*vc4_state), base);
 
 	return vc4_state->dlist_count;
 }
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92c84e9ab09a..4e97186293be 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 	return state->connector_states[index];
 }
 
+/**
+ * __drm_atomic_get_current_plane_state - get current plane state
+ * @state: global atomic state object
+ * @plane: plane to grab
+ *
+ * This function returns the plane state for the given plane, either from
+ * @state, or if the plane isn't part of the atomic state update, from @plane.
+ * This is useful in atomic check callbacks, when drivers need to peek at, but
+ * not change, state of other planes, since it avoids threading an error code
+ * back up the call chain.
+ *
+ * WARNING:
+ *
+ * Note that this function is in general unsafe since it doesn't check for the
+ * required locking for access state structures. Drivers must ensure that it is
+ * save to access the returned state structure through other means. One commone
+ * example is when planes are fixed to a single CRTC, and the driver knows that
+ * the CRTC locks is held already. In that case holding the CRTC locks gives a
+ * read-lock on all planes connected to that CRTC. But if planes can be
+ * reassigned things get more tricky. In that case it's better to use
+ * drm_atomic_get_plane_state and wire up full error handling.
+ *
+ * Returns:
+ *
+ * Read-only pointer to the current plane state.
+ */
+static inline const struct drm_plane_state *
+__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
+				     struct drm_plane *plane)
+{
+	if (state->plane_states[drm_plane_index(plane)])
+		return state->plane_states[drm_plane_index(plane)];
+
+	return plane->state;
+}
+
 int __must_check
 drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
 			     struct drm_display_mode *mode);
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (5 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-31 12:19   ` Inki Dae
  2016-06-13  0:52   ` Inki Dae
  2016-05-29 18:35 ` [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
                   ` (21 subsequent siblings)
  28 siblings, 2 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

We want to hide drm_atomic_state internals better.

Cc: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2dd820e23b0c..cabc5fd0246d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 {
 	struct exynos_drm_private *priv = dev->dev_private;
 	struct exynos_atomic_commit *commit;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
 	int i, ret;
 
 	commit = kzalloc(sizeof(*commit), GFP_KERNEL);
@@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 	/* Wait until all affected CRTCs have completed previous commits and
 	 * mark them as pending.
 	 */
-	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
-		if (state->crtcs[i])
-			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
-	}
+	for_each_crtc_in_state(state, crtc, crtc_state, i)
+		commit->crtcs |= 1 << drm_crtc_index(crtc);
 
 	wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
 
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (6 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-30 14:59   ` Ville Syrjälä
  2016-05-29 18:35 ` [PATCH 09/26] drm: Consolidate plane " Daniel Vetter
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-connector state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
connectors, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h            | 10 +++++-----
 include/drm/drm_crtc.h              | 11 +++++++----
 4 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 3ff1ed7b33db..a6395e9654af 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -44,7 +44,6 @@
 void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
 	kfree(state->connectors);
-	kfree(state->connector_states);
 	kfree(state->crtcs);
 	kfree(state->crtc_states);
 	kfree(state->planes);
@@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
 
 	for (i = 0; i < state->num_connector; i++) {
-		struct drm_connector *connector = state->connectors[i];
+		struct drm_connector *connector = state->connectors[i].ptr;
 
 		if (!connector)
 			continue;
 
 		connector->funcs->atomic_destroy_state(connector,
-						       state->connector_states[i]);
-		state->connectors[i] = NULL;
-		state->connector_states[i] = NULL;
+						       state->connectors[i].state);
+		state->connectors[i].ptr = NULL;
+		state->connectors[i].state = NULL;
 		drm_connector_unreference(connector);
 	}
 
@@ -896,8 +895,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
 	index = drm_connector_index(connector);
 
 	if (index >= state->num_connector) {
-		struct drm_connector **c;
-		struct drm_connector_state **cs;
+		struct __drm_connnectors_state *c;
 		int alloc = max(index + 1, config->num_connector);
 
 		c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
@@ -908,26 +906,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
 		memset(&state->connectors[state->num_connector], 0,
 		       sizeof(*state->connectors) * (alloc - state->num_connector));
 
-		cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
-		if (!cs)
-			return ERR_PTR(-ENOMEM);
-
-		state->connector_states = cs;
-		memset(&state->connector_states[state->num_connector], 0,
-		       sizeof(*state->connector_states) * (alloc - state->num_connector));
 		state->num_connector = alloc;
 	}
 
-	if (state->connector_states[index])
-		return state->connector_states[index];
+	if (state->connectors[index].state)
+		return state->connectors[index].state;
 
 	connector_state = connector->funcs->atomic_duplicate_state(connector);
 	if (!connector_state)
 		return ERR_PTR(-ENOMEM);
 
 	drm_connector_reference(connector);
-	state->connector_states[index] = connector_state;
-	state->connectors[index] = connector;
+	state->connectors[index].state = connector_state;
+	state->connectors[index].ptr = connector;
 	connector_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 464541c87c40..0fb4868fdad6 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1567,7 +1567,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
-		swap(state->connector_states[i], connector->state);
+		swap(state->connectors[i].state, connector->state);
 		connector->state->state = NULL;
 	}
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 4e97186293be..37478adb6a16 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -106,7 +106,7 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
 	if (index >= state->num_connector)
 		return NULL;
 
-	return state->connector_states[index];
+	return state->connectors[index].state;
 }
 
 /**
@@ -175,11 +175,11 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
 int __must_check drm_atomic_commit(struct drm_atomic_state *state);
 int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 
-#define for_each_connector_in_state(state, connector, connector_state, __i) \
+#define for_each_connector_in_state(__state, connector, connector_state, __i) \
 	for ((__i) = 0;							\
-	     (__i) < (state)->num_connector &&				\
-	     ((connector) = (state)->connectors[__i],			\
-	     (connector_state) = (state)->connector_states[__i], 1); 	\
+	     (__i) < (__state)->num_connector &&				\
+	     ((connector) = (__state)->connectors[__i].ptr,			\
+	     (connector_state) = (__state)->connectors[__i].state, 1); 	\
 	     (__i)++)							\
 		for_each_if (connector)
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 5bffb5c86ea8..d4c46bfe4142 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1694,6 +1694,11 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+struct __drm_connnectors_state {
+	struct drm_connector *ptr;
+	struct drm_connector_state *state;
+};
+
 /**
  * struct drm_atomic_state - the global state object for atomic updates
  * @dev: parent DRM device
@@ -1705,8 +1710,7 @@ struct drm_bridge {
  * @crtcs: pointer to array of CRTC pointers
  * @crtc_states: pointer to array of CRTC states pointers
  * @num_connector: size of the @connectors and @connector_states arrays
- * @connectors: pointer to array of connector pointers
- * @connector_states: pointer to array of connector states pointers
+ * @connectors: pointer to array of structures with per-connector data
  * @acquire_ctx: acquire context for this atomic modeset state update
  */
 struct drm_atomic_state {
@@ -1719,8 +1723,7 @@ struct drm_atomic_state {
 	struct drm_crtc **crtcs;
 	struct drm_crtc_state **crtc_states;
 	int num_connector;
-	struct drm_connector **connectors;
-	struct drm_connector_state **connector_states;
+	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 09/26] drm: Consolidate plane arrays in drm_atomic_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (7 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 10/26] drm: Consolidate crtc " Daniel Vetter
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's kinda pointless to have 2 separate mallocs for these. And when we
add more per-plane state in the future it's even more pointless.

Right now there's no such thing planned, but both Gustavo's per-crtc
fence patches, and some nonblocking commit helpers I'm playing around
with will add more per-crtc stuff. It makes sense to also consolidate
planes, just for consistency.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 17 ++++++-----------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 drivers/gpu/drm/i915/intel_atomic.c |  2 +-
 include/drm/drm_atomic.h            | 14 +++++++-------
 include/drm/drm_crtc.h              | 11 +++++++----
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index a6395e9654af..68fd99d2fd01 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -47,7 +47,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
 	kfree(state->crtcs);
 	kfree(state->crtc_states);
 	kfree(state->planes);
-	kfree(state->plane_states);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);
 
@@ -79,10 +78,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 				sizeof(*state->planes), GFP_KERNEL);
 	if (!state->planes)
 		goto fail;
-	state->plane_states = kcalloc(dev->mode_config.num_total_plane,
-				      sizeof(*state->plane_states), GFP_KERNEL);
-	if (!state->plane_states)
-		goto fail;
 
 	state->dev = dev;
 
@@ -163,15 +158,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	}
 
 	for (i = 0; i < config->num_total_plane; i++) {
-		struct drm_plane *plane = state->planes[i];
+		struct drm_plane *plane = state->planes[i].ptr;
 
 		if (!plane)
 			continue;
 
 		plane->funcs->atomic_destroy_state(plane,
-						   state->plane_states[i]);
-		state->planes[i] = NULL;
-		state->plane_states[i] = NULL;
+						   state->planes[i].state);
+		state->planes[i].ptr = NULL;
+		state->planes[i].state = NULL;
 	}
 }
 EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@ -630,8 +625,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
 	if (!plane_state)
 		return ERR_PTR(-ENOMEM);
 
-	state->plane_states[index] = plane_state;
-	state->planes[index] = plane;
+	state->planes[index].state = plane_state;
+	state->planes[index].ptr = plane;
 	plane_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 0fb4868fdad6..f70d576f745e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1579,7 +1579,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
 		plane->state->state = state;
-		swap(state->plane_states[i], plane->state);
+		swap(state->planes[i].state, plane->state);
 		plane->state->state = NULL;
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 3e6d9ff8840a..7542f5f5db1d 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -191,7 +191,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
 
 			/* plane scaler case: assign as a plane scaler */
 			/* find the plane that set the bit as scaler_user */
-			plane = drm_state->planes[i];
+			plane = drm_state->planes[i].ptr;
 
 			/*
 			 * to enable/disable hq mode, add planes that are using scaler
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 37478adb6a16..8e616d39353b 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -86,7 +86,7 @@ static inline struct drm_plane_state *
 drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
 				    struct drm_plane *plane)
 {
-	return state->plane_states[drm_plane_index(plane)];
+	return state->planes[drm_plane_index(plane)].state;
 }
 
 /**
@@ -139,8 +139,8 @@ static inline const struct drm_plane_state *
 __drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
 				     struct drm_plane *plane)
 {
-	if (state->plane_states[drm_plane_index(plane)])
-		return state->plane_states[drm_plane_index(plane)];
+	if (state->planes[drm_plane_index(plane)].state)
+		return state->planes[drm_plane_index(plane)].state;
 
 	return plane->state;
 }
@@ -191,11 +191,11 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (__i)++)						\
 		for_each_if (crtc_state)
 
-#define for_each_plane_in_state(state, plane, plane_state, __i)		\
+#define for_each_plane_in_state(__state, plane, plane_state, __i)		\
 	for ((__i) = 0;							\
-	     (__i) < (state)->dev->mode_config.num_total_plane &&	\
-	     ((plane) = (state)->planes[__i],				\
-	     (plane_state) = (state)->plane_states[__i], 1);		\
+	     (__i) < (__state)->dev->mode_config.num_total_plane &&	\
+	     ((plane) = (__state)->planes[__i].ptr,				\
+	     (plane_state) = (__state)->planes[__i].state, 1);		\
 	     (__i)++)							\
 		for_each_if (plane_state)
 static inline bool
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d4c46bfe4142..c7c2b3fa7179 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1694,6 +1694,11 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+struct __drm_planes_state {
+	struct drm_plane *ptr;
+	struct drm_plane_state *state;
+};
+
 struct __drm_connnectors_state {
 	struct drm_connector *ptr;
 	struct drm_connector_state *state;
@@ -1705,8 +1710,7 @@ struct __drm_connnectors_state {
  * @allow_modeset: allow full modeset
  * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
  * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
- * @planes: pointer to array of plane pointers
- * @plane_states: pointer to array of plane states pointers
+ * @planes: pointer to array of structures with per-plane data
  * @crtcs: pointer to array of CRTC pointers
  * @crtc_states: pointer to array of CRTC states pointers
  * @num_connector: size of the @connectors and @connector_states arrays
@@ -1718,8 +1722,7 @@ struct drm_atomic_state {
 	bool allow_modeset : 1;
 	bool legacy_cursor_update : 1;
 	bool legacy_set_config : 1;
-	struct drm_plane **planes;
-	struct drm_plane_state **plane_states;
+	struct __drm_planes_state *planes;
 	struct drm_crtc **crtcs;
 	struct drm_crtc_state **crtc_states;
 	int num_connector;
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 10/26] drm: Consolidate crtc arrays in drm_atomic_state
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (8 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 09/26] drm: Consolidate plane " Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 11/26] drm/fence: add fence to drm_pending_event Daniel Vetter
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's silly to have 2 mallocs when we could tie these two together.

Also, Gustavo adds another one in his per-crtc out-fence patches. And
I want to add more stuff here for nonblocking commit helpers.

In the future we can use this to store a pointer to the preceeding
state, making an atomic update entirely free-standing. This will be
needed to be able to queue them up with a depth > 1.

Cc: Gustavo Padovan <gustavo@padovan.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c        | 17 ++++++-----------
 drivers/gpu/drm/drm_atomic_helper.c |  2 +-
 include/drm/drm_atomic.h            | 10 +++++-----
 include/drm/drm_crtc.h              |  8 ++++++--
 4 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 68fd99d2fd01..674b2e490aa9 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,7 +45,6 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
 {
 	kfree(state->connectors);
 	kfree(state->crtcs);
-	kfree(state->crtc_states);
 	kfree(state->planes);
 }
 EXPORT_SYMBOL(drm_atomic_state_default_release);
@@ -70,10 +69,6 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
 			       sizeof(*state->crtcs), GFP_KERNEL);
 	if (!state->crtcs)
 		goto fail;
-	state->crtc_states = kcalloc(dev->mode_config.num_crtc,
-				     sizeof(*state->crtc_states), GFP_KERNEL);
-	if (!state->crtc_states)
-		goto fail;
 	state->planes = kcalloc(dev->mode_config.num_total_plane,
 				sizeof(*state->planes), GFP_KERNEL);
 	if (!state->planes)
@@ -146,15 +141,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 	}
 
 	for (i = 0; i < config->num_crtc; i++) {
-		struct drm_crtc *crtc = state->crtcs[i];
+		struct drm_crtc *crtc = state->crtcs[i].ptr;
 
 		if (!crtc)
 			continue;
 
 		crtc->funcs->atomic_destroy_state(crtc,
-						  state->crtc_states[i]);
-		state->crtcs[i] = NULL;
-		state->crtc_states[i] = NULL;
+						  state->crtcs[i].state);
+		state->crtcs[i].ptr = NULL;
+		state->crtcs[i].state = NULL;
 	}
 
 	for (i = 0; i < config->num_total_plane; i++) {
@@ -264,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 	if (!crtc_state)
 		return ERR_PTR(-ENOMEM);
 
-	state->crtc_states[index] = crtc_state;
-	state->crtcs[index] = crtc;
+	state->crtcs[index].state = crtc_state;
+	state->crtcs[index].ptr = crtc;
 	crtc_state->state = state;
 
 	DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index f70d576f745e..5298eb668ca7 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1573,7 +1573,7 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		crtc->state->state = state;
-		swap(state->crtc_states[i], crtc->state);
+		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
 	}
 
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 8e616d39353b..d9504dfcd1cc 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -71,7 +71,7 @@ static inline struct drm_crtc_state *
 drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
 				   struct drm_crtc *crtc)
 {
-	return state->crtc_states[drm_crtc_index(crtc)];
+	return state->crtcs[drm_crtc_index(crtc)].state;
 }
 
 /**
@@ -183,11 +183,11 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (__i)++)							\
 		for_each_if (connector)
 
-#define for_each_crtc_in_state(state, crtc, crtc_state, __i)	\
+#define for_each_crtc_in_state(__state, crtc, crtc_state, __i)	\
 	for ((__i) = 0;						\
-	     (__i) < (state)->dev->mode_config.num_crtc &&	\
-	     ((crtc) = (state)->crtcs[__i],			\
-	     (crtc_state) = (state)->crtc_states[__i], 1);	\
+	     (__i) < (__state)->dev->mode_config.num_crtc &&	\
+	     ((crtc) = (__state)->crtcs[__i].ptr,			\
+	     (crtc_state) = (__state)->crtcs[__i].state, 1);	\
 	     (__i)++)						\
 		for_each_if (crtc_state)
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index c7c2b3fa7179..d5d5e343531e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1699,6 +1699,11 @@ struct __drm_planes_state {
 	struct drm_plane_state *state;
 };
 
+struct __drm_crtcs_state {
+	struct drm_crtc *ptr;
+	struct drm_crtc_state *state;
+};
+
 struct __drm_connnectors_state {
 	struct drm_connector *ptr;
 	struct drm_connector_state *state;
@@ -1723,8 +1728,7 @@ struct drm_atomic_state {
 	bool legacy_cursor_update : 1;
 	bool legacy_set_config : 1;
 	struct __drm_planes_state *planes;
-	struct drm_crtc **crtcs;
-	struct drm_crtc_state **crtc_states;
+	struct __drm_crtcs_state *crtcs;
 	int num_connector;
 	struct __drm_connnectors_state *connectors;
 
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 11/26] drm/fence: add fence to drm_pending_event
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (9 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 10/26] drm: Consolidate crtc " Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat Daniel Vetter
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Now a drm_pending_event can either send a real drm_event or signal a
fence, or both. It allow us to signal via fences when the buffer is
displayed on the screen. Which in turn means that the previous buffer
is not in use anymore and can be freed or sent back to another driver
for processing.

v2: Comments from Daniel Vetter
	- call fence_signal in drm_send_event_locked()
	- remove unneeded !e->event check

v3: Remove drm_pending_event->destroy to fix a leak when e->file_priv
is not set.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> (v2)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/drm_atomic.c                | 19 +++++++++++++------
 drivers/gpu/drm/drm_fops.c                  | 16 +++++++++-------
 drivers/gpu/drm/nouveau/nouveau_usif.c      |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  2 +-
 include/drm/drmP.h                          |  3 ++-
 5 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 674b2e490aa9..1db198df3014 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1412,7 +1412,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
  */
 
 static struct drm_pending_vblank_event *create_vblank_event(
-		struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
+		struct drm_device *dev, struct drm_file *file_priv,
+		struct fence *fence, uint64_t user_data)
 {
 	struct drm_pending_vblank_event *e = NULL;
 	int ret;
@@ -1425,12 +1426,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
 	e->event.base.length = sizeof(e->event);
 	e->event.user_data = user_data;
 
-	ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
-	if (ret) {
-		kfree(e);
-		return NULL;
+	if (file_priv) {
+		ret = drm_event_reserve_init(dev, file_priv, &e->base,
+					     &e->event.base);
+		if (ret) {
+			kfree(e);
+			return NULL;
+		}
 	}
 
+	e->base.fence = fence;
+
 	return e;
 }
 
@@ -1670,7 +1676,8 @@ retry:
 		for_each_crtc_in_state(state, crtc, crtc_state, i) {
 			struct drm_pending_vblank_event *e;
 
-			e = create_vblank_event(dev, file_priv, arg->user_data);
+			e = create_vblank_event(dev, file_priv, NULL,
+						arg->user_data);
 			if (!e) {
 				ret = -ENOMEM;
 				goto out;
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 868871068956..4c4b30f7a9f2 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -294,7 +294,7 @@ static void drm_events_release(struct drm_file *file_priv)
 	/* Remove unconsumed events */
 	list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
 		list_del(&e->link);
-		e->destroy(e);
+		kfree(e);
 	}
 
 	spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -525,7 +525,7 @@ put_back_event:
 			}
 
 			ret += length;
-			e->destroy(e);
+			kfree(e);
 		}
 	}
 	mutex_unlock(&file_priv->event_read_lock);
@@ -602,9 +602,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
 	list_add(&p->pending_link, &file_priv->pending_event_list);
 	p->file_priv = file_priv;
 
-	/* we *could* pass this in as arg, but everyone uses kfree: */
-	p->destroy = (void (*) (struct drm_pending_event *)) kfree;
-
 	return 0;
 }
 EXPORT_SYMBOL(drm_event_reserve_init_locked);
@@ -667,7 +664,7 @@ void drm_event_cancel_free(struct drm_device *dev,
 		list_del(&p->pending_link);
 	}
 	spin_unlock_irqrestore(&dev->event_lock, flags);
-	p->destroy(p);
+	kfree(p);
 }
 EXPORT_SYMBOL(drm_event_cancel_free);
 
@@ -689,8 +686,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->fence) {
+		fence_signal(e->fence);
+		fence_put(e->fence);
+	}
+
 	if (!e->file_priv) {
-		e->destroy(e);
+		kfree(e);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
index 675e9e077a95..08f9c6fa0f7f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_usif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
@@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
 	ntfy->p->base.event = &ntfy->p->e.base;
 	ntfy->p->base.file_priv = f;
 	ntfy->p->base.pid = current->pid;
-	ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
 	ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
 	ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1c4d5b5a70a2..5567fb43e674 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
 	if (e && e->base.file_priv == file_priv) {
 		vop->event = NULL;
 
-		e->base.destroy(&e->base);
+		kfree(&e->base);
 		file_priv->event_space += sizeof(e->event);
 	}
 	spin_unlock_irqrestore(&drm->event_lock, flags);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index f51fa4328494..51f751d1c8a4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -57,6 +57,7 @@
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/fence.h>
 
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
@@ -283,12 +284,12 @@ struct drm_ioctl_desc {
 /* Event queued up for userspace to read */
 struct drm_pending_event {
 	struct drm_event *event;
+	struct fence *fence;
 	struct list_head link;
 	struct list_head pending_link;
 	struct drm_file *file_priv;
 	pid_t pid; /* pid of requester, no guarantee it's valid by the time
 		      we deliver the event, for tracing only */
-	void (*destroy)(struct drm_pending_event *event);
 };
 
 /* initial implementaton using a linked list - todo hashtab */
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (10 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 11/26] drm/fence: add fence to drm_pending_event Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-30 13:08   ` Maarten Lankhorst
  2016-05-29 18:35   ` Daniel Vetter
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

- dev is redundant, we have state->atomic
- add stall parameter, which must be set when swapping needs to stall
  for preceeding commits to stop looking at ->state pointers. Currently
  all drivers need this to be, just prep work for a glorious future.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +-
 drivers/gpu/drm/drm_atomic_helper.c          | 8 ++++----
 drivers/gpu/drm/exynos/exynos_drm_drv.c      | 2 +-
 drivers/gpu/drm/i915/intel_display.c         | 2 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c       | 2 +-
 drivers/gpu/drm/msm/msm_atomic.c             | 2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c           | 2 +-
 drivers/gpu/drm/rcar-du/rcar_du_kms.c        | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c   | 2 +-
 drivers/gpu/drm/sti/sti_drv.c                | 2 +-
 drivers/gpu/drm/tegra/drm.c                  | 2 +-
 drivers/gpu/drm/vc4/vc4_kms.c                | 2 +-
 include/drm/drm_atomic_helper.h              | 4 ++--
 13 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 6485fa5bee8b..9ecf16c7911d 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -519,7 +519,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
 	}
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (async)
 		queue_work(dc->wq, &commit->work);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 5298eb668ca7..fecbb52cbb85 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1160,7 +1160,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
@@ -1531,8 +1531,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
 
 /**
  * drm_atomic_helper_swap_state - store atomic state into current sw state
- * @dev: DRM device
  * @state: atomic state
+ * @stall: stall for proceeding commits
  *
  * This function stores the atomic state into the current state pointers in all
  * driver objects. It should be called after all failing steps have been done
@@ -1554,8 +1554,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
  */
-void drm_atomic_helper_swap_state(struct drm_device *dev,
-				  struct drm_atomic_state *state)
+void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+				  bool stall)
 {
 	int i;
 	struct drm_connector *connector;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index cabc5fd0246d..deba76982358 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -299,7 +299,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
 	priv->pending |= commit->crtcs;
 	spin_unlock(&priv->lock);
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9ccd76699f48..d32274071393 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13660,7 +13660,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 		return ret;
 	}
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 	dev_priv->wm.distrust_bios_wm = false;
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 06a417b2f91e..c33bf98c5d5e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -91,7 +91,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
 	mutex_lock(&private->commit.lock);
 	flush_work(&private->commit.work);
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (async)
 		mtk_atomic_schedule(private, state);
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 9c0e4261dbba..d02bd6a50e90 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -238,7 +238,7 @@ int msm_atomic_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index d86f5479345b..5d8377aad639 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -175,7 +175,7 @@ static int omap_atomic_commit(struct drm_device *dev,
 	spin_unlock(&priv->commit.lock);
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index f315c55c1f65..3d04a506cf33 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -327,7 +327,7 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
 	}
 
 	/* Swap the state, this is the point of no return. */
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		schedule_work(&commit->work);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 03913b483506..5ea141dfae5b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -290,7 +290,7 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
 	mutex_lock(&commit->lock);
 	flush_work(&commit->work);
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	commit->dev = dev;
 	commit->state = state;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index b440617a7019..dd2c400c4a46 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -215,7 +215,7 @@ static int sti_atomic_commit(struct drm_device *drm,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		sti_atomic_schedule(private, state);
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index b59c3bf0df44..a177a42a9849 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -93,7 +93,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(drm, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	if (nonblock)
 		tegra_atomic_schedule(tegra, state);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 39c0b2048bfd..8f4d5ffc32be 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -148,7 +148,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
 	 * the software side now.
 	 */
 
-	drm_atomic_helper_swap_state(dev, state);
+	drm_atomic_helper_swap_state(state, true);
 
 	/*
 	 * Everything below can be run asynchronously without the need to grab
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d473dcc91f54..0276447225ed 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -71,8 +71,8 @@ void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_sta
 void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 					      bool atomic);
 
-void drm_atomic_helper_swap_state(struct drm_device *dev,
-				  struct drm_atomic_state *state);
+void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
+				  bool stall);
 
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/26] drm/arc: Nuke event_list
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
@ 2016-05-29 18:35   ` Daniel Vetter
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (27 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: linux-snps-arc

This is just used for cleanup in preclose, and with the reworked event
handling code this is now done properly by the core.

Nuke it!

But it also shows that arc totally fails at sending out drm events for
flips. Next patch will hack that up.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu.h      |  1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c |  4 ----
 drivers/gpu/drm/arc/arcpgu_drv.c  | 19 -------------------
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h
index 86574b698a78..8c01a25d279a 100644
--- a/drivers/gpu/drm/arc/arcpgu.h
+++ b/drivers/gpu/drm/arc/arcpgu.h
@@ -22,7 +22,6 @@ struct arcpgu_drm_private {
 	struct clk		*clk;
 	struct drm_fbdev_cma	*fbdev;
 	struct drm_framebuffer	*fb;
-	struct list_head	event_list;
 	struct drm_crtc		crtc;
 	struct drm_plane	*plane;
 };
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 92f8beff8e60..d5ca0c280e68 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 		event->pipe = drm_crtc_index(crtc);
 
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &arcpgu->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	}
 }
 
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..d407fd79a400 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = {
 	.mmap = arcpgu_gem_mmap,
 };
 
-static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
-{
-	struct arcpgu_drm_private *arcpgu = drm->dev_private;
-	struct drm_pending_vblank_event *e, *t;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) {
-		if (e->base.file_priv != file)
-			continue;
-		list_del(&e->base.link);
-		e->base.destroy(&e->base);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void arcpgu_lastclose(struct drm_device *drm)
 {
 	struct arcpgu_drm_private *arcpgu = drm->dev_private;
@@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm)
 	if (IS_ERR(arcpgu->clk))
 		return PTR_ERR(arcpgu->clk);
 
-	INIT_LIST_HEAD(&arcpgu->event_list);
-
 	arcpgu_setup_mode_config(drm);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm)
 static struct drm_driver arcpgu_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
 			   DRIVER_ATOMIC,
-	.preclose = arcpgu_preclose,
 	.lastclose = arcpgu_lastclose,
 	.name = "drm-arcpgu",
 	.desc = "ARC PGU Controller",
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 13/26] drm/arc: Nuke event_list
@ 2016-05-29 18:35   ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

This is just used for cleanup in preclose, and with the reworked event
handling code this is now done properly by the core.

Nuke it!

But it also shows that arc totally fails at sending out drm events for
flips. Next patch will hack that up.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu.h      |  1 -
 drivers/gpu/drm/arc/arcpgu_crtc.c |  4 ----
 drivers/gpu/drm/arc/arcpgu_drv.c  | 19 -------------------
 3 files changed, 24 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu.h b/drivers/gpu/drm/arc/arcpgu.h
index 86574b698a78..8c01a25d279a 100644
--- a/drivers/gpu/drm/arc/arcpgu.h
+++ b/drivers/gpu/drm/arc/arcpgu.h
@@ -22,7 +22,6 @@ struct arcpgu_drm_private {
 	struct clk		*clk;
 	struct drm_fbdev_cma	*fbdev;
 	struct drm_framebuffer	*fb;
-	struct list_head	event_list;
 	struct drm_crtc		crtc;
 	struct drm_plane	*plane;
 };
diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index 92f8beff8e60..d5ca0c280e68 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -155,10 +155,6 @@ static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 		event->pipe = drm_crtc_index(crtc);
 
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
-		spin_lock_irqsave(&crtc->dev->event_lock, flags);
-		list_add_tail(&event->base.link, &arcpgu->event_list);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	}
 }
 
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..d407fd79a400 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -81,22 +81,6 @@ static const struct file_operations arcpgu_drm_ops = {
 	.mmap = arcpgu_gem_mmap,
 };
 
-static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
-{
-	struct arcpgu_drm_private *arcpgu = drm->dev_private;
-	struct drm_pending_vblank_event *e, *t;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	list_for_each_entry_safe(e, t, &arcpgu->event_list, base.link) {
-		if (e->base.file_priv != file)
-			continue;
-		list_del(&e->base.link);
-		e->base.destroy(&e->base);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void arcpgu_lastclose(struct drm_device *drm)
 {
 	struct arcpgu_drm_private *arcpgu = drm->dev_private;
@@ -122,8 +106,6 @@ static int arcpgu_load(struct drm_device *drm)
 	if (IS_ERR(arcpgu->clk))
 		return PTR_ERR(arcpgu->clk);
 
-	INIT_LIST_HEAD(&arcpgu->event_list);
-
 	arcpgu_setup_mode_config(drm);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -192,7 +174,6 @@ int arcpgu_unload(struct drm_device *drm)
 static struct drm_driver arcpgu_drm_driver = {
 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
 			   DRIVER_ATOMIC,
-	.preclose = arcpgu_preclose,
 	.lastclose = arcpgu_lastclose,
 	.name = "drm-arcpgu",
 	.desc = "ARC PGU Controller",
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 14/26] drm/arc: Actually bother with handling atomic events.
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
@ 2016-05-29 18:35   ` Daniel Vetter
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (27 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: linux-snps-arc

The drm core has a nice ready-made helper for exactly the simple case
where it should fire on the next vblank.

Note that arming the vblank event in _begin is probably too early, and
might easily result in the vblank firing too early, before the new set
of planes are actually disabled. But that's kinda a minor issue
compared to just outright hanging userspace.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index d5ca0c280e68..c9f183b11df9 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -145,16 +145,17 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 				      struct drm_crtc_state *state)
 {
-	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
+	if (event) {
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
 
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 }
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 14/26] drm/arc: Actually bother with handling atomic events.
@ 2016-05-29 18:35   ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

The drm core has a nice ready-made helper for exactly the simple case
where it should fire on the next vblank.

Note that arming the vblank event in _begin is probably too early, and
might easily result in the vblank firing too early, before the new set
of planes are actually disabled. But that's kinda a minor issue
compared to just outright hanging userspace.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu_crtc.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c
index d5ca0c280e68..c9f183b11df9 100644
--- a/drivers/gpu/drm/arc/arcpgu_crtc.c
+++ b/drivers/gpu/drm/arc/arcpgu_crtc.c
@@ -145,16 +145,17 @@ static int arc_pgu_crtc_atomic_check(struct drm_crtc *crtc,
 static void arc_pgu_crtc_atomic_begin(struct drm_crtc *crtc,
 				      struct drm_crtc_state *state)
 {
-	struct arcpgu_drm_private *arcpgu = crtc_to_arcpgu_priv(crtc);
-	unsigned long flags;
-
-	if (crtc->state->event) {
-		struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
+	if (event) {
 		crtc->state->event = NULL;
-		event->pipe = drm_crtc_index(crtc);
 
-		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
 	}
 }
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
@ 2016-05-29 18:35   ` Daniel Vetter
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
                     ` (27 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: linux-snps-arc

Committing with block it is not.

Thanks to the fixed up vblank event handling we can just use the
helper support for nonblocking commits now.

Cc: Carlos Palminha <palminha at synopsys.com>
Cc: Alexey Brodkin <abrodkin at synopsys.com>
Cc: linux-snps-arc at lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d407fd79a400..a92e533531c3 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
 		drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
 }
 
-static int arcpgu_atomic_commit(struct drm_device *dev,
-				    struct drm_atomic_state *state, bool async)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
 	.fb_create  = drm_fb_cma_create,
 	.output_poll_changed = arcpgu_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = arcpgu_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void arcpgu_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
@ 2016-05-29 18:35   ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	Carlos Palminha, Daniel Vetter, linux-snps-arc

Committing with block it is not.

Thanks to the fixed up vblank event handling we can just use the
helper support for nonblocking commits now.

Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arc/arcpgu_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index d407fd79a400..a92e533531c3 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -32,17 +32,11 @@ static void arcpgu_fb_output_poll_changed(struct drm_device *dev)
 		drm_fbdev_cma_hotplug_event(arcpgu->fbdev);
 }
 
-static int arcpgu_atomic_commit(struct drm_device *dev,
-				    struct drm_atomic_state *state, bool async)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
 	.fb_create  = drm_fb_cma_create,
 	.output_poll_changed = arcpgu_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = arcpgu_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void arcpgu_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (14 preceding siblings ...)
  2016-05-29 18:35   ` Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-31 11:02   ` Liviu Dudau
  2016-05-29 18:35 ` [PATCH 17/26] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
                   ` (12 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Liviu Dudau, Daniel Vetter

Again, just doing them as blocking commits isn't cool.

From a cursory check hdlcd does seem to at least try to handle
drm_pending_vblank_event, so hopefully this works.

Cc: Liviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 4f909378d581..6d1877238cf0 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -112,17 +112,11 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
 		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
 }
 
-static int hdlcd_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state, bool nonblock)
-{
-	return drm_atomic_helper_commit(dev, state, false);
-}
-
 static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
 	.fb_create = drm_fb_cma_create,
 	.output_poll_changed = hdlcd_fb_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = hdlcd_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 static void hdlcd_setup_mode_config(struct drm_device *drm)
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 17/26] drm/fsl-du: Implement some semblance of vblank event handling
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (15 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 18/26] drm/hisilicon: " Daniel Vetter
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

No idea how exactly fsl-du commits hw state changes, but here in flush
is probably the safest place.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Stefan Agner <stefan@agner.ch>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
index 89c0084c2814..706de3278f1c 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -22,20 +22,21 @@
 #include "fsl_dcu_drm_drv.h"
 #include "fsl_dcu_drm_plane.h"
 
-static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc,
+static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 					  struct drm_crtc_state *old_crtc_state)
 {
-}
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
-static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
-					 struct drm_crtc_state *state)
-{
-	return 0;
-}
+	if (event) {
+		crtc->state->event = NULL;
 
-static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc,
-					  struct drm_crtc_state *old_crtc_state)
-{
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
@@ -117,8 +118,6 @@ static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
-	.atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
-	.atomic_check = fsl_dcu_drm_crtc_atomic_check,
 	.atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
 	.disable = fsl_dcu_drm_disable_crtc,
 	.enable = fsl_dcu_drm_crtc_enable,
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 18/26] drm/hisilicon: Implement some semblance of vblank event handling
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (16 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 17/26] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 19/26] drm/sun4i: " Daniel Vetter
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

atomic_flush seems to be the right place, but I'm not entirely sure
whether this will catch them all. It could be that when disabling the
crtc we'll miss the vblank.

While at it nuke the dummy functions.

v2: Be more robust and either arm, when the CRTC is on, or just send
the event out right away.

Cc: Xinliang Liu <xinliang.liu@linaro.org>
Cc: Xinwei Kong <kong.kongxinwei@hisilicon.com>
Cc: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
index fba6372d060e..ed76baad525f 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c
@@ -502,13 +502,6 @@ static void ade_crtc_disable(struct drm_crtc *crtc)
 	acrtc->enable = false;
 }
 
-static int ade_crtc_atomic_check(struct drm_crtc *crtc,
-				 struct drm_crtc_state *state)
-{
-	/* do nothing */
-	return 0;
-}
-
 static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc)
 {
 	struct ade_crtc *acrtc = to_ade_crtc(crtc);
@@ -537,6 +530,7 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 {
 	struct ade_crtc *acrtc = to_ade_crtc(crtc);
 	struct ade_hw_ctx *ctx = acrtc->ctx;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 	void __iomem *base = ctx->base;
 
 	/* only crtc is enabled regs take effect */
@@ -545,12 +539,22 @@ static void ade_crtc_atomic_flush(struct drm_crtc *crtc,
 		/* flush ade registers */
 		writel(ADE_ENABLE, base + ADE_EN);
 	}
+
+	if (event) {
+		crtc->state->event = NULL;
+
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs = {
 	.enable		= ade_crtc_enable,
 	.disable	= ade_crtc_disable,
-	.atomic_check	= ade_crtc_atomic_check,
 	.mode_set_nofb	= ade_crtc_mode_set_nofb,
 	.atomic_begin	= ade_crtc_atomic_begin,
 	.atomic_flush	= ade_crtc_atomic_flush,
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 19/26] drm/sun4i: Implement some semblance of vblank event handling
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (17 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 18/26] drm/hisilicon: " Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-06-01 16:18   ` Maxime Ripard
  2016-05-29 18:35 ` [PATCH 20/26] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
                   ` (9 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Maxime Ripard

atomic_flush seems to be the right place, right after we commit the
plane updates. Again use the fullproof version, since the pipe might
be off.

Cc: Boris Brezillon <boris.brezillon@free-electrons.com>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/sun4i/sun4i_crtc.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c
index 4182a21f5923..f628b6d8f23f 100644
--- a/drivers/gpu/drm/sun4i/sun4i_crtc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c
@@ -51,10 +51,22 @@ static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc,
 {
 	struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
 	struct sun4i_drv *drv = scrtc->drv;
+	struct drm_pending_vblank_event *event = crtc->state->event;
 
 	DRM_DEBUG_DRIVER("Committing plane changes\n");
 
 	sun4i_backend_commit(drv->backend);
+
+	if (event) {
+		crtc->state->event = NULL;
+
+		spin_lock_irq(&crtc->dev->event_lock);
+		if (drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
 }
 
 static void sun4i_crtc_disable(struct drm_crtc *crtc)
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 20/26] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (18 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 19/26] drm/sun4i: " Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 21/26] drm/atomic-helper: nonblocking commit support Daniel Vetter
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Just a bit of drive-by ocd.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 include/drm/drm_atomic.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index d9504dfcd1cc..465a1212f4f0 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -198,6 +198,13 @@ int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
 	     (plane_state) = (__state)->planes[__i].state, 1);		\
 	     (__i)++)							\
 		for_each_if (plane_state)
+
+/**
+ * drm_atomic_crtc_needs_modeset - compute combined modeset need
+ * @state: &drm_crtc_state for the CRTC
+ *
+ * This computes the combined need for a modeset for @state.
+ */
 static inline bool
 drm_atomic_crtc_needs_modeset(struct drm_crtc_state *state)
 {
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 21/26] drm/atomic-helper: nonblocking commit support
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (19 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 20/26] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-30  8:01   ` [PATCH] " Daniel Vetter
  2016-05-29 18:35 ` [PATCH 22/26] drm/i915: Signal drm events for atomic Daniel Vetter
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Daniel Stone, Tomeu Vizoso

Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

Cc: Tomeu Vizoso <tomeu.vizoso@gmail.com>
Cc: Daniel Stone <daniels@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c             |  22 ++
 drivers/gpu/drm/drm_atomic_helper.c      | 366 ++++++++++++++++++++++++++++---
 drivers/gpu/drm/drm_crtc.c               |   3 +
 drivers/gpu/drm/drm_fops.c               |   6 +
 include/drm/drmP.h                       |   1 +
 include/drm/drm_atomic.h                 |   6 +
 include/drm/drm_atomic_helper.h          |   8 +
 include/drm/drm_crtc.h                   | 119 +++++++++-
 include/drm/drm_modeset_helper_vtables.h |  36 +++
 9 files changed, 534 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 1db198df3014..50aa341ca9ff 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@
 
 #include "drm_crtc_internal.h"
 
+static void crtc_commit_free(struct kref *kref)
+{
+	struct drm_crtc_commit *commit =
+		container_of(kref, struct drm_crtc_commit, ref);
+
+	kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+	kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 
 		crtc->funcs->atomic_destroy_state(crtc,
 						  state->crtcs[i].state);
+
+		if (state->crtcs[i].commit) {
+			kfree(state->crtcs[i].commit->event);
+			state->crtcs[i].commit->event = NULL;
+			drm_crtc_commit_put(state->crtcs[i].commit);
+		}
+
+		state->crtcs[i].commit = NULL;
 		state->crtcs[i].ptr = NULL;
 		state->crtcs[i].state = NULL;
 	}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index fecbb52cbb85..a5854a31f493 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1113,20 +1113,15 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
 
 /**
- * drm_atomic_helper_commit - commit validated state object
- * @dev: DRM device
- * @state: the driver state object
- * @nonblocking: whether nonblocking behavior is requested.
+ * drm_atomic_helper_commit_tail - commit atomic update to hardware
+ * @state: new modeset state to be committed
  *
- * This function commits a with drm_atomic_helper_check() pre-validated state
- * object. This can still fail when e.g. the framebuffer reservation fails. For
- * now this doesn't implement nonblocking commits.
+ * This is the default implemenation for the ->atomic_commit_tail() hook of the
+ * &drm_mode_config_helper_funcs vtable.
  *
- * Note that right now this function does not support nonblocking commits, hence
- * driver writers must implement their own version for now. Also note that the
- * default ordering of how the various stages are called is to match the legacy
- * modeset helper library closest. One peculiarity of that is that it doesn't
- * mesh well with runtime PM at all.
+ * Note that the default ordering of how the various stages are called is to
+ * match the legacy modeset helper library closest. One peculiarity of that is
+ * that it doesn't mesh well with runtime PM at all.
  *
  * For drivers supporting runtime PM the recommended sequence is
  *
@@ -1137,6 +1132,70 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  *     drm_atomic_helper_commit_planes(dev, state, true);
  *
  * See the kerneldoc entries for these three functions for more details.
+ */
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, false);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_hw_done(state);
+
+	drm_atomic_helper_wait_for_vblanks(dev, state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+
+void commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config_helper_funcs *funcs;
+
+	funcs = dev->mode_config.helper_private;
+
+	drm_atomic_helper_wait_for_fences(dev, state);
+
+	drm_atomic_helper_wait_for_dependencies(state);
+
+	if (funcs && funcs->atomic_commit_tail)
+		funcs->atomic_commit_tail(state);
+	else
+		drm_atomic_helper_commit_tail(state);
+
+	drm_atomic_helper_commit_cleanup_done(state);
+
+	drm_atomic_state_free(state);
+}
+
+static void commit_work(struct work_struct *work)
+{
+	struct drm_atomic_state *state = container_of(work,
+						      struct drm_atomic_state,
+						      commit_work);
+	commit_tail(state);
+}
+
+/**
+ * drm_atomic_helper_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the driver state object
+ * @nonblocking: whether nonblocking behavior is requested.
+ *
+ * This function commits a with drm_atomic_helper_check() pre-validated state
+ * object. This can still fail when e.g. the framebuffer reservation fails. For
+ * now this doesn't implement nonblocking commits.
+ *
+ * Note that right now this function does not support nonblocking commits, hence
+ * driver writers must implement their own version for now.
+ *
+ * Committing the actual hardware state is done through the
+ * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable,
+ *  or it's default implementation drm_atomic_helper_commit_tail().
  *
  * RETURNS
  * Zero for success or -errno.
@@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&state->commit_work, commit_work);
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
@@ -1176,21 +1238,16 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * update. Which is important since compositors need to figure out the
 	 * composition of the next frame right after having submitted the
 	 * current layout.
+	 *
+	 * NOTE: Commit work has multiple phases, first hardware commit, then
+	 * cleanup. We want them to overlap, hence need system_unbound_wq to
+	 * make sure work items don't artifically stall on each another.
 	 */
 
-	drm_atomic_helper_wait_for_fences(dev, state);
-
-	drm_atomic_helper_commit_modeset_disables(dev, state);
-
-	drm_atomic_helper_commit_planes(dev, state, false);
-
-	drm_atomic_helper_commit_modeset_enables(dev, state);
-
-	drm_atomic_helper_wait_for_vblanks(dev, state);
-
-	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
+	if (nonblock)
+		queue_work(system_unbound_wq, &state->commit_work);
+	else
+		commit_tail(state);
 
 	return 0;
 }
@@ -1234,6 +1291,225 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * being displayed.
  */
 
+static int stall_checks(struct drm_crtc *crtc, bool nonblock)
+{
+	struct drm_crtc_commit *commit, *stall_commit = NULL;
+	bool completed = true;
+	int i, ret = 0;
+
+	spin_lock(&crtc->commit_lock);
+	i = 0;
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		if (i == 0) {
+			completed = try_wait_for_completion(&commit->flip_done);
+			/* Userspace is not allowed to get ahead of the previous
+			 * commit with nonblocking ones. */
+			if (!completed && nonblock) {
+				spin_unlock(&crtc->commit_lock);
+				return -EBUSY;
+			}
+		} else if (i == 1) {
+			stall_commit = commit;
+			drm_crtc_commit_get(stall_commit);
+		} else
+			break;
+
+		i++;
+	}
+	spin_unlock(&crtc->commit_lock);
+
+	if (!stall_commit)
+		return 0;
+
+	/* We don't want to let commits get ahead of cleanup work too much,
+	 * stalling on 2nd previous commit means triple-buffer won't ever stall.
+	 */
+	ret = wait_for_completion_interruptible_timeout(&commit->cleanup_done,
+							10*HZ);
+	if (ret == 0)
+		DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
+			  crtc->base.id, crtc->name);
+
+	if (ret == -ERESTARTSYS)
+		ret = -EINTR;
+
+	drm_crtc_commit_put(stall_commit);
+
+	return ret;
+}
+
+/**
+ * drm_atomic_helper_setup_commit - setup possible nonblocking commit
+ *
+ * Returns:
+ *
+ * 0 on success. -EBUSY when userspace schedules nonblocking commits too fast,
+ * -ENOMEM on allocation failures and -EINTR when a signal is pending.
+ */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i, ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+		if (!commit)
+			return -ENOMEM;
+
+		init_completion(&commit->flip_done);
+		init_completion(&commit->hw_done);
+		init_completion(&commit->cleanup_done);
+		INIT_LIST_HEAD(&commit->commit_entry);
+		kref_init(&commit->ref);
+		commit->crtc = crtc;
+
+		state->crtcs[i].commit = commit;
+
+		ret = stall_checks(crtc, nonblock);
+		if (ret)
+			return ret;
+
+		/* Drivers only send out events when at least either current or
+		 * new CRTC state is active. Complete right away if everything
+		 * stays off. */
+		if (!crtc->state->active && !crtc_state->active) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		/* Legacy cursor updates are fully unsynced. */
+		if (state->legacy_cursor_update) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		if (!crtc_state->event) {
+			commit->event = kzalloc(sizeof(*commit->event),
+						GFP_KERNEL);
+			if (!commit->event)
+				return -ENOMEM;
+
+			crtc_state->event = commit->event;
+		}
+
+		crtc_state->event->base.completion = &commit->flip_done;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
+
+
+static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_commit *commit;
+	int i = 0;
+
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		/* skip the first entry, that's the current commit */
+		if (i == 1)
+			return commit;
+		i++;
+	}
+
+	return NULL;
+}
+
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		spin_lock(&crtc->commit_lock);
+		commit = preceeding_commit(crtc);
+		if (commit)
+			drm_crtc_commit_get(commit);
+		spin_unlock(&crtc->commit_lock);
+
+		if (!commit)
+			continue;
+
+		ret = wait_for_completion_timeout(&commit->hw_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		/* Currently no support for overwriting flips, hence
+		 * stall for previous one to execute completely. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		drm_crtc_commit_put(commit);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
+
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+
+		/* backend must have consumed any event by now */
+		WARN_ON(crtc->state->event);
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->hw_done);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
+
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->cleanup_done);
+
+		WARN_ON(!try_wait_for_completion(&commit->hw_done));
+		
+		/* commit_list borrows our reference, need to remove before we
+		 * clean up our drm_atomic_state. */
+		list_del(&commit->commit_entry);
+		spin_unlock(&crtc->commit_lock);
+
+		/* We must wait for the vblank event to signal our completion
+		 * before releasing our reference, since the vblank work does
+		 * not hold a reference of its own. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
+
 /**
  * drm_atomic_helper_prepare_planes - prepare plane resources before commit
  * @dev: DRM device
@@ -1553,17 +1829,44 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  *
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
+ *
+ * @stall must be set when nonblocking commits for this driver directly access
+ * the ->state pointer of &drm_plane, &drm_crtc or &drm_connector. With the
+ * current atomic helpers this is almost always the case, since the helpers
+ * don't pass the right state structures to the callbacks.
  */
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall)
 {
 	int i;
+	long ret;
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_plane *plane;
 	struct drm_plane_state *plane_state;
+	struct drm_crtc_commit *commit;
+
+	if (stall) {
+		for_each_crtc_in_state(state, crtc, crtc_state, i) {
+			spin_lock(&crtc->commit_lock);
+			commit = preceeding_commit(crtc);
+			if (commit)
+				drm_crtc_commit_get(commit);
+			spin_unlock(&crtc->commit_lock);
+
+			if (!commit)
+				continue;
+
+			ret = wait_for_completion_timeout(&commit->hw_done,
+							  10*HZ);
+			if (ret == 0)
+				DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+					  crtc->base.id, crtc->name);
+			drm_crtc_commit_put(commit);
+		}
+	}
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
@@ -1575,6 +1878,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 		crtc->state->state = state;
 		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
+
+		if (state->crtcs[i].commit) {
+			spin_lock(&crtc->commit_lock);
+			list_add(&state->crtcs[i].commit->commit_entry,
+				 &crtc->commit_list);
+			spin_unlock(&crtc->commit_lock);
+
+			state->crtcs[i].commit->event = NULL;
+		}
 	}
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 88cf22052a69..3e52a6ecf6c0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -669,6 +669,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 	crtc->dev = dev;
 	crtc->funcs = funcs;
 
+	INIT_LIST_HEAD(&crtc->commit_list);
+	spin_lock_init(&crtc->commit_lock);
+
 	drm_modeset_lock_init(&crtc->mutex);
 	ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 	if (ret)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 4c4b30f7a9f2..5921b203503a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -686,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->completion) {
+		/* ->completion might disappear as soon as it signalled. */
+		complete_all(e->completion);
+		e->completion = NULL;
+	}
+
 	if (e->fence) {
 		fence_signal(e->fence);
 		fence_put(e->fence);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 51f751d1c8a4..781db4f562d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {
+	struct completion *completion;
 	struct drm_event *event;
 	struct fence *fence;
 	struct list_head link;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 465a1212f4f0..abec2a3f0225 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,12 @@
 
 #include <drm/drm_crtc.h>
 
+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
+static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+	kref_get(&commit->ref);
+}
+
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 0276447225ed..5fb8c306e16b 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -38,6 +38,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
 			       struct drm_atomic_state *state);
 int drm_atomic_helper_check(struct drm_device *dev,
 			    struct drm_atomic_state *state);
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
 int drm_atomic_helper_commit(struct drm_device *dev,
 			     struct drm_atomic_state *state,
 			     bool nonblock);
@@ -74,6 +75,13 @@ void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall);
 
+/* nonblocking commit helpers */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock);
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
+
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
 				   struct drm_crtc *crtc,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d5d5e343531e..c0edd87fa0ee 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -725,9 +725,6 @@ struct drm_crtc_funcs {
  * @gamma_store: gamma ramp values
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
- * @state: current atomic state for this CRTC
- * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
- * 	legacy IOCTLs
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -780,11 +777,37 @@ struct drm_crtc {
 
 	struct drm_object_properties properties;
 
+	/**
+	 * @state:
+	 *
+	 * Current atomic state for this CRTC.
+	 */
 	struct drm_crtc_state *state;
 
-	/*
-	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
-	 * acquire context.
+	/**
+	 * @commit_list:
+	 *
+	 * List of &drm_crtc_commit structures tracking pending commits.
+	 * Protected by @commit_lock. This list doesn't hold its own full
+	 * reference, but burrows it from the ongoing commit. Commit entries
+	 * must be removed from this list once the commit is fully completed,
+	 * but before it's correspoding &drm_atomic_state gets destroyed.
+	 */
+	struct list_head commit_list;
+
+	/**
+	 * @commit_lock:
+	 *
+	 * Spinlock to protect @commit_list.
+	 */
+	spinlock_t commit_lock;
+
+	/**
+	 * @acquire_ctx:
+	 *
+	 * Per-CRTC implicit acquire context used by atomic drivers for legacy
+	 * IOCTLs, so that atomic drivers can get at the locking acquire
+	 * context.
 	 */
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
@@ -1694,6 +1717,78 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+/**
+ * struct drm_crtc_commit - track modeset commits on a CRTC
+ */
+struct drm_crtc_commit {
+	/**
+	 * @crtc:
+	 *
+	 * DRM CRTC for this commit.
+	 */
+	struct drm_crtc *crtc;
+
+	/**
+	 * @ref:
+	 *
+	 * Reference count for this structure. Needed to allow blocking on
+	 * completions without the risk of the completion disappearing
+	 * meanwhile.
+	 */
+	struct kref ref;
+
+	/**
+	 * @flip_done:
+	 *
+	 * Will be signaled when the hardware has flipped to the new set of
+	 * buffers. Signals at the same time as when the drm event for this
+	 * commit is sent to userspace, or when an out-fence is singalled. Note
+	 * that for most hardware, in most cases this happens after @hw_done is
+	 * signalled.
+	 */
+	struct completion flip_done;
+
+	/**
+	 * @hw_done:
+	 *
+	 * Will be signalled when all hw register changes for this commit have
+	 * been written out. Especially when disabling a pipe this can be much
+	 * later than than @flip_done, since that can signal already when the
+	 * screen goes black, whereas to fully shut down a pipe more register
+	 * I/O is required.
+	 *
+	 * Note that this does not need to include separately reference-counted
+	 * resources like backing storage buffer pinning, or runtime pm
+	 * management.
+	 */
+	struct completion hw_done;
+
+	/**
+	 * cleanup_done:
+	 *
+	 * Will be signalled after old buffers have been cleaned up again by
+	 * calling drm_atomic_helper_cleanup_planes(). Since this can only
+	 * happen after a vblank wait completed it might be a bit later. This
+	 * completion is useful to throttle updates and avoid hardware updates
+	 * getting ahead of the buffer cleanup too much.
+	 */
+	struct completion cleanup_done;
+
+	/**
+	 * @commit_entry:
+	 *
+	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
+	 */
+	struct list_head commit_entry;
+
+	/**
+	 * @event:
+	 *
+	 * &drm_pending_vblank_event pointer to clean up private events.
+	 */
+	struct drm_pending_vblank_event *event;
+};
+
 struct __drm_planes_state {
 	struct drm_plane *ptr;
 	struct drm_plane_state *state;
@@ -1702,6 +1797,7 @@ struct __drm_planes_state {
 struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
+	struct drm_crtc_commit *commit;
 };
 
 struct __drm_connnectors_state {
@@ -1733,6 +1829,14 @@ struct drm_atomic_state {
 	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
+
+	/**
+	 * @commit_work:
+	 *
+	 * Work item which can be used by the driver or helpers to execute the
+	 * commit without blocking.
+	 */
+	struct work_struct commit_work;
 };
 
 
@@ -2074,6 +2178,7 @@ struct drm_mode_config_funcs {
  * @async_page_flip: does this device support async flips on the primary plane?
  * @cursor_width: hint to userspace for max cursor width
  * @cursor_height: hint to userspace for max cursor height
+ * @helper_private: mid-layer private data
  *
  * Core mode resource tracking structure.  All CRTC, encoders, and connectors
  * enumerated by the driver are added here, as are global properties.  Some
@@ -2193,6 +2298,8 @@ struct drm_mode_config {
 
 	/* cursor size */
 	uint32_t cursor_width, cursor_height;
+
+	struct drm_mode_config_helper_funcs *helper_private;
 };
 
 /**
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index d4619dc2eecb..145c147705d8 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -925,4 +925,40 @@ static inline void drm_plane_helper_add(struct drm_plane *plane,
 	plane->helper_private = funcs;
 }
 
+/**
+ * struct drm_mode_config_helper_funcs - global modeset helper operations
+ *
+ * These helper functions are used by the atomic helpers.
+ */
+struct drm_mode_config_helper_funcs {
+	/**
+	 * @atomic_commit_tail:
+	 *
+	 * This hook should commit the given atomic state to the hardware, but
+	 * nothing else. This excludes specifically any prepare and cleanup work
+	 * done by drm_atomic_helper_prepare_planes() and
+	 * drm_atomic_helper_cleanup_planes(). And also any synchronization and
+	 * stalling necessary around the around the hardware commit as done for
+	 * example by drm_atomic_helper_wait_for_fences() or
+	 * drm_atomic_helper_wait_for_vblanks().
+	 *
+	 * The function is not required to stall for the commit to actually
+	 * complete and for the new buffers to be displayed on the screen. This
+	 * is handled by properly signalling the &drm_pending_vblank_event in each
+	 * &drm_crtc_state through a call to drm_send_vblank_event() or
+	 * drm_arm_vblank_event(), depending upon how the driver works.
+	 *
+	 * When disabling a CRTC otoh this hook _must_ stall for the commit to
+	 * complete. Vblank waits don't work on disabled CRTC, hence the core
+	 * can't take care of this. And it also can't rely on the vblank event,
+	 * since that can be signalled already when the screen shows black,
+	 * which can happen much earlier than the last hardware access needed to
+	 * shut off the display pipeline completely.
+	 *
+	 * This hook is optional, the default implementation is
+	 * drm_atomic_helper_commit_tail().
+	 */
+	void (*atomic_commit_tail)(struct drm_atomic_state *state);
+};
+
 #endif
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 22/26] drm/i915: Signal drm events for atomic
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (20 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 21/26] drm/atomic-helper: nonblocking commit support Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 23/26] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

This is part of what atomic must implement. And it's also required
to be able to use the helper nonblocking support.

v2: Always send out the drm event, remove the planes_changed check.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_display.c | 13 ++++++++++---
 drivers/gpu/drm/i915/intel_sprite.c  | 14 ++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d32274071393..66a254fa2a96 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13731,13 +13731,21 @@ static int intel_atomic_commit(struct drm_device *dev,
 		bool modeset = needs_modeset(crtc->state);
 		struct intel_crtc_state *pipe_config =
 			to_intel_crtc_state(crtc->state);
-		bool update_pipe = !modeset && pipe_config->update_pipe;
 
 		if (modeset && crtc->state->active) {
 			update_scanline_offset(to_intel_crtc(crtc));
 			dev_priv->display.crtc_enable(crtc);
 		}
 
+		/* Complete events for now disable pipes here. */
+		if (modeset && !crtc->state->active && crtc->state->event) {
+			spin_lock_irq(&dev->event_lock);
+			drm_crtc_send_vblank_event(crtc, crtc->state->event);
+			spin_unlock_irq(&dev->event_lock);
+
+			crtc->state->event = NULL;
+		}
+
 		if (!modeset)
 			intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
 
@@ -13745,8 +13753,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 		    drm_atomic_get_existing_plane_state(state, crtc->primary))
 			intel_fbc_enable(intel_crtc);
 
-		if (crtc->state->active &&
-		    (crtc->state->planes_changed || update_pipe))
+		if (crtc->state->active)
 			drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
 
 		if (pipe_config->base.active && needs_vblank_wait(pipe_config))
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 97b1a54eb09f..8864cc983ea2 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -166,6 +166,20 @@ void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work
 
 	trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
 
+	/* We're still in the vblank-evade critical section, this can't race.
+	 * Would be slightly nice to just grab the vblank count and arm the
+	 * event outside of the critical section - the spinlock might spin for a
+	 * while ... */
+	if (crtc->base.state->event) {
+		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
+
+		spin_lock(&crtc->base.dev->event_lock);
+		drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event);
+		spin_unlock(&crtc->base.dev->event_lock);
+
+		crtc->base.state->event = NULL;
+	}
+
 	local_irq_enable();
 
 	if (crtc->debug.start_vbl_count &&
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 23/26] drm/i915: Roll out the helper nonblock tracking
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (21 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 22/26] drm/i915: Signal drm events for atomic Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 24/26] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Right now still all blocking, no worker anywhere to be seen.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 66a254fa2a96..4b81cffef24e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13654,6 +13654,10 @@ static int intel_atomic_commit(struct drm_device *dev,
 	unsigned long put_domains[I915_MAX_PIPES] = {};
 	unsigned crtc_vblank_mask = 0;
 
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
 	ret = intel_atomic_prepare_commit(dev, state, nonblock);
 	if (ret) {
 		DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
@@ -13665,6 +13669,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	dev_priv->wm.skl_results = intel_state->wm_results;
 	intel_shared_dpll_commit(state);
 
+	drm_atomic_helper_wait_for_dependencies(state);
+
 	if (intel_state->modeset) {
 		memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
 		       sizeof(intel_state->min_pixclk));
@@ -13760,7 +13766,7 @@ static int intel_atomic_commit(struct drm_device *dev,
 			crtc_vblank_mask |= 1 << i;
 	}
 
-	/* FIXME: add subpixel order */
+	drm_atomic_helper_commit_hw_done(state);
 
 	if (!state->legacy_cursor_update)
 		intel_atomic_wait_for_vblanks(dev, dev_priv, crtc_vblank_mask);
@@ -13795,6 +13801,8 @@ static int intel_atomic_commit(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, state);
 	mutex_unlock(&dev->struct_mutex);
 
+	drm_atomic_helper_commit_cleanup_done(state);
+
 	drm_atomic_state_free(state);
 
 	/* As one of the primary mmio accessors, KMS has a high likelihood
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 24/26] drm/rockchip: convert to helper nonblocking atomic commit
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (22 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 23/26] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 25/26] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Mark yao

So totally untested ...

v2: Fixes from Tomeu.

v3: Send out vblank events correctly when shutting down a crtc for
good. This is part of the atomic interface contract.

v4: Properly protect vop->event.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  3 --
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 10 ----
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 72 ++++-------------------------
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 +++++-
 4 files changed, 22 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 09a4d429c0f0..2fac6799ceb2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -145,9 +145,6 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	if (!private)
 		return -ENOMEM;
 
-	mutex_init(&private->commit.lock);
-	INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
-
 	drm_dev->dev_private = private;
 
 	drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 56f43a364c7f..7684503ff765 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -43,13 +43,6 @@ struct rockchip_crtc_funcs {
 	void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
 };
 
-struct rockchip_atomic_commit {
-	struct work_struct	work;
-	struct drm_atomic_state *state;
-	struct drm_device *dev;
-	struct mutex lock;
-};
-
 struct rockchip_crtc_state {
 	struct drm_crtc_state base;
 	int output_type;
@@ -68,11 +61,8 @@ struct rockchip_drm_private {
 	struct drm_fb_helper fbdev_helper;
 	struct drm_gem_object *fbdev_bo;
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
-
-	struct rockchip_atomic_commit commit;
 };
 
-void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 				 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 5ea141dfae5b..9198ee1ddc87 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -229,87 +229,32 @@ rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_stat
 }
 
 static void
-rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
+rockchip_atomic_commit_tail(struct drm_atomic_state *state)
 {
-	struct drm_atomic_state *state = commit->state;
-	struct drm_device *dev = commit->dev;
+	struct drm_device *dev = state->dev;
 
-	/*
-	 * TODO: do fence wait here.
-	 */
-
-	/*
-	 * Rockchip crtc support runtime PM, can't update display planes
-	 * when crtc is disabled.
-	 *
-	 * drm_atomic_helper_commit comments detail that:
-	 *     For drivers supporting runtime PM the recommended sequence is
-	 *
-	 *     drm_atomic_helper_commit_modeset_disables(dev, state);
-	 *
-	 *     drm_atomic_helper_commit_modeset_enables(dev, state);
-	 *
-	 *     drm_atomic_helper_commit_planes(dev, state, true);
-	 *
-	 * See the kerneldoc entries for these three functions for more details.
-	 */
 	drm_atomic_helper_commit_modeset_disables(dev, state);
 
 	drm_atomic_helper_commit_modeset_enables(dev, state);
 
 	drm_atomic_helper_commit_planes(dev, state, true);
 
+	drm_atomic_helper_commit_hw_done(state);
+
 	rockchip_atomic_wait_for_complete(dev, state);
 
 	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
-}
-
-void rockchip_drm_atomic_work(struct work_struct *work)
-{
-	struct rockchip_atomic_commit *commit = container_of(work,
-					struct rockchip_atomic_commit, work);
-
-	rockchip_atomic_commit_complete(commit);
 }
 
-int rockchip_drm_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool nonblock)
-{
-	struct rockchip_drm_private *private = dev->dev_private;
-	struct rockchip_atomic_commit *commit = &private->commit;
-	int ret;
-
-	ret = drm_atomic_helper_prepare_planes(dev, state);
-	if (ret)
-		return ret;
-
-	/* serialize outstanding nonblocking commits */
-	mutex_lock(&commit->lock);
-	flush_work(&commit->work);
-
-	drm_atomic_helper_swap_state(state, true);
-
-	commit->dev = dev;
-	commit->state = state;
-
-	if (nonblock)
-		schedule_work(&commit->work);
-	else
-		rockchip_atomic_commit_complete(commit);
-
-	mutex_unlock(&commit->lock);
-
-	return 0;
-}
+struct drm_mode_config_helper_funcs rockchip_mode_config_helpers = {
+	.atomic_commit_tail = rockchip_atomic_commit_tail,
+};
 
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
 	.fb_create = rockchip_user_fb_create,
 	.output_poll_changed = rockchip_drm_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
-	.atomic_commit = rockchip_drm_atomic_commit,
+	.atomic_commit = drm_atomic_helper_commit,
 };
 
 struct drm_framebuffer *
@@ -340,4 +285,5 @@ void rockchip_drm_mode_config_init(struct drm_device *dev)
 	dev->mode_config.max_height = 4096;
 
 	dev->mode_config.funcs = &rockchip_drm_mode_config_funcs;
+	dev->mode_config.helper_private = &rockchip_mode_config_helpers;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 5567fb43e674..8cde1ea62978 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -553,6 +553,14 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	clk_disable(vop->aclk);
 	clk_disable(vop->hclk);
 	pm_runtime_put(vop->dev);
+
+	if (crtc->state->event && !crtc->state->active) {
+		spin_lock_irq(&crtc->dev->event_lock);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		spin_unlock_irq(&crtc->dev->event_lock);
+
+		crtc->state->event = NULL;
+	}
 }
 
 static void vop_plane_destroy(struct drm_plane *plane)
@@ -1027,12 +1035,14 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
 {
 	struct vop *vop = to_vop(crtc);
 
+	spin_lock_irq(&crtc->dev->event_lock);
 	if (crtc->state->event) {
 		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
 		vop->event = crtc->state->event;
 		crtc->state->event = NULL;
 	}
+	spin_unlock_irq(&crtc->dev->event_lock);
 }
 
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
@@ -1104,15 +1114,16 @@ static void vop_handle_vblank(struct vop *vop)
 			return;
 	}
 
+	spin_lock_irqsave(&drm->event_lock, flags);
 	if (vop->event) {
-		spin_lock_irqsave(&drm->event_lock, flags);
 
 		drm_crtc_send_vblank_event(crtc, vop->event);
 		drm_crtc_vblank_put(crtc);
 		vop->event = NULL;
 
-		spin_unlock_irqrestore(&drm->event_lock, flags);
 	}
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+
 	if (!completion_done(&vop->wait_update_complete))
 		complete(&vop->wait_update_complete);
 }
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 25/26] drm/rockchip: Nuke pending event handling in preclose
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (23 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 24/26] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-29 18:35 ` [PATCH 26/26] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Tomeu Vizoso, Mark yao

This is now handled by the core, drivers can totally ignore lifetime
issues of drm events.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 22 ----------------------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 --------------------
 3 files changed, 43 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 2fac6799ceb2..2251121343e6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -257,27 +257,6 @@ static int rockchip_drm_unload(struct drm_device *drm_dev)
 	return 0;
 }
 
-static void rockchip_drm_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-						    struct drm_file *file_priv)
-{
-	struct rockchip_drm_private *priv = crtc->dev->dev_private;
-	int pipe = drm_crtc_index(crtc);
-
-	if (pipe < ROCKCHIP_MAX_CRTC &&
-	    priv->crtc_funcs[pipe] &&
-	    priv->crtc_funcs[pipe]->cancel_pending_vblank)
-		priv->crtc_funcs[pipe]->cancel_pending_vblank(crtc, file_priv);
-}
-
-static void rockchip_drm_preclose(struct drm_device *dev,
-				  struct drm_file *file_priv)
-{
-	struct drm_crtc *crtc;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-		rockchip_drm_crtc_cancel_pending_vblank(crtc, file_priv);
-}
-
 void rockchip_drm_lastclose(struct drm_device *dev)
 {
 	struct rockchip_drm_private *priv = dev->dev_private;
@@ -303,7 +282,6 @@ static struct drm_driver rockchip_drm_driver = {
 				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.load			= rockchip_drm_load,
 	.unload			= rockchip_drm_unload,
-	.preclose		= rockchip_drm_preclose,
 	.lastclose		= rockchip_drm_lastclose,
 	.get_vblank_counter	= drm_vblank_no_hw_counter,
 	.enable_vblank		= rockchip_drm_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 7684503ff765..005634484441 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -40,7 +40,6 @@ struct rockchip_crtc_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
 	void (*wait_for_update)(struct drm_crtc *crtc);
-	void (*cancel_pending_vblank)(struct drm_crtc *crtc, struct drm_file *file_priv);
 };
 
 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 8cde1ea62978..37a1339c30ae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -884,30 +884,10 @@ static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
 	WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
 }
 
-static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
-					   struct drm_file *file_priv)
-{
-	struct drm_device *drm = crtc->dev;
-	struct vop *vop = to_vop(crtc);
-	struct drm_pending_vblank_event *e;
-	unsigned long flags;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-	e = vop->event;
-	if (e && e->base.file_priv == file_priv) {
-		vop->event = NULL;
-
-		kfree(&e->base);
-		file_priv->event_space += sizeof(e->event);
-	}
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.enable_vblank = vop_crtc_enable_vblank,
 	.disable_vblank = vop_crtc_disable_vblank,
 	.wait_for_update = vop_crtc_wait_for_update,
-	.cancel_pending_vblank = vop_crtc_cancel_pending_vblank,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
-- 
2.8.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH 26/26] drm/virtio: Don't reinvent a flipping wheel
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (24 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 25/26] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
@ 2016-05-29 18:35 ` Daniel Vetter
  2016-05-31 13:40 ` ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers Patchwork
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-29 18:35 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Now that the core helpers support nonblocking atomic commits there's
no need to invent that wheel separately (instead of fixing the bug in
the atomic implementation of virtio, as it should have been done!).

Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 48 ++------------------------------
 1 file changed, 2 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index d4305da88f44..325c6f73814b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -118,58 +118,13 @@ static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc,
 	return 0;
 }
 
-static int virtio_gpu_page_flip(struct drm_crtc *crtc,
-				struct drm_framebuffer *fb,
-				struct drm_pending_vblank_event *event,
-				uint32_t flags)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-	struct drm_plane *plane = crtc->primary;
-	struct virtio_gpu_framebuffer *vgfb;
-	struct virtio_gpu_object *bo;
-	unsigned long irqflags;
-	uint32_t handle;
-
-	plane->fb = fb;
-	vgfb = to_virtio_gpu_framebuffer(plane->fb);
-	bo = gem_to_virtio_gpu_obj(vgfb->obj);
-	handle = bo->hw_res_handle;
-
-	DRM_DEBUG("handle 0x%x%s, crtc %dx%d\n", handle,
-		  bo->dumb ? ", dumb" : "",
-		  crtc->mode.hdisplay, crtc->mode.vdisplay);
-	if (bo->dumb) {
-		virtio_gpu_cmd_transfer_to_host_2d
-			(vgdev, handle, 0,
-			 cpu_to_le32(crtc->mode.hdisplay),
-			 cpu_to_le32(crtc->mode.vdisplay),
-			 0, 0, NULL);
-	}
-	virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
-				   crtc->mode.hdisplay,
-				   crtc->mode.vdisplay, 0, 0);
-	virtio_gpu_cmd_resource_flush(vgdev, handle, 0, 0,
-				      crtc->mode.hdisplay,
-				      crtc->mode.vdisplay);
-
-	if (event) {
-		spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
-		drm_send_vblank_event(crtc->dev, -1, event);
-		spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
-	}
-
-	return 0;
-}
-
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
 	.cursor_set2            = virtio_gpu_crtc_cursor_set,
 	.cursor_move            = virtio_gpu_crtc_cursor_move,
 	.set_config             = drm_atomic_helper_set_config,
 	.destroy                = drm_crtc_cleanup,
 
-	.page_flip              = virtio_gpu_page_flip,
+	.page_flip              = drm_atomic_helper_page_flip,
 	.reset                  = drm_atomic_helper_crtc_reset,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
@@ -267,6 +222,7 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
 	spin_lock_irqsave(&crtc->dev->event_lock, flags);
 	if (crtc->state->event)
 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+	crtc->state->event = NULL;
 	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 }
 
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH] drm/atomic-helper: nonblocking commit support
  2016-05-29 18:35 ` [PATCH 21/26] drm/atomic-helper: nonblocking commit support Daniel Vetter
@ 2016-05-30  8:01   ` Daniel Vetter
  2016-05-31 14:22     ` [Intel-gfx] " Maarten Lankhorst
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30  8:01 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	Daniel Stone, Tomeu Vizoso

Design ideas:

- split up the actual commit into different phases, and have
  completions for each of them. This will be useful for the future
  when we want to interleave phases much more aggressively, for e.g.
  queue depth > 1. For not it's just a minimal optimization compared
  to current common nonblocking implementation patterns from drivers,
  which all stall for the entire commit to complete, including vblank
  waits and cleanups.

- Extract a separate atomic_commit_hw hook since that's the part most
  drivers will need to overwrite, hopefully allowing even more shared
  code.

- Enforce EBUSY seamntics by attaching one of the completions to the
  flip_done vblank event. Side benefit of forcing atomic drivers using
  these helpers to implement event handlign at least semi-correct. I'm
  evil that way ;-)

- Ridiculously modular, as usual.

- The main tracking unit for a commit stays struct drm_atomic_state,
  and the ownership rules for that are unchanged. Ownership still
  gets transferred to the driver (and subsequently to the worker) on
  successful commits. What is added is a small, per-crtc, refcounted
  structure to track pending commits called struct drm_crtc_commit.
  No actual state is attached to that though, it's purely for ordering
  and waiting.

- Dependencies are implicitly handled by assuming that any CRTC part
  of &drm_atomic_state is a dependency, and that the current commit
  must wait for any commits to complete on those CRTC. This way
  drivers can easily add more depencies using
  drm_atomic_get_crtc_state(), which is very natural since in most
  case a dependency exists iff there's some bit of state that needs to
  be cross checked.

  Removing depencies is not possible, drivers simply need to be
  careful to not include every CRTC in a commit if that's not
  necessary. Which is a good idea anyway, since that also avoids
  ww_mutex lock contention.

- Queue depth > 1 sees some prep work in this patch by adding a stall
  paramater to drm_atomic_helper_swap_states(). To be able to push
  commits entirely free-standing and in a deeper queue through the
  back-end the driver must not access any obj->state pointers. This
  means we need to track the old state in drm_atomic_state (much
  easier with the consolidated arrays), and pass them all explicitly
  to driver backends (this will be serious amounts of churn).

  Once that's done stall can be set to false in swap_states.

Features: Contains bugs because totally untested.

v2: Dont ask for flip_done signalling when the CRTC is off and stays
off: Drivers don't handle events in that case. Instead complete right
away. This way future commits don't need to have special-case logic,
but can keep blocking for the flip_done completion.

v3: Tons of fixes:
- Stall for preceeding commit for real, not the current one by
  accident.
- Add WARN_ON in case drivers don't fire the drm event.
- Don't double-free drm events.

v4: Make legacy cursor not stall.

v5: Extend the helper hook to cover the entire commit tail. Some
drivers need special code for cleanup and vblank waiting, this makes
it a bit more useful. Inspired by the rockchip driver.

v6: Add WARN_ON to catch drivers who forget to send out the
drm event.

v7: Fixup the stalls in swap_state for real!!

Cc: Tomeu Vizoso <tomeu.vizoso@gmail.com>
Cc: Daniel Stone <daniels@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_atomic.c             |  22 ++
 drivers/gpu/drm/drm_atomic_helper.c      | 367 ++++++++++++++++++++++++++++---
 drivers/gpu/drm/drm_crtc.c               |   3 +
 drivers/gpu/drm/drm_fops.c               |   6 +
 include/drm/drmP.h                       |   1 +
 include/drm/drm_atomic.h                 |   6 +
 include/drm/drm_atomic_helper.h          |   8 +
 include/drm/drm_crtc.h                   | 119 +++++++++-
 include/drm/drm_modeset_helper_vtables.h |  36 +++
 9 files changed, 535 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 1db198df3014..50aa341ca9ff 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -33,6 +33,20 @@
 
 #include "drm_crtc_internal.h"
 
+static void crtc_commit_free(struct kref *kref)
+{
+	struct drm_crtc_commit *commit =
+		container_of(kref, struct drm_crtc_commit, ref);
+
+	kfree(commit);
+}
+
+void drm_crtc_commit_put(struct drm_crtc_commit *commit)
+{
+	kref_put(&commit->ref, crtc_commit_free);
+}
+EXPORT_SYMBOL(drm_crtc_commit_put);
+
 /**
  * drm_atomic_state_default_release -
  * release memory initialized by drm_atomic_state_init
@@ -148,6 +162,14 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
 
 		crtc->funcs->atomic_destroy_state(crtc,
 						  state->crtcs[i].state);
+
+		if (state->crtcs[i].commit) {
+			kfree(state->crtcs[i].commit->event);
+			state->crtcs[i].commit->event = NULL;
+			drm_crtc_commit_put(state->crtcs[i].commit);
+		}
+
+		state->crtcs[i].commit = NULL;
 		state->crtcs[i].ptr = NULL;
 		state->crtcs[i].state = NULL;
 	}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index fecbb52cbb85..0389917c5dfd 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1113,20 +1113,15 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
 EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
 
 /**
- * drm_atomic_helper_commit - commit validated state object
- * @dev: DRM device
- * @state: the driver state object
- * @nonblocking: whether nonblocking behavior is requested.
+ * drm_atomic_helper_commit_tail - commit atomic update to hardware
+ * @state: new modeset state to be committed
  *
- * This function commits a with drm_atomic_helper_check() pre-validated state
- * object. This can still fail when e.g. the framebuffer reservation fails. For
- * now this doesn't implement nonblocking commits.
+ * This is the default implemenation for the ->atomic_commit_tail() hook of the
+ * &drm_mode_config_helper_funcs vtable.
  *
- * Note that right now this function does not support nonblocking commits, hence
- * driver writers must implement their own version for now. Also note that the
- * default ordering of how the various stages are called is to match the legacy
- * modeset helper library closest. One peculiarity of that is that it doesn't
- * mesh well with runtime PM at all.
+ * Note that the default ordering of how the various stages are called is to
+ * match the legacy modeset helper library closest. One peculiarity of that is
+ * that it doesn't mesh well with runtime PM at all.
  *
  * For drivers supporting runtime PM the recommended sequence is
  *
@@ -1137,6 +1132,70 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
  *     drm_atomic_helper_commit_planes(dev, state, true);
  *
  * See the kerneldoc entries for these three functions for more details.
+ */
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, false);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_hw_done(state);
+
+	drm_atomic_helper_wait_for_vblanks(dev, state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
+
+void commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config_helper_funcs *funcs;
+
+	funcs = dev->mode_config.helper_private;
+
+	drm_atomic_helper_wait_for_fences(dev, state);
+
+	drm_atomic_helper_wait_for_dependencies(state);
+
+	if (funcs && funcs->atomic_commit_tail)
+		funcs->atomic_commit_tail(state);
+	else
+		drm_atomic_helper_commit_tail(state);
+
+	drm_atomic_helper_commit_cleanup_done(state);
+
+	drm_atomic_state_free(state);
+}
+
+static void commit_work(struct work_struct *work)
+{
+	struct drm_atomic_state *state = container_of(work,
+						      struct drm_atomic_state,
+						      commit_work);
+	commit_tail(state);
+}
+
+/**
+ * drm_atomic_helper_commit - commit validated state object
+ * @dev: DRM device
+ * @state: the driver state object
+ * @nonblocking: whether nonblocking behavior is requested.
+ *
+ * This function commits a with drm_atomic_helper_check() pre-validated state
+ * object. This can still fail when e.g. the framebuffer reservation fails. For
+ * now this doesn't implement nonblocking commits.
+ *
+ * Note that right now this function does not support nonblocking commits, hence
+ * driver writers must implement their own version for now.
+ *
+ * Committing the actual hardware state is done through the
+ * ->atomic_commit_tail() callback of the &drm_mode_config_helper_funcs vtable,
+ *  or it's default implementation drm_atomic_helper_commit_tail().
  *
  * RETURNS
  * Zero for success or -errno.
@@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;
+	ret = drm_atomic_helper_setup_commit(state, nonblock);
+	if (ret)
+		return ret;
+
+	INIT_WORK(&state->commit_work, commit_work);
 
 	ret = drm_atomic_helper_prepare_planes(dev, state);
 	if (ret)
@@ -1176,21 +1238,16 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 	 * update. Which is important since compositors need to figure out the
 	 * composition of the next frame right after having submitted the
 	 * current layout.
+	 *
+	 * NOTE: Commit work has multiple phases, first hardware commit, then
+	 * cleanup. We want them to overlap, hence need system_unbound_wq to
+	 * make sure work items don't artifically stall on each another.
 	 */
 
-	drm_atomic_helper_wait_for_fences(dev, state);
-
-	drm_atomic_helper_commit_modeset_disables(dev, state);
-
-	drm_atomic_helper_commit_planes(dev, state, false);
-
-	drm_atomic_helper_commit_modeset_enables(dev, state);
-
-	drm_atomic_helper_wait_for_vblanks(dev, state);
-
-	drm_atomic_helper_cleanup_planes(dev, state);
-
-	drm_atomic_state_free(state);
+	if (nonblock)
+		queue_work(system_unbound_wq, &state->commit_work);
+	else
+		commit_tail(state);
 
 	return 0;
 }
@@ -1234,6 +1291,225 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
  * being displayed.
  */
 
+static int stall_checks(struct drm_crtc *crtc, bool nonblock)
+{
+	struct drm_crtc_commit *commit, *stall_commit = NULL;
+	bool completed = true;
+	int i, ret = 0;
+
+	spin_lock(&crtc->commit_lock);
+	i = 0;
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		if (i == 0) {
+			completed = try_wait_for_completion(&commit->flip_done);
+			/* Userspace is not allowed to get ahead of the previous
+			 * commit with nonblocking ones. */
+			if (!completed && nonblock) {
+				spin_unlock(&crtc->commit_lock);
+				return -EBUSY;
+			}
+		} else if (i == 1) {
+			stall_commit = commit;
+			drm_crtc_commit_get(stall_commit);
+		} else
+			break;
+
+		i++;
+	}
+	spin_unlock(&crtc->commit_lock);
+
+	if (!stall_commit)
+		return 0;
+
+	/* We don't want to let commits get ahead of cleanup work too much,
+	 * stalling on 2nd previous commit means triple-buffer won't ever stall.
+	 */
+	ret = wait_for_completion_interruptible_timeout(&commit->cleanup_done,
+							10*HZ);
+	if (ret == 0)
+		DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
+			  crtc->base.id, crtc->name);
+
+	if (ret == -ERESTARTSYS)
+		ret = -EINTR;
+
+	drm_crtc_commit_put(stall_commit);
+
+	return ret;
+}
+
+/**
+ * drm_atomic_helper_setup_commit - setup possible nonblocking commit
+ *
+ * Returns:
+ *
+ * 0 on success. -EBUSY when userspace schedules nonblocking commits too fast,
+ * -ENOMEM on allocation failures and -EINTR when a signal is pending.
+ */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i, ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = kzalloc(sizeof(*commit), GFP_KERNEL);
+		if (!commit)
+			return -ENOMEM;
+
+		init_completion(&commit->flip_done);
+		init_completion(&commit->hw_done);
+		init_completion(&commit->cleanup_done);
+		INIT_LIST_HEAD(&commit->commit_entry);
+		kref_init(&commit->ref);
+		commit->crtc = crtc;
+
+		state->crtcs[i].commit = commit;
+
+		ret = stall_checks(crtc, nonblock);
+		if (ret)
+			return ret;
+
+		/* Drivers only send out events when at least either current or
+		 * new CRTC state is active. Complete right away if everything
+		 * stays off. */
+		if (!crtc->state->active && !crtc_state->active) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		/* Legacy cursor updates are fully unsynced. */
+		if (state->legacy_cursor_update) {
+			complete_all(&commit->flip_done);
+			continue;
+		}
+
+		if (!crtc_state->event) {
+			commit->event = kzalloc(sizeof(*commit->event),
+						GFP_KERNEL);
+			if (!commit->event)
+				return -ENOMEM;
+
+			crtc_state->event = commit->event;
+		}
+
+		crtc_state->event->base.completion = &commit->flip_done;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
+
+
+static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_commit *commit;
+	int i = 0;
+
+	list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
+		/* skip the first entry, that's the current commit */
+		if (i == 1)
+			return commit;
+		i++;
+	}
+
+	return NULL;
+}
+
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		spin_lock(&crtc->commit_lock);
+		commit = preceeding_commit(crtc);
+		if (commit)
+			drm_crtc_commit_get(commit);
+		spin_unlock(&crtc->commit_lock);
+
+		if (!commit)
+			continue;
+
+		ret = wait_for_completion_timeout(&commit->hw_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		/* Currently no support for overwriting flips, hence
+		 * stall for previous one to execute completely. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+
+		drm_crtc_commit_put(commit);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
+
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+
+		/* backend must have consumed any event by now */
+		WARN_ON(crtc->state->event);
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->hw_done);
+		spin_unlock(&crtc->commit_lock);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
+
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc_commit *commit;
+	int i;
+	long ret;
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		commit = state->crtcs[i].commit;
+		if (!commit)
+			continue;
+		spin_lock(&crtc->commit_lock);
+		complete_all(&commit->cleanup_done);
+
+		WARN_ON(!try_wait_for_completion(&commit->hw_done));
+		
+		/* commit_list borrows our reference, need to remove before we
+		 * clean up our drm_atomic_state. */
+		list_del(&commit->commit_entry);
+		spin_unlock(&crtc->commit_lock);
+
+		/* We must wait for the vblank event to signal our completion
+		 * before releasing our reference, since the vblank work does
+		 * not hold a reference of its own. */
+		ret = wait_for_completion_timeout(&commit->flip_done,
+						  10*HZ);
+		if (ret == 0)
+			DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
+				  crtc->base.id, crtc->name);
+	}
+}
+EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
+
 /**
  * drm_atomic_helper_prepare_planes - prepare plane resources before commit
  * @dev: DRM device
@@ -1553,17 +1829,45 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
  *
  * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
  * contains the old state. Also do any other cleanup required with that state.
+ *
+ * @stall must be set when nonblocking commits for this driver directly access
+ * the ->state pointer of &drm_plane, &drm_crtc or &drm_connector. With the
+ * current atomic helpers this is almost always the case, since the helpers
+ * don't pass the right state structures to the callbacks.
  */
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall)
 {
 	int i;
+	long ret;
 	struct drm_connector *connector;
 	struct drm_connector_state *conn_state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *crtc_state;
 	struct drm_plane *plane;
 	struct drm_plane_state *plane_state;
+	struct drm_crtc_commit *commit;
+
+	if (stall) {
+		for_each_crtc_in_state(state, crtc, crtc_state, i) {
+			spin_lock(&crtc->commit_lock);
+			commit = list_first_entry_or_null(&crtc->commit_list,
+					struct drm_crtc_commit, commit_entry);
+			if (commit)
+				drm_crtc_commit_get(commit);
+			spin_unlock(&crtc->commit_lock);
+
+			if (!commit)
+				continue;
+
+			ret = wait_for_completion_timeout(&commit->hw_done,
+							  10*HZ);
+			if (ret == 0)
+				DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
+					  crtc->base.id, crtc->name);
+			drm_crtc_commit_put(commit);
+		}
+	}
 
 	for_each_connector_in_state(state, connector, conn_state, i) {
 		connector->state->state = state;
@@ -1575,6 +1879,15 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 		crtc->state->state = state;
 		swap(state->crtcs[i].state, crtc->state);
 		crtc->state->state = NULL;
+
+		if (state->crtcs[i].commit) {
+			spin_lock(&crtc->commit_lock);
+			list_add(&state->crtcs[i].commit->commit_entry,
+				 &crtc->commit_list);
+			spin_unlock(&crtc->commit_lock);
+
+			state->crtcs[i].commit->event = NULL;
+		}
 	}
 
 	for_each_plane_in_state(state, plane, plane_state, i) {
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 88cf22052a69..3e52a6ecf6c0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -669,6 +669,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 	crtc->dev = dev;
 	crtc->funcs = funcs;
 
+	INIT_LIST_HEAD(&crtc->commit_list);
+	spin_lock_init(&crtc->commit_lock);
+
 	drm_modeset_lock_init(&crtc->mutex);
 	ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
 	if (ret)
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 4c4b30f7a9f2..5921b203503a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -686,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
 {
 	assert_spin_locked(&dev->event_lock);
 
+	if (e->completion) {
+		/* ->completion might disappear as soon as it signalled. */
+		complete_all(e->completion);
+		e->completion = NULL;
+	}
+
 	if (e->fence) {
 		fence_signal(e->fence);
 		fence_put(e->fence);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 51f751d1c8a4..781db4f562d4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -283,6 +283,7 @@ struct drm_ioctl_desc {
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {
+	struct completion *completion;
 	struct drm_event *event;
 	struct fence *fence;
 	struct list_head link;
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 465a1212f4f0..abec2a3f0225 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,6 +30,12 @@
 
 #include <drm/drm_crtc.h>
 
+void drm_crtc_commit_put(struct drm_crtc_commit *commit);
+static inline void drm_crtc_commit_get(struct drm_crtc_commit *commit)
+{
+	kref_get(&commit->ref);
+}
+
 struct drm_atomic_state * __must_check
 drm_atomic_state_alloc(struct drm_device *dev);
 void drm_atomic_state_clear(struct drm_atomic_state *state);
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 0276447225ed..5fb8c306e16b 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -38,6 +38,7 @@ int drm_atomic_helper_check_planes(struct drm_device *dev,
 			       struct drm_atomic_state *state);
 int drm_atomic_helper_check(struct drm_device *dev,
 			    struct drm_atomic_state *state);
+void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
 int drm_atomic_helper_commit(struct drm_device *dev,
 			     struct drm_atomic_state *state,
 			     bool nonblock);
@@ -74,6 +75,13 @@ void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
 void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 				  bool stall);
 
+/* nonblocking commit helpers */
+int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
+				   bool nonblock);
+void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
+
 /* implementations for legacy interfaces */
 int drm_atomic_helper_update_plane(struct drm_plane *plane,
 				   struct drm_crtc *crtc,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d5d5e343531e..c0edd87fa0ee 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -725,9 +725,6 @@ struct drm_crtc_funcs {
  * @gamma_store: gamma ramp values
  * @helper_private: mid-layer private data
  * @properties: property tracking for this CRTC
- * @state: current atomic state for this CRTC
- * @acquire_ctx: per-CRTC implicit acquire context used by atomic drivers for
- * 	legacy IOCTLs
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
@@ -780,11 +777,37 @@ struct drm_crtc {
 
 	struct drm_object_properties properties;
 
+	/**
+	 * @state:
+	 *
+	 * Current atomic state for this CRTC.
+	 */
 	struct drm_crtc_state *state;
 
-	/*
-	 * For legacy crtc IOCTLs so that atomic drivers can get at the locking
-	 * acquire context.
+	/**
+	 * @commit_list:
+	 *
+	 * List of &drm_crtc_commit structures tracking pending commits.
+	 * Protected by @commit_lock. This list doesn't hold its own full
+	 * reference, but burrows it from the ongoing commit. Commit entries
+	 * must be removed from this list once the commit is fully completed,
+	 * but before it's correspoding &drm_atomic_state gets destroyed.
+	 */
+	struct list_head commit_list;
+
+	/**
+	 * @commit_lock:
+	 *
+	 * Spinlock to protect @commit_list.
+	 */
+	spinlock_t commit_lock;
+
+	/**
+	 * @acquire_ctx:
+	 *
+	 * Per-CRTC implicit acquire context used by atomic drivers for legacy
+	 * IOCTLs, so that atomic drivers can get at the locking acquire
+	 * context.
 	 */
 	struct drm_modeset_acquire_ctx *acquire_ctx;
 };
@@ -1694,6 +1717,78 @@ struct drm_bridge {
 	void *driver_private;
 };
 
+/**
+ * struct drm_crtc_commit - track modeset commits on a CRTC
+ */
+struct drm_crtc_commit {
+	/**
+	 * @crtc:
+	 *
+	 * DRM CRTC for this commit.
+	 */
+	struct drm_crtc *crtc;
+
+	/**
+	 * @ref:
+	 *
+	 * Reference count for this structure. Needed to allow blocking on
+	 * completions without the risk of the completion disappearing
+	 * meanwhile.
+	 */
+	struct kref ref;
+
+	/**
+	 * @flip_done:
+	 *
+	 * Will be signaled when the hardware has flipped to the new set of
+	 * buffers. Signals at the same time as when the drm event for this
+	 * commit is sent to userspace, or when an out-fence is singalled. Note
+	 * that for most hardware, in most cases this happens after @hw_done is
+	 * signalled.
+	 */
+	struct completion flip_done;
+
+	/**
+	 * @hw_done:
+	 *
+	 * Will be signalled when all hw register changes for this commit have
+	 * been written out. Especially when disabling a pipe this can be much
+	 * later than than @flip_done, since that can signal already when the
+	 * screen goes black, whereas to fully shut down a pipe more register
+	 * I/O is required.
+	 *
+	 * Note that this does not need to include separately reference-counted
+	 * resources like backing storage buffer pinning, or runtime pm
+	 * management.
+	 */
+	struct completion hw_done;
+
+	/**
+	 * cleanup_done:
+	 *
+	 * Will be signalled after old buffers have been cleaned up again by
+	 * calling drm_atomic_helper_cleanup_planes(). Since this can only
+	 * happen after a vblank wait completed it might be a bit later. This
+	 * completion is useful to throttle updates and avoid hardware updates
+	 * getting ahead of the buffer cleanup too much.
+	 */
+	struct completion cleanup_done;
+
+	/**
+	 * @commit_entry:
+	 *
+	 * Entry on the per-CRTC commit_list. Protected by crtc->commit_lock.
+	 */
+	struct list_head commit_entry;
+
+	/**
+	 * @event:
+	 *
+	 * &drm_pending_vblank_event pointer to clean up private events.
+	 */
+	struct drm_pending_vblank_event *event;
+};
+
 struct __drm_planes_state {
 	struct drm_plane *ptr;
 	struct drm_plane_state *state;
@@ -1702,6 +1797,7 @@ struct __drm_planes_state {
 struct __drm_crtcs_state {
 	struct drm_crtc *ptr;
 	struct drm_crtc_state *state;
+	struct drm_crtc_commit *commit;
 };
 
 struct __drm_connnectors_state {
@@ -1733,6 +1829,14 @@ struct drm_atomic_state {
 	struct __drm_connnectors_state *connectors;
 
 	struct drm_modeset_acquire_ctx *acquire_ctx;
+
+	/**
+	 * @commit_work:
+	 *
+	 * Work item which can be used by the driver or helpers to execute the
+	 * commit without blocking.
+	 */
+	struct work_struct commit_work;
 };
 
 
@@ -2074,6 +2178,7 @@ struct drm_mode_config_funcs {
  * @async_page_flip: does this device support async flips on the primary plane?
  * @cursor_width: hint to userspace for max cursor width
  * @cursor_height: hint to userspace for max cursor height
+ * @helper_private: mid-layer private data
  *
  * Core mode resource tracking structure.  All CRTC, encoders, and connectors
  * enumerated by the driver are added here, as are global properties.  Some
@@ -2193,6 +2298,8 @@ struct drm_mode_config {
 
 	/* cursor size */
 	uint32_t cursor_width, cursor_height;
+
+	struct drm_mode_config_helper_funcs *helper_private;
 };
 
 /**
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index d4619dc2eecb..145c147705d8 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -925,4 +925,40 @@ static inline void drm_plane_helper_add(struct drm_plane *plane,
 	plane->helper_private = funcs;
 }
 
+/**
+ * struct drm_mode_config_helper_funcs - global modeset helper operations
+ *
+ * These helper functions are used by the atomic helpers.
+ */
+struct drm_mode_config_helper_funcs {
+	/**
+	 * @atomic_commit_tail:
+	 *
+	 * This hook should commit the given atomic state to the hardware, but
+	 * nothing else. This excludes specifically any prepare and cleanup work
+	 * done by drm_atomic_helper_prepare_planes() and
+	 * drm_atomic_helper_cleanup_planes(). And also any synchronization and
+	 * stalling necessary around the around the hardware commit as done for
+	 * example by drm_atomic_helper_wait_for_fences() or
+	 * drm_atomic_helper_wait_for_vblanks().
+	 *
+	 * The function is not required to stall for the commit to actually
+	 * complete and for the new buffers to be displayed on the screen. This
+	 * is handled by properly signalling the &drm_pending_vblank_event in each
+	 * &drm_crtc_state through a call to drm_send_vblank_event() or
+	 * drm_arm_vblank_event(), depending upon how the driver works.
+	 *
+	 * When disabling a CRTC otoh this hook _must_ stall for the commit to
+	 * complete. Vblank waits don't work on disabled CRTC, hence the core
+	 * can't take care of this. And it also can't rely on the vblank event,
+	 * since that can be signalled already when the screen shows black,
+	 * which can happen much earlier than the last hardware access needed to
+	 * shut off the display pipeline completely.
+	 *
+	 * This hook is optional, the default implementation is
+	 * drm_atomic_helper_commit_tail().
+	 */
+	void (*atomic_commit_tail)(struct drm_atomic_state *state);
+};
+
 #endif
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
  2016-05-29 18:35   ` Daniel Vetter
@ 2016-05-30  8:15     ` Maarten Lankhorst
  -1 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30  8:15 UTC (permalink / raw)
  To: linux-snps-arc

Op 29-05-16 om 20:35 schreef Daniel Vetter:
> Committing with block it is not.
>
> Thanks to the fixed up vblank event handling we can just use the
> helper support for nonblocking commits now.
>
> Cc: Carlos Palminha <palminha at synopsys.com>
> Cc: Alexey Brodkin <abrodkin at synopsys.com>
> Cc: linux-snps-arc at lists.infradead.org
> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
This breaks page flip on arc, it uses drm_atomic_helper_page_flip.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
@ 2016-05-30  8:15     ` Maarten Lankhorst
  0 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30  8:15 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, linux-snps-arc,
	Alexey Brodkin

Op 29-05-16 om 20:35 schreef Daniel Vetter:
> Committing with block it is not.
>
> Thanks to the fixed up vblank event handling we can just use the
> helper support for nonblocking commits now.
>
> Cc: Carlos Palminha <palminha@synopsys.com>
> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> Cc: linux-snps-arc@lists.infradead.org
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
This breaks page flip on arc, it uses drm_atomic_helper_page_flip.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-05-29 18:35 ` [PATCH 04/26] drm/rcar-du: " Daniel Vetter
@ 2016-05-30  9:18   ` Laurent Pinchart
  2016-05-30  9:58     ` Maarten Lankhorst
  0 siblings, 1 reply; 76+ messages in thread
From: Laurent Pinchart @ 2016-05-30  9:18 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

Thank you for the patch.

This looks good to me as the resulting code is mostly similar. However, the 
for_each_*_in_state macros end with an for_each_if() that tests if the 
object's state is NULL, which isn't present in this code. I'm wondering 
whether that was an oversight on my side possibly leading to a crash when 
dereferencing a NULL state, or an unneeded check in the macros. Can 
atomic_state->*_states[i] be NULL if atomic_state->*[i] is not NULL ?

On Sunday 29 May 2016 20:35:01 Daniel Vetter wrote:
> We want to hide drm_atomic_state internals better.
> 
> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c   |  8 ++++----
>  drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 ++++++++------------
>  2 files changed, 12 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index e70a4f33d970..f315c55c1f65
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
> {
>  	struct rcar_du_device *rcdu = dev->dev_private;
>  	struct rcar_du_commit *commit;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	unsigned int i;
>  	int ret;
> 
> @@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device
> *dev, /* Wait until all affected CRTCs have completed previous commits and
> * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
> 
>  	spin_lock(&rcdu->commit.wait.lock);
>  	ret = wait_event_interruptible_locked(rcdu->commit.wait,
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index d445e67f78e1..bfe31ca870cc
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> @@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device
> *dev, bool needs_realloc = false;
>  	unsigned int groups = 0;
>  	unsigned int i;
> +	struct drm_plane *drm_plane;
> +	struct drm_plane_state *drm_plane_state;
> 
>  	/* Check if hardware planes need to be reallocated. */
> -	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
> +	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
>  		struct rcar_du_plane_state *plane_state;
>  		struct rcar_du_plane *plane;
>  		unsigned int index;
> 
> -		if (!state->planes[i])
> -			continue;
> -
> -		plane = to_rcar_plane(state->planes[i]);
> -		plane_state = to_rcar_plane_state(state->plane_states[i]);
> +		plane = to_rcar_plane(drm_plane);
> +		plane_state = to_rcar_plane_state(drm_plane_state);
> 
>  		dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
>  			plane->group->index, plane - plane->group->planes);
> @@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device
> *dev, }
> 
>  	/* Reallocate hardware planes for each plane that needs it. */
> -	for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
> +	for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
>  		struct rcar_du_plane_state *plane_state;
>  		struct rcar_du_plane *plane;
>  		unsigned int crtc_planes;
>  		unsigned int free;
>  		int idx;
> 
> -		if (!state->planes[i])
> -			continue;
> -
> -		plane = to_rcar_plane(state->planes[i]);
> -		plane_state = to_rcar_plane_state(state->plane_states[i]);
> +		plane = to_rcar_plane(drm_plane);
> +		plane_state = to_rcar_plane_state(drm_plane_state);
> 
>  		dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
>  			plane->group->index, plane - plane->group->planes);

-- 
Regards,

Laurent Pinchart

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
  2016-05-30  8:15     ` Maarten Lankhorst
@ 2016-05-30  9:24       ` Daniel Vetter
  -1 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30  9:24 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, May 30, 2016@10:15:14AM +0200, Maarten Lankhorst wrote:
> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> > Committing with block it is not.
> >
> > Thanks to the fixed up vblank event handling we can just use the
> > helper support for nonblocking commits now.
> >
> > Cc: Carlos Palminha <palminha at synopsys.com>
> > Cc: Alexey Brodkin <abrodkin at synopsys.com>
> > Cc: linux-snps-arc at lists.infradead.org
> > Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.

How exactly does this break page_flip? Note that the commit to implement
generic nonblocking commit in drm_atomic_helper_commit is _before_ this
patch in the series.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
@ 2016-05-30  9:24       ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30  9:24 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	DRI Development, Carlos Palminha, Daniel Vetter, linux-snps-arc

On Mon, May 30, 2016 at 10:15:14AM +0200, Maarten Lankhorst wrote:
> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> > Committing with block it is not.
> >
> > Thanks to the fixed up vblank event handling we can just use the
> > helper support for nonblocking commits now.
> >
> > Cc: Carlos Palminha <palminha@synopsys.com>
> > Cc: Alexey Brodkin <abrodkin@synopsys.com>
> > Cc: linux-snps-arc@lists.infradead.org
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.

How exactly does this break page_flip? Note that the commit to implement
generic nonblocking commit in drm_atomic_helper_commit is _before_ this
patch in the series.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
  2016-05-30  9:24       ` Daniel Vetter
@ 2016-05-30  9:36         ` Maarten Lankhorst
  -1 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30  9:36 UTC (permalink / raw)
  To: linux-snps-arc

Op 30-05-16 om 11:24 schreef Daniel Vetter:
> On Mon, May 30, 2016@10:15:14AM +0200, Maarten Lankhorst wrote:
>> Op 29-05-16 om 20:35 schreef Daniel Vetter:
>>> Committing with block it is not.
>>>
>>> Thanks to the fixed up vblank event handling we can just use the
>>> helper support for nonblocking commits now.
>>>
>>> Cc: Carlos Palminha <palminha at synopsys.com>
>>> Cc: Alexey Brodkin <abrodkin at synopsys.com>
>>> Cc: linux-snps-arc at lists.infradead.org
>>> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
>> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.
> How exactly does this break page_flip? Note that the commit to implement
> generic nonblocking commit in drm_atomic_helper_commit is _before_ this
> patch in the series.
> -Daniel

This is patch 15/16, I found this in patch 21/26:

@@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
@ 2016-05-30  9:36         ` Maarten Lankhorst
  0 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30  9:36 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	DRI Development, Carlos Palminha, Daniel Vetter, linux-snps-arc

Op 30-05-16 om 11:24 schreef Daniel Vetter:
> On Mon, May 30, 2016 at 10:15:14AM +0200, Maarten Lankhorst wrote:
>> Op 29-05-16 om 20:35 schreef Daniel Vetter:
>>> Committing with block it is not.
>>>
>>> Thanks to the fixed up vblank event handling we can just use the
>>> helper support for nonblocking commits now.
>>>
>>> Cc: Carlos Palminha <palminha@synopsys.com>
>>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
>>> Cc: linux-snps-arc@lists.infradead.org
>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.
> How exactly does this break page_flip? Note that the commit to implement
> generic nonblocking commit in drm_atomic_helper_commit is _before_ this
> patch in the series.
> -Daniel

This is patch 15/16, I found this in patch 21/26:

@@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
 {
 	int ret;
 
-	if (nonblock)
-		return -EBUSY;

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-05-30  9:18   ` Laurent Pinchart
@ 2016-05-30  9:58     ` Maarten Lankhorst
  2016-05-30 14:54       ` [Intel-gfx] " Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30  9:58 UTC (permalink / raw)
  To: Laurent Pinchart, Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> Hi Daniel,
>
> Thank you for the patch.
>
> This looks good to me as the resulting code is mostly similar. However, the 
> for_each_*_in_state macros end with an for_each_if() that tests if the 
> object's state is NULL, which isn't present in this code. I'm wondering 
> whether that was an oversight on my side possibly leading to a crash when 
> dereferencing a NULL state, or an unneeded check in the macros. Can 
> atomic_state->*_states[i] be NULL if atomic_state->*[i] is not NULL ?
Not in any normal case.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-05-29 18:35 ` [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
@ 2016-05-30 11:42   ` Maarten Lankhorst
  2016-05-30 15:05     ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30 11:42 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 29-05-16 om 20:35 schreef Daniel Vetter:
> ... and use it in msm&vc4. Again just want to encapsulate
> drm_atomic_state internals a bit.
>
> The const threading is a bit awkward in vc4 since C sucks, but I still
> think it's worth to enforce this. Eventually I want to make all the
> obj->state pointers const too, but that's a lot more work ...
>
> Cc: Eric Anholt <eric@anholt.net>
> Cc: Rob Clark <robdclark@gmail.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++------
>  drivers/gpu/drm/vc4/vc4_crtc.c           | 11 +++-------
>  drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
>  drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
>  include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
>  5 files changed, 46 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> index 88fe256c1931..6d4086ee0503 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> @@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
>  	 */
>  	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
>  	drm_atomic_crtc_state_for_each_plane(plane, state) {
> -		struct drm_plane_state *pstate;
> +		const struct drm_plane_state *pstate;
>  		if (cnt >= (hw_cfg->lm.nb_stages)) {
>  			dev_err(dev->dev, "too many planes!\n");
>  			return -EINVAL;
>  		}
>  
> -		pstate = state->state->plane_states[drm_plane_index(plane)];
> +		pstate = __drm_atomic_get_current_plane_state(state->state,
> +							      plane);
>  
> -		/* plane might not have changed, in which case take
> -		 * current state:
> -		 */
> -		if (!pstate)
> -			pstate = plane->state;
>  		pstates[cnt].plane = plane;
>  		pstates[cnt].state = to_mdp5_plane_state(pstate);
>  
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 904d0754ad78..703bda170105 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
>  		return -EINVAL;
>  
>  	drm_atomic_crtc_state_for_each_plane(plane, state) {
> -		struct drm_plane_state *plane_state =
> -			state->state->plane_states[drm_plane_index(plane)];
> -
> -		/* plane might not have changed, in which case take
> -		 * current state:
> -		 */
> -		if (!plane_state)
> -			plane_state = plane->state;
> +		const struct drm_plane_state *plane_state =
> +			__drm_atomic_get_current_plane_state(state->state,
> +							     plane);
>  
>  		dlist_count += vc4_plane_dlist_size(plane_state);
>  	}
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 37cac59401d7..c799baabc008 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
>  struct drm_plane *vc4_plane_init(struct drm_device *dev,
>  				 enum drm_plane_type type);
>  u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
> -u32 vc4_plane_dlist_size(struct drm_plane_state *state);
> +u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
>  void vc4_plane_async_set_fb(struct drm_plane *plane,
>  			    struct drm_framebuffer *fb);
>  
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 4037b52fde31..5d2c3d9fd17a 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
>  	return vc4_state->dlist_count;
>  }
>  
> -u32 vc4_plane_dlist_size(struct drm_plane_state *state)
> +u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
>  {
> -	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +	const struct vc4_plane_state *vc4_state =
> +		container_of(state, typeof(*vc4_state), base);
>  
>  	return vc4_state->dlist_count;
>  }
> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> index 92c84e9ab09a..4e97186293be 100644
> --- a/include/drm/drm_atomic.h
> +++ b/include/drm/drm_atomic.h
> @@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
>  	return state->connector_states[index];
>  }
>  
> +/**
> + * __drm_atomic_get_current_plane_state - get current plane state
> + * @state: global atomic state object
> + * @plane: plane to grab
> + *
> + * This function returns the plane state for the given plane, either from
> + * @state, or if the plane isn't part of the atomic state update, from @plane.
> + * This is useful in atomic check callbacks, when drivers need to peek at, but
> + * not change, state of other planes, since it avoids threading an error code
> + * back up the call chain.
> + *
> + * WARNING:
> + *
> + * Note that this function is in general unsafe since it doesn't check for the
> + * required locking for access state structures. Drivers must ensure that it is
> + * save to access the returned state structure through other means. One commone
> + * example is when planes are fixed to a single CRTC, and the driver knows that
> + * the CRTC locks is held already. In that case holding the CRTC locks gives a
> + * read-lock on all planes connected to that CRTC. But if planes can be
> + * reassigned things get more tricky. In that case it's better to use
> + * drm_atomic_get_plane_state and wire up full error handling.
> + *
> + * Returns:
> + *
> + * Read-only pointer to the current plane state.
> + */
> +static inline const struct drm_plane_state *
> +__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
> +				     struct drm_plane *plane)
> +{
> +	if (state->plane_states[drm_plane_index(plane)])
> +		return state->plane_states[drm_plane_index(plane)];
Could use a debug WARN_ON here. Just in case someone tries to use this for a plane that can't be safely checked:

WARN_ON(!plane->state->crtc || !drm_modeset_is_locked(&plane->state->crtc->mutex));

Also use drm_atomic_get_existing_plane_state?

~Maarten
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more
  2016-05-29 18:34 ` [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
@ 2016-05-30 12:17   ` Maarten Lankhorst
  2016-05-30 15:02     ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30 12:17 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 29-05-16 om 20:34 schreef Daniel Vetter:
> This avois leaking drm_atomic_state internals into the helpers. The
> only place where this still happens after this patch is drm_atomic_helper_swap_state().
> It's unavoidable there, and maybe a good indicator we should actually
> move that function into drm_atomic.c.
Would be a good idea, commit is part of atomic core and there's really only one way to do swap_state.
Drivers can swap any required internal state before or after the call.

~Maarten.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-29 18:35 ` [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat Daniel Vetter
@ 2016-05-30 13:08   ` Maarten Lankhorst
  2016-05-30 15:09     ` [Intel-gfx] " Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30 13:08 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Intel Graphics Development

Op 29-05-16 om 20:35 schreef Daniel Vetter:
> - dev is redundant, we have state->atomic
> - add stall parameter, which must be set when swapping needs to stall
>   for preceeding commits to stop looking at ->state pointers. Currently
>   all drivers need this to be, just prep work for a glorious future.
I have to disagree, if you want to stall it should be done in a separate helper before swapping state.
That function should also have the ability to fail, since we haven't called swap_state yet. :)

Maybe with nonblock as parameter, so it could fail with -EBUSY if it would stall, and -EINTR if interrupted?
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +-
>  drivers/gpu/drm/drm_atomic_helper.c          | 8 ++++----
>  drivers/gpu/drm/exynos/exynos_drm_drv.c      | 2 +-
>  drivers/gpu/drm/i915/intel_display.c         | 2 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c       | 2 +-
>  drivers/gpu/drm/msm/msm_atomic.c             | 2 +-
>  drivers/gpu/drm/omapdrm/omap_drv.c           | 2 +-
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c        | 2 +-
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c   | 2 +-
>  drivers/gpu/drm/sti/sti_drv.c                | 2 +-
>  drivers/gpu/drm/tegra/drm.c                  | 2 +-
>  drivers/gpu/drm/vc4/vc4_kms.c                | 2 +-
>  include/drm/drm_atomic_helper.h              | 4 ++--
>  13 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index 6485fa5bee8b..9ecf16c7911d 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -519,7 +519,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
>  	}
>  
>  	/* Swap the state, this is the point of no return. */
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (async)
>  		queue_work(dc->wq, &commit->work);
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 5298eb668ca7..fecbb52cbb85 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -1160,7 +1160,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
>  	 * the software side now.
>  	 */
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	/*
>  	 * Everything below can be run asynchronously without the need to grab
> @@ -1531,8 +1531,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
>  
>  /**
>   * drm_atomic_helper_swap_state - store atomic state into current sw state
> - * @dev: DRM device
>   * @state: atomic state
> + * @stall: stall for proceeding commits
>   *
>   * This function stores the atomic state into the current state pointers in all
>   * driver objects. It should be called after all failing steps have been done
> @@ -1554,8 +1554,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
>   * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
>   * contains the old state. Also do any other cleanup required with that state.
>   */
> -void drm_atomic_helper_swap_state(struct drm_device *dev,
> -				  struct drm_atomic_state *state)
> +void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> +				  bool stall)
>  {
>  	int i;
>  	struct drm_connector *connector;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index cabc5fd0246d..deba76982358 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -299,7 +299,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  	priv->pending |= commit->crtcs;
>  	spin_unlock(&priv->lock);
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (nonblock)
>  		schedule_work(&commit->work);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 9ccd76699f48..d32274071393 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13660,7 +13660,7 @@ static int intel_atomic_commit(struct drm_device *dev,
>  		return ret;
>  	}
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  	dev_priv->wm.distrust_bios_wm = false;
>  	dev_priv->wm.skl_results = intel_state->wm_results;
>  	intel_shared_dpll_commit(state);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 06a417b2f91e..c33bf98c5d5e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -91,7 +91,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
>  	mutex_lock(&private->commit.lock);
>  	flush_work(&private->commit.work);
>  
> -	drm_atomic_helper_swap_state(drm, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (async)
>  		mtk_atomic_schedule(private, state);
> diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
> index 9c0e4261dbba..d02bd6a50e90 100644
> --- a/drivers/gpu/drm/msm/msm_atomic.c
> +++ b/drivers/gpu/drm/msm/msm_atomic.c
> @@ -238,7 +238,7 @@ int msm_atomic_commit(struct drm_device *dev,
>  	 * the software side now.
>  	 */
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	/*
>  	 * Everything below can be run asynchronously without the need to grab
> diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> index d86f5479345b..5d8377aad639 100644
> --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> @@ -175,7 +175,7 @@ static int omap_atomic_commit(struct drm_device *dev,
>  	spin_unlock(&priv->commit.lock);
>  
>  	/* Swap the state, this is the point of no return. */
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (nonblock)
>  		schedule_work(&commit->work);
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index f315c55c1f65..3d04a506cf33 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -327,7 +327,7 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
>  	}
>  
>  	/* Swap the state, this is the point of no return. */
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (nonblock)
>  		schedule_work(&commit->work);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 03913b483506..5ea141dfae5b 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -290,7 +290,7 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
>  	mutex_lock(&commit->lock);
>  	flush_work(&commit->work);
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	commit->dev = dev;
>  	commit->state = state;
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index b440617a7019..dd2c400c4a46 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -215,7 +215,7 @@ static int sti_atomic_commit(struct drm_device *drm,
>  	 * the software side now.
>  	 */
>  
> -	drm_atomic_helper_swap_state(drm, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (nonblock)
>  		sti_atomic_schedule(private, state);
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index b59c3bf0df44..a177a42a9849 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -93,7 +93,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
>  	 * the software side now.
>  	 */
>  
> -	drm_atomic_helper_swap_state(drm, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	if (nonblock)
>  		tegra_atomic_schedule(tegra, state);
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 39c0b2048bfd..8f4d5ffc32be 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -148,7 +148,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
>  	 * the software side now.
>  	 */
>  
> -	drm_atomic_helper_swap_state(dev, state);
> +	drm_atomic_helper_swap_state(state, true);
>  
>  	/*
>  	 * Everything below can be run asynchronously without the need to grab
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index d473dcc91f54..0276447225ed 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -71,8 +71,8 @@ void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_sta
>  void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
>  					      bool atomic);
>  
> -void drm_atomic_helper_swap_state(struct drm_device *dev,
> -				  struct drm_atomic_state *state);
> +void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> +				  bool stall);
>  
>  /* implementations for legacy interfaces */
>  int drm_atomic_helper_update_plane(struct drm_plane *plane,


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state
  2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
@ 2016-05-30 13:10   ` Maarten Lankhorst
  0 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-30 13:10 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Op 29-05-16 om 20:34 schreef Daniel Vetter:
> We want to encapsulate the drm_atomic_state internals.
>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 50ff90aea721..3e6d9ff8840a 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -223,7 +223,9 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
>  				continue;
>  			}
>  
> -			plane_state = to_intel_plane_state(drm_state->plane_states[i]);
> +			plane_state = to_intel_plane_state(
> +				drm_atomic_get_existing_plane_state(drm_state,
> +								    plane));
>  			scaler_id = &plane_state->scaler_id;
>  		}
>  

Use intel_atomic_get_existing_plane_state with intel_plane. :)

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-05-30  9:58     ` Maarten Lankhorst
@ 2016-05-30 14:54       ` Daniel Vetter
  2016-06-02 22:54         ` Laurent Pinchart
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 14:54 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, Laurent Pinchart,
	DRI Development, Daniel Vetter

On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
> Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> > Hi Daniel,
> >
> > Thank you for the patch.
> >
> > This looks good to me as the resulting code is mostly similar. However, the 
> > for_each_*_in_state macros end with an for_each_if() that tests if the 
> > object's state is NULL, which isn't present in this code. I'm wondering 
> > whether that was an oversight on my side possibly leading to a crash when 
> > dereferencing a NULL state, or an unneeded check in the macros. Can 
> > atomic_state->*_states[i] be NULL if atomic_state->*[i] is not NULL ?
> Not in any normal case.

Yeah, the drm_atomic_get_*_state functions only ever fill in both of
neither. If this gets out of sync it's a bug ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-29 18:35 ` [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
@ 2016-05-30 14:59   ` Ville Syrjälä
  2016-05-30 15:13     ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Ville Syrjälä @ 2016-05-30 14:59 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Sun, May 29, 2016 at 08:35:05PM +0200, Daniel Vetter wrote:
> It's kinda pointless to have 2 separate mallocs for these. And when we
> add more per-connector state in the future it's even more pointless.
> 
> Right now there's no such thing planned, but both Gustavo's per-crtc
> fence patches, and some nonblocking commit helpers I'm playing around
> with will add more per-crtc stuff. It makes sense to also consolidate
> connectors, just for consistency.
> 
> In the future we can use this to store a pointer to the preceeding
> state, making an atomic update entirely free-standing. This will be
> needed to be able to queue them up with a depth > 1.
> 
> Cc: Gustavo Padovan <gustavo@padovan.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
>  drivers/gpu/drm/drm_atomic_helper.c |  2 +-
>  include/drm/drm_atomic.h            | 10 +++++-----
>  include/drm/drm_crtc.h              | 11 +++++++----
>  4 files changed, 22 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 3ff1ed7b33db..a6395e9654af 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -44,7 +44,6 @@
>  void drm_atomic_state_default_release(struct drm_atomic_state *state)
>  {
>  	kfree(state->connectors);
> -	kfree(state->connector_states);
>  	kfree(state->crtcs);
>  	kfree(state->crtc_states);
>  	kfree(state->planes);
> @@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
>  	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
>  
>  	for (i = 0; i < state->num_connector; i++) {
> -		struct drm_connector *connector = state->connectors[i];
> +		struct drm_connector *connector = state->connectors[i].ptr;

'ptr' is not a very good name.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more
  2016-05-30 12:17   ` Maarten Lankhorst
@ 2016-05-30 15:02     ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:02 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 02:17:06PM +0200, Maarten Lankhorst wrote:
> Op 29-05-16 om 20:34 schreef Daniel Vetter:
> > This avois leaking drm_atomic_state internals into the helpers. The
> > only place where this still happens after this patch is drm_atomic_helper_swap_state().
> > It's unavoidable there, and maybe a good indicator we should actually
> > move that function into drm_atomic.c.
> Would be a good idea, commit is part of atomic core and there's really only one way to do swap_state.
> Drivers can swap any required internal state before or after the call.

Later on I'm adding some of the nonblocking stuff to swap_state, and I
think at least the nonblocking support should be part of the helpers.

I'm torn again about where to put it ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-05-30 11:42   ` [Intel-gfx] " Maarten Lankhorst
@ 2016-05-30 15:05     ` Daniel Vetter
  2016-05-31  8:35       ` [Intel-gfx] " Maarten Lankhorst
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:05 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 01:42:40PM +0200, Maarten Lankhorst wrote:
> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> > ... and use it in msm&vc4. Again just want to encapsulate
> > drm_atomic_state internals a bit.
> >
> > The const threading is a bit awkward in vc4 since C sucks, but I still
> > think it's worth to enforce this. Eventually I want to make all the
> > obj->state pointers const too, but that's a lot more work ...
> >
> > Cc: Eric Anholt <eric@anholt.net>
> > Cc: Rob Clark <robdclark@gmail.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++------
> >  drivers/gpu/drm/vc4/vc4_crtc.c           | 11 +++-------
> >  drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
> >  drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
> >  include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
> >  5 files changed, 46 insertions(+), 18 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > index 88fe256c1931..6d4086ee0503 100644
> > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > @@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
> >  	 */
> >  	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
> >  	drm_atomic_crtc_state_for_each_plane(plane, state) {
> > -		struct drm_plane_state *pstate;
> > +		const struct drm_plane_state *pstate;
> >  		if (cnt >= (hw_cfg->lm.nb_stages)) {
> >  			dev_err(dev->dev, "too many planes!\n");
> >  			return -EINVAL;
> >  		}
> >  
> > -		pstate = state->state->plane_states[drm_plane_index(plane)];
> > +		pstate = __drm_atomic_get_current_plane_state(state->state,
> > +							      plane);
> >  
> > -		/* plane might not have changed, in which case take
> > -		 * current state:
> > -		 */
> > -		if (!pstate)
> > -			pstate = plane->state;
> >  		pstates[cnt].plane = plane;
> >  		pstates[cnt].state = to_mdp5_plane_state(pstate);
> >  
> > diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> > index 904d0754ad78..703bda170105 100644
> > --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> > +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> > @@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
> >  		return -EINVAL;
> >  
> >  	drm_atomic_crtc_state_for_each_plane(plane, state) {
> > -		struct drm_plane_state *plane_state =
> > -			state->state->plane_states[drm_plane_index(plane)];
> > -
> > -		/* plane might not have changed, in which case take
> > -		 * current state:
> > -		 */
> > -		if (!plane_state)
> > -			plane_state = plane->state;
> > +		const struct drm_plane_state *plane_state =
> > +			__drm_atomic_get_current_plane_state(state->state,
> > +							     plane);
> >  
> >  		dlist_count += vc4_plane_dlist_size(plane_state);
> >  	}
> > diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> > index 37cac59401d7..c799baabc008 100644
> > --- a/drivers/gpu/drm/vc4/vc4_drv.h
> > +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> > @@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
> >  struct drm_plane *vc4_plane_init(struct drm_device *dev,
> >  				 enum drm_plane_type type);
> >  u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
> > -u32 vc4_plane_dlist_size(struct drm_plane_state *state);
> > +u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
> >  void vc4_plane_async_set_fb(struct drm_plane *plane,
> >  			    struct drm_framebuffer *fb);
> >  
> > diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> > index 4037b52fde31..5d2c3d9fd17a 100644
> > --- a/drivers/gpu/drm/vc4/vc4_plane.c
> > +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> > @@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
> >  	return vc4_state->dlist_count;
> >  }
> >  
> > -u32 vc4_plane_dlist_size(struct drm_plane_state *state)
> > +u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
> >  {
> > -	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> > +	const struct vc4_plane_state *vc4_state =
> > +		container_of(state, typeof(*vc4_state), base);
> >  
> >  	return vc4_state->dlist_count;
> >  }
> > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
> > index 92c84e9ab09a..4e97186293be 100644
> > --- a/include/drm/drm_atomic.h
> > +++ b/include/drm/drm_atomic.h
> > @@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
> >  	return state->connector_states[index];
> >  }
> >  
> > +/**
> > + * __drm_atomic_get_current_plane_state - get current plane state
> > + * @state: global atomic state object
> > + * @plane: plane to grab
> > + *
> > + * This function returns the plane state for the given plane, either from
> > + * @state, or if the plane isn't part of the atomic state update, from @plane.
> > + * This is useful in atomic check callbacks, when drivers need to peek at, but
> > + * not change, state of other planes, since it avoids threading an error code
> > + * back up the call chain.
> > + *
> > + * WARNING:
> > + *
> > + * Note that this function is in general unsafe since it doesn't check for the
> > + * required locking for access state structures. Drivers must ensure that it is
> > + * save to access the returned state structure through other means. One commone
> > + * example is when planes are fixed to a single CRTC, and the driver knows that
> > + * the CRTC locks is held already. In that case holding the CRTC locks gives a
> > + * read-lock on all planes connected to that CRTC. But if planes can be
> > + * reassigned things get more tricky. In that case it's better to use
> > + * drm_atomic_get_plane_state and wire up full error handling.
> > + *
> > + * Returns:
> > + *
> > + * Read-only pointer to the current plane state.
> > + */
> > +static inline const struct drm_plane_state *
> > +__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
> > +				     struct drm_plane *plane)
> > +{
> > +	if (state->plane_states[drm_plane_index(plane)])
> > +		return state->plane_states[drm_plane_index(plane)];
> Could use a debug WARN_ON here. Just in case someone tries to use this for a plane that can't be safely checked:
> 
> WARN_ON(!plane->state->crtc || !drm_modeset_is_locked(&plane->state->crtc->mutex));

If you have hw like i915, where you can't move planes, this check isn't
good enough, because plane->state->crtc might be NULL, but if you hold the
right crtc mutex it's still perfectly safe. That's why I didn't add that
check, and instead typed the really long warning.

> Also use drm_atomic_get_existing_plane_state?

Hm, feels like overkill since this is a core atomic function. We don't use
get_existing_* in drm_atomic.c much either.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-30 13:08   ` Maarten Lankhorst
@ 2016-05-30 15:09     ` Daniel Vetter
  2016-05-31  8:43       ` Maarten Lankhorst
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:09 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, May 30, 2016 at 03:08:39PM +0200, Maarten Lankhorst wrote:
> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> > - dev is redundant, we have state->atomic
> > - add stall parameter, which must be set when swapping needs to stall
> >   for preceeding commits to stop looking at ->state pointers. Currently
> >   all drivers need this to be, just prep work for a glorious future.
> I have to disagree, if you want to stall it should be done in a separate helper before swapping state.
> That function should also have the ability to fail, since we haven't called swap_state yet. :)
> 
> Maybe with nonblock as parameter, so it could fail with -EBUSY if it would stall, and -EINTR if interrupted?

This is not the stalling you're thinking of. The EBUSY check is in
drm_atomic_helper_setup_commit (and as such entirely optional).

And if you don't ever use the nonblocking helpers, no struct
drm_crtc_commit will ever show up in crtc->commit_list, which means this
here also doesn't do anything.

This stall here is just to make sure that the previous commit doesn't get
confused because we've ripped out crtc/plane/connector->state from
underneath it. And as soon as we add previous_state pointers to
drm_atomic_state and wire it up through all the hooks we can set
stall=false here, since then pipelining with a queue depth > 1 is
possible.
-Daniel


> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > ---
> >  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 +-
> >  drivers/gpu/drm/drm_atomic_helper.c          | 8 ++++----
> >  drivers/gpu/drm/exynos/exynos_drm_drv.c      | 2 +-
> >  drivers/gpu/drm/i915/intel_display.c         | 2 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c       | 2 +-
> >  drivers/gpu/drm/msm/msm_atomic.c             | 2 +-
> >  drivers/gpu/drm/omapdrm/omap_drv.c           | 2 +-
> >  drivers/gpu/drm/rcar-du/rcar_du_kms.c        | 2 +-
> >  drivers/gpu/drm/rockchip/rockchip_drm_fb.c   | 2 +-
> >  drivers/gpu/drm/sti/sti_drv.c                | 2 +-
> >  drivers/gpu/drm/tegra/drm.c                  | 2 +-
> >  drivers/gpu/drm/vc4/vc4_kms.c                | 2 +-
> >  include/drm/drm_atomic_helper.h              | 4 ++--
> >  13 files changed, 17 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> > index 6485fa5bee8b..9ecf16c7911d 100644
> > --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> > +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> > @@ -519,7 +519,7 @@ static int atmel_hlcdc_dc_atomic_commit(struct drm_device *dev,
> >  	}
> >  
> >  	/* Swap the state, this is the point of no return. */
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (async)
> >  		queue_work(dc->wq, &commit->work);
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 5298eb668ca7..fecbb52cbb85 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -1160,7 +1160,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
> >  	 * the software side now.
> >  	 */
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	/*
> >  	 * Everything below can be run asynchronously without the need to grab
> > @@ -1531,8 +1531,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
> >  
> >  /**
> >   * drm_atomic_helper_swap_state - store atomic state into current sw state
> > - * @dev: DRM device
> >   * @state: atomic state
> > + * @stall: stall for proceeding commits
> >   *
> >   * This function stores the atomic state into the current state pointers in all
> >   * driver objects. It should be called after all failing steps have been done
> > @@ -1554,8 +1554,8 @@ EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
> >   * 5. Call drm_atomic_helper_cleanup_planes() with @state, which since step 3
> >   * contains the old state. Also do any other cleanup required with that state.
> >   */
> > -void drm_atomic_helper_swap_state(struct drm_device *dev,
> > -				  struct drm_atomic_state *state)
> > +void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> > +				  bool stall)
> >  {
> >  	int i;
> >  	struct drm_connector *connector;
> > diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> > index cabc5fd0246d..deba76982358 100644
> > --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> > +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> > @@ -299,7 +299,7 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
> >  	priv->pending |= commit->crtcs;
> >  	spin_unlock(&priv->lock);
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (nonblock)
> >  		schedule_work(&commit->work);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 9ccd76699f48..d32274071393 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -13660,7 +13660,7 @@ static int intel_atomic_commit(struct drm_device *dev,
> >  		return ret;
> >  	}
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  	dev_priv->wm.distrust_bios_wm = false;
> >  	dev_priv->wm.skl_results = intel_state->wm_results;
> >  	intel_shared_dpll_commit(state);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index 06a417b2f91e..c33bf98c5d5e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -91,7 +91,7 @@ static int mtk_atomic_commit(struct drm_device *drm,
> >  	mutex_lock(&private->commit.lock);
> >  	flush_work(&private->commit.work);
> >  
> > -	drm_atomic_helper_swap_state(drm, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (async)
> >  		mtk_atomic_schedule(private, state);
> > diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
> > index 9c0e4261dbba..d02bd6a50e90 100644
> > --- a/drivers/gpu/drm/msm/msm_atomic.c
> > +++ b/drivers/gpu/drm/msm/msm_atomic.c
> > @@ -238,7 +238,7 @@ int msm_atomic_commit(struct drm_device *dev,
> >  	 * the software side now.
> >  	 */
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	/*
> >  	 * Everything below can be run asynchronously without the need to grab
> > diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
> > index d86f5479345b..5d8377aad639 100644
> > --- a/drivers/gpu/drm/omapdrm/omap_drv.c
> > +++ b/drivers/gpu/drm/omapdrm/omap_drv.c
> > @@ -175,7 +175,7 @@ static int omap_atomic_commit(struct drm_device *dev,
> >  	spin_unlock(&priv->commit.lock);
> >  
> >  	/* Swap the state, this is the point of no return. */
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (nonblock)
> >  		schedule_work(&commit->work);
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > index f315c55c1f65..3d04a506cf33 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> > @@ -327,7 +327,7 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
> >  	}
> >  
> >  	/* Swap the state, this is the point of no return. */
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (nonblock)
> >  		schedule_work(&commit->work);
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > index 03913b483506..5ea141dfae5b 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > @@ -290,7 +290,7 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
> >  	mutex_lock(&commit->lock);
> >  	flush_work(&commit->work);
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	commit->dev = dev;
> >  	commit->state = state;
> > diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> > index b440617a7019..dd2c400c4a46 100644
> > --- a/drivers/gpu/drm/sti/sti_drv.c
> > +++ b/drivers/gpu/drm/sti/sti_drv.c
> > @@ -215,7 +215,7 @@ static int sti_atomic_commit(struct drm_device *drm,
> >  	 * the software side now.
> >  	 */
> >  
> > -	drm_atomic_helper_swap_state(drm, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (nonblock)
> >  		sti_atomic_schedule(private, state);
> > diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> > index b59c3bf0df44..a177a42a9849 100644
> > --- a/drivers/gpu/drm/tegra/drm.c
> > +++ b/drivers/gpu/drm/tegra/drm.c
> > @@ -93,7 +93,7 @@ static int tegra_atomic_commit(struct drm_device *drm,
> >  	 * the software side now.
> >  	 */
> >  
> > -	drm_atomic_helper_swap_state(drm, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	if (nonblock)
> >  		tegra_atomic_schedule(tegra, state);
> > diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> > index 39c0b2048bfd..8f4d5ffc32be 100644
> > --- a/drivers/gpu/drm/vc4/vc4_kms.c
> > +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> > @@ -148,7 +148,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
> >  	 * the software side now.
> >  	 */
> >  
> > -	drm_atomic_helper_swap_state(dev, state);
> > +	drm_atomic_helper_swap_state(state, true);
> >  
> >  	/*
> >  	 * Everything below can be run asynchronously without the need to grab
> > diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> > index d473dcc91f54..0276447225ed 100644
> > --- a/include/drm/drm_atomic_helper.h
> > +++ b/include/drm/drm_atomic_helper.h
> > @@ -71,8 +71,8 @@ void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_sta
> >  void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
> >  					      bool atomic);
> >  
> > -void drm_atomic_helper_swap_state(struct drm_device *dev,
> > -				  struct drm_atomic_state *state);
> > +void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> > +				  bool stall);
> >  
> >  /* implementations for legacy interfaces */
> >  int drm_atomic_helper_update_plane(struct drm_plane *plane,
> 
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
  2016-05-30  9:36         ` Maarten Lankhorst
@ 2016-05-30 15:10           ` Daniel Vetter
  -1 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:10 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, May 30, 2016@11:36:06AM +0200, Maarten Lankhorst wrote:
> Op 30-05-16 om 11:24 schreef Daniel Vetter:
> > On Mon, May 30, 2016@10:15:14AM +0200, Maarten Lankhorst wrote:
> >> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> >>> Committing with block it is not.
> >>>
> >>> Thanks to the fixed up vblank event handling we can just use the
> >>> helper support for nonblocking commits now.
> >>>
> >>> Cc: Carlos Palminha <palminha at synopsys.com>
> >>> Cc: Alexey Brodkin <abrodkin at synopsys.com>
> >>> Cc: linux-snps-arc at lists.infradead.org
> >>> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
> >> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.
> > How exactly does this break page_flip? Note that the commit to implement
> > generic nonblocking commit in drm_atomic_helper_commit is _before_ this
> > patch in the series.
> > -Daniel
> 
> This is patch 15/16, I found this in patch 21/26:
> 
> @@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
>  {
>  	int ret;
>  
> -	if (nonblock)
> -		return -EBUSY;

Oh right, I mixed things up. Most of the prep work is for drm event
handling. We need to do that _before_ the non-blocking commit lands for
the drivers that just directly reuse drm_atomic_helper_commit, since the
nonblocking helpers will time out when drm events don't work.

But this one indeed should only happen after that commit. I'll reorder.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 15/26] drm/arc: Implement nonblocking commit correctly
@ 2016-05-30 15:10           ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:10 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, Alexey Brodkin,
	DRI Development, Daniel Vetter, linux-snps-arc

On Mon, May 30, 2016 at 11:36:06AM +0200, Maarten Lankhorst wrote:
> Op 30-05-16 om 11:24 schreef Daniel Vetter:
> > On Mon, May 30, 2016 at 10:15:14AM +0200, Maarten Lankhorst wrote:
> >> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> >>> Committing with block it is not.
> >>>
> >>> Thanks to the fixed up vblank event handling we can just use the
> >>> helper support for nonblocking commits now.
> >>>
> >>> Cc: Carlos Palminha <palminha@synopsys.com>
> >>> Cc: Alexey Brodkin <abrodkin@synopsys.com>
> >>> Cc: linux-snps-arc@lists.infradead.org
> >>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >> This breaks page flip on arc, it uses drm_atomic_helper_page_flip.
> > How exactly does this break page_flip? Note that the commit to implement
> > generic nonblocking commit in drm_atomic_helper_commit is _before_ this
> > patch in the series.
> > -Daniel
> 
> This is patch 15/16, I found this in patch 21/26:
> 
> @@ -1147,8 +1206,11 @@ int drm_atomic_helper_commit(struct drm_device *dev,
>  {
>  	int ret;
>  
> -	if (nonblock)
> -		return -EBUSY;

Oh right, I mixed things up. Most of the prep work is for drm event
handling. We need to do that _before_ the non-blocking commit lands for
the drivers that just directly reuse drm_atomic_helper_commit, since the
nonblocking helpers will time out when drm events don't work.

But this one indeed should only happen after that commit. I'll reorder.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-30 14:59   ` Ville Syrjälä
@ 2016-05-30 15:13     ` Daniel Vetter
  2016-05-30 15:25       ` [Intel-gfx] " Ville Syrjälä
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:13 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 05:59:24PM +0300, Ville Syrjälä wrote:
> On Sun, May 29, 2016 at 08:35:05PM +0200, Daniel Vetter wrote:
> > It's kinda pointless to have 2 separate mallocs for these. And when we
> > add more per-connector state in the future it's even more pointless.
> > 
> > Right now there's no such thing planned, but both Gustavo's per-crtc
> > fence patches, and some nonblocking commit helpers I'm playing around
> > with will add more per-crtc stuff. It makes sense to also consolidate
> > connectors, just for consistency.
> > 
> > In the future we can use this to store a pointer to the preceeding
> > state, making an atomic update entirely free-standing. This will be
> > needed to be able to queue them up with a depth > 1.
> > 
> > Cc: Gustavo Padovan <gustavo@padovan.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
> >  drivers/gpu/drm/drm_atomic_helper.c |  2 +-
> >  include/drm/drm_atomic.h            | 10 +++++-----
> >  include/drm/drm_crtc.h              | 11 +++++++----
> >  4 files changed, 22 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 3ff1ed7b33db..a6395e9654af 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -44,7 +44,6 @@
> >  void drm_atomic_state_default_release(struct drm_atomic_state *state)
> >  {
> >  	kfree(state->connectors);
> > -	kfree(state->connector_states);
> >  	kfree(state->crtcs);
> >  	kfree(state->crtc_states);
> >  	kfree(state->planes);
> > @@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
> >  	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
> >  
> >  	for (i = 0; i < state->num_connector; i++) {
> > -		struct drm_connector *connector = state->connectors[i];
> > +		struct drm_connector *connector = state->connectors[i].ptr;
> 
> 'ptr' is not a very good name.

Suggestions for something better? I was lacking good inspiration ...
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-30 15:13     ` Daniel Vetter
@ 2016-05-30 15:25       ` Ville Syrjälä
  2016-05-30 15:33         ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Ville Syrjälä @ 2016-05-30 15:25 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 05:13:56PM +0200, Daniel Vetter wrote:
> On Mon, May 30, 2016 at 05:59:24PM +0300, Ville Syrjälä wrote:
> > On Sun, May 29, 2016 at 08:35:05PM +0200, Daniel Vetter wrote:
> > > It's kinda pointless to have 2 separate mallocs for these. And when we
> > > add more per-connector state in the future it's even more pointless.
> > > 
> > > Right now there's no such thing planned, but both Gustavo's per-crtc
> > > fence patches, and some nonblocking commit helpers I'm playing around
> > > with will add more per-crtc stuff. It makes sense to also consolidate
> > > connectors, just for consistency.
> > > 
> > > In the future we can use this to store a pointer to the preceeding
> > > state, making an atomic update entirely free-standing. This will be
> > > needed to be able to queue them up with a depth > 1.
> > > 
> > > Cc: Gustavo Padovan <gustavo@padovan.org>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > ---
> > >  drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
> > >  drivers/gpu/drm/drm_atomic_helper.c |  2 +-
> > >  include/drm/drm_atomic.h            | 10 +++++-----
> > >  include/drm/drm_crtc.h              | 11 +++++++----
> > >  4 files changed, 22 insertions(+), 28 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > index 3ff1ed7b33db..a6395e9654af 100644
> > > --- a/drivers/gpu/drm/drm_atomic.c
> > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > @@ -44,7 +44,6 @@
> > >  void drm_atomic_state_default_release(struct drm_atomic_state *state)
> > >  {
> > >  	kfree(state->connectors);
> > > -	kfree(state->connector_states);
> > >  	kfree(state->crtcs);
> > >  	kfree(state->crtc_states);
> > >  	kfree(state->planes);
> > > @@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
> > >  	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
> > >  
> > >  	for (i = 0; i < state->num_connector; i++) {
> > > -		struct drm_connector *connector = state->connectors[i];
> > > +		struct drm_connector *connector = state->connectors[i].ptr;
> > 
> > 'ptr' is not a very good name.
> 
> Suggestions for something better? I was lacking good inspiration ...

Maybe just 'connector' ?

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-30 15:25       ` [Intel-gfx] " Ville Syrjälä
@ 2016-05-30 15:33         ` Daniel Vetter
  2016-05-30 15:45           ` Ville Syrjälä
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:33 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 06:25:50PM +0300, Ville Syrjälä wrote:
> On Mon, May 30, 2016 at 05:13:56PM +0200, Daniel Vetter wrote:
> > On Mon, May 30, 2016 at 05:59:24PM +0300, Ville Syrjälä wrote:
> > > On Sun, May 29, 2016 at 08:35:05PM +0200, Daniel Vetter wrote:
> > > > It's kinda pointless to have 2 separate mallocs for these. And when we
> > > > add more per-connector state in the future it's even more pointless.
> > > > 
> > > > Right now there's no such thing planned, but both Gustavo's per-crtc
> > > > fence patches, and some nonblocking commit helpers I'm playing around
> > > > with will add more per-crtc stuff. It makes sense to also consolidate
> > > > connectors, just for consistency.
> > > > 
> > > > In the future we can use this to store a pointer to the preceeding
> > > > state, making an atomic update entirely free-standing. This will be
> > > > needed to be able to queue them up with a depth > 1.
> > > > 
> > > > Cc: Gustavo Padovan <gustavo@padovan.org>
> > > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
> > > >  drivers/gpu/drm/drm_atomic_helper.c |  2 +-
> > > >  include/drm/drm_atomic.h            | 10 +++++-----
> > > >  include/drm/drm_crtc.h              | 11 +++++++----
> > > >  4 files changed, 22 insertions(+), 28 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > > index 3ff1ed7b33db..a6395e9654af 100644
> > > > --- a/drivers/gpu/drm/drm_atomic.c
> > > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > > @@ -44,7 +44,6 @@
> > > >  void drm_atomic_state_default_release(struct drm_atomic_state *state)
> > > >  {
> > > >  	kfree(state->connectors);
> > > > -	kfree(state->connector_states);
> > > >  	kfree(state->crtcs);
> > > >  	kfree(state->crtc_states);
> > > >  	kfree(state->planes);
> > > > @@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
> > > >  	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
> > > >  
> > > >  	for (i = 0; i < state->num_connector; i++) {
> > > > -		struct drm_connector *connector = state->connectors[i];
> > > > +		struct drm_connector *connector = state->connectors[i].ptr;
> > > 
> > > 'ptr' is not a very good name.
> > 
> > Suggestions for something better? I was lacking good inspiration ...
> 
> Maybe just 'connector' ?

state->connectors[i].connector is really long, and makes a lot of code
look ugly. "obj" might be a bit better than "ptr" at least. Something
else?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-30 15:33         ` Daniel Vetter
@ 2016-05-30 15:45           ` Ville Syrjälä
  2016-05-30 15:48             ` [Intel-gfx] " Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Ville Syrjälä @ 2016-05-30 15:45 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Mon, May 30, 2016 at 05:33:56PM +0200, Daniel Vetter wrote:
> On Mon, May 30, 2016 at 06:25:50PM +0300, Ville Syrjälä wrote:
> > On Mon, May 30, 2016 at 05:13:56PM +0200, Daniel Vetter wrote:
> > > On Mon, May 30, 2016 at 05:59:24PM +0300, Ville Syrjälä wrote:
> > > > On Sun, May 29, 2016 at 08:35:05PM +0200, Daniel Vetter wrote:
> > > > > It's kinda pointless to have 2 separate mallocs for these. And when we
> > > > > add more per-connector state in the future it's even more pointless.
> > > > > 
> > > > > Right now there's no such thing planned, but both Gustavo's per-crtc
> > > > > fence patches, and some nonblocking commit helpers I'm playing around
> > > > > with will add more per-crtc stuff. It makes sense to also consolidate
> > > > > connectors, just for consistency.
> > > > > 
> > > > > In the future we can use this to store a pointer to the preceeding
> > > > > state, making an atomic update entirely free-standing. This will be
> > > > > needed to be able to queue them up with a depth > 1.
> > > > > 
> > > > > Cc: Gustavo Padovan <gustavo@padovan.org>
> > > > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/drm_atomic.c        | 27 +++++++++------------------
> > > > >  drivers/gpu/drm/drm_atomic_helper.c |  2 +-
> > > > >  include/drm/drm_atomic.h            | 10 +++++-----
> > > > >  include/drm/drm_crtc.h              | 11 +++++++----
> > > > >  4 files changed, 22 insertions(+), 28 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > > > > index 3ff1ed7b33db..a6395e9654af 100644
> > > > > --- a/drivers/gpu/drm/drm_atomic.c
> > > > > +++ b/drivers/gpu/drm/drm_atomic.c
> > > > > @@ -44,7 +44,6 @@
> > > > >  void drm_atomic_state_default_release(struct drm_atomic_state *state)
> > > > >  {
> > > > >  	kfree(state->connectors);
> > > > > -	kfree(state->connector_states);
> > > > >  	kfree(state->crtcs);
> > > > >  	kfree(state->crtc_states);
> > > > >  	kfree(state->planes);
> > > > > @@ -139,15 +138,15 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
> > > > >  	DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
> > > > >  
> > > > >  	for (i = 0; i < state->num_connector; i++) {
> > > > > -		struct drm_connector *connector = state->connectors[i];
> > > > > +		struct drm_connector *connector = state->connectors[i].ptr;
> > > > 
> > > > 'ptr' is not a very good name.
> > > 
> > > Suggestions for something better? I was lacking good inspiration ...
> > 
> > Maybe just 'connector' ?
> 
> state->connectors[i].connector is really long, and makes a lot of code
> look ugly. "obj" might be a bit better than "ptr" at least. Something
> else?

How often are you expecting to have to type this anyway? Using any
kind of generic name here will make life harder for cscope users.
Atomic is really bad in this regard, escecially with all the identically
named function pointers. It's seriosuly hard to navigate that maze
these days. Someone should do a bit of renaming of stuff to make
things more unique.

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state
  2016-05-30 15:45           ` Ville Syrjälä
@ 2016-05-30 15:48             ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-30 15:48 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Mon, May 30, 2016 at 5:45 PM, Ville Syrjälä
<ville.syrjala@linux.intel.com> wrote:
>> state->connectors[i].connector is really long, and makes a lot of code
>> look ugly. "obj" might be a bit better than "ptr" at least. Something
>> else?
>
> How often are you expecting to have to type this anyway? Using any
> kind of generic name here will make life harder for cscope users.
> Atomic is really bad in this regard, escecially with all the identically
> named function pointers. It's seriosuly hard to navigate that maze
> these days. Someone should do a bit of renaming of stuff to make
> things more unique.

We have the same aliasing with legacy hooks shared between
encoder/bridge&crtc. I just always search for the containing structure
since indeed there's no other way to find stuff. Plus big screens ;-)
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state
  2016-05-30 15:05     ` Daniel Vetter
@ 2016-05-31  8:35       ` Maarten Lankhorst
  0 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-31  8:35 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

Op 30-05-16 om 17:05 schreef Daniel Vetter:
> On Mon, May 30, 2016 at 01:42:40PM +0200, Maarten Lankhorst wrote:
>> Op 29-05-16 om 20:35 schreef Daniel Vetter:
>>> ... and use it in msm&vc4. Again just want to encapsulate
>>> drm_atomic_state internals a bit.
>>>
>>> The const threading is a bit awkward in vc4 since C sucks, but I still
>>> think it's worth to enforce this. Eventually I want to make all the
>>> obj->state pointers const too, but that's a lot more work ...
>>>
>>> Cc: Eric Anholt <eric@anholt.net>
>>> Cc: Rob Clark <robdclark@gmail.com>
>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>> ---
>>>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | 10 +++------
>>>  drivers/gpu/drm/vc4/vc4_crtc.c           | 11 +++-------
>>>  drivers/gpu/drm/vc4/vc4_drv.h            |  2 +-
>>>  drivers/gpu/drm/vc4/vc4_plane.c          |  5 +++--
>>>  include/drm/drm_atomic.h                 | 36 ++++++++++++++++++++++++++++++++
>>>  5 files changed, 46 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
>>> index 88fe256c1931..6d4086ee0503 100644
>>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
>>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
>>> @@ -383,19 +383,15 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
>>>  	 */
>>>  	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
>>>  	drm_atomic_crtc_state_for_each_plane(plane, state) {
>>> -		struct drm_plane_state *pstate;
>>> +		const struct drm_plane_state *pstate;
>>>  		if (cnt >= (hw_cfg->lm.nb_stages)) {
>>>  			dev_err(dev->dev, "too many planes!\n");
>>>  			return -EINVAL;
>>>  		}
>>>  
>>> -		pstate = state->state->plane_states[drm_plane_index(plane)];
>>> +		pstate = __drm_atomic_get_current_plane_state(state->state,
>>> +							      plane);
>>>  
>>> -		/* plane might not have changed, in which case take
>>> -		 * current state:
>>> -		 */
>>> -		if (!pstate)
>>> -			pstate = plane->state;
>>>  		pstates[cnt].plane = plane;
>>>  		pstates[cnt].state = to_mdp5_plane_state(pstate);
>>>  
>>> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
>>> index 904d0754ad78..703bda170105 100644
>>> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
>>> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
>>> @@ -405,14 +405,9 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
>>>  		return -EINVAL;
>>>  
>>>  	drm_atomic_crtc_state_for_each_plane(plane, state) {
>>> -		struct drm_plane_state *plane_state =
>>> -			state->state->plane_states[drm_plane_index(plane)];
>>> -
>>> -		/* plane might not have changed, in which case take
>>> -		 * current state:
>>> -		 */
>>> -		if (!plane_state)
>>> -			plane_state = plane->state;
>>> +		const struct drm_plane_state *plane_state =
>>> +			__drm_atomic_get_current_plane_state(state->state,
>>> +							     plane);
>>>  
>>>  		dlist_count += vc4_plane_dlist_size(plane_state);
>>>  	}
>>> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
>>> index 37cac59401d7..c799baabc008 100644
>>> --- a/drivers/gpu/drm/vc4/vc4_drv.h
>>> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
>>> @@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
>>>  struct drm_plane *vc4_plane_init(struct drm_device *dev,
>>>  				 enum drm_plane_type type);
>>>  u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
>>> -u32 vc4_plane_dlist_size(struct drm_plane_state *state);
>>> +u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
>>>  void vc4_plane_async_set_fb(struct drm_plane *plane,
>>>  			    struct drm_framebuffer *fb);
>>>  
>>> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
>>> index 4037b52fde31..5d2c3d9fd17a 100644
>>> --- a/drivers/gpu/drm/vc4/vc4_plane.c
>>> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
>>> @@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
>>>  	return vc4_state->dlist_count;
>>>  }
>>>  
>>> -u32 vc4_plane_dlist_size(struct drm_plane_state *state)
>>> +u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
>>>  {
>>> -	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
>>> +	const struct vc4_plane_state *vc4_state =
>>> +		container_of(state, typeof(*vc4_state), base);
>>>  
>>>  	return vc4_state->dlist_count;
>>>  }
>>> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
>>> index 92c84e9ab09a..4e97186293be 100644
>>> --- a/include/drm/drm_atomic.h
>>> +++ b/include/drm/drm_atomic.h
>>> @@ -109,6 +109,42 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
>>>  	return state->connector_states[index];
>>>  }
>>>  
>>> +/**
>>> + * __drm_atomic_get_current_plane_state - get current plane state
>>> + * @state: global atomic state object
>>> + * @plane: plane to grab
>>> + *
>>> + * This function returns the plane state for the given plane, either from
>>> + * @state, or if the plane isn't part of the atomic state update, from @plane.
>>> + * This is useful in atomic check callbacks, when drivers need to peek at, but
>>> + * not change, state of other planes, since it avoids threading an error code
>>> + * back up the call chain.
>>> + *
>>> + * WARNING:
>>> + *
>>> + * Note that this function is in general unsafe since it doesn't check for the
>>> + * required locking for access state structures. Drivers must ensure that it is
>>> + * save to access the returned state structure through other means. One commone
>>> + * example is when planes are fixed to a single CRTC, and the driver knows that
>>> + * the CRTC locks is held already. In that case holding the CRTC locks gives a
>>> + * read-lock on all planes connected to that CRTC. But if planes can be
>>> + * reassigned things get more tricky. In that case it's better to use
>>> + * drm_atomic_get_plane_state and wire up full error handling.
>>> + *
>>> + * Returns:
>>> + *
>>> + * Read-only pointer to the current plane state.
>>> + */
>>> +static inline const struct drm_plane_state *
>>> +__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
>>> +				     struct drm_plane *plane)
>>> +{
>>> +	if (state->plane_states[drm_plane_index(plane)])
>>> +		return state->plane_states[drm_plane_index(plane)];
>> Could use a debug WARN_ON here. Just in case someone tries to use this for a plane that can't be safely checked:
>>
>> WARN_ON(!plane->state->crtc || !drm_modeset_is_locked(&plane->state->crtc->mutex));
> If you have hw like i915, where you can't move planes, this check isn't
> good enough, because plane->state->crtc might be NULL, but if you hold the
> right crtc mutex it's still perfectly safe. That's why I didn't add that
> check, and instead typed the really long warning.
Wrong! If crtc == NULL, you can set for example a different source rectangle, and plane->state would change from
underneath you since you don't hold the plane mutex.
>> Also use drm_atomic_get_existing_plane_state?
> Hm, feels like overkill since this is a core atomic function. We don't use
> get_existing_* in drm_atomic.c much either.
Ok, but that's an oversight..

Looking at drm_atomic.c it seems to me that drm_atomic_state_default_clear should use for_each_xx_in too..

drm_atomic_get_{crtc,plane}_state uses get_existing_state, drm_atomic_get_connector_state does not, since it duplicated some checks in drm_atomic_get_connector_state.
It is probably worth it to convert drm_atomic_get_connector_state too.

Apart from that I don't see what you mean..

~Maarten

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-30 15:09     ` [Intel-gfx] " Daniel Vetter
@ 2016-05-31  8:43       ` Maarten Lankhorst
  2016-05-31 10:46         ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-31  8:43 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Op 30-05-16 om 17:09 schreef Daniel Vetter:
> On Mon, May 30, 2016 at 03:08:39PM +0200, Maarten Lankhorst wrote:
>> Op 29-05-16 om 20:35 schreef Daniel Vetter:
>>> - dev is redundant, we have state->atomic
>>> - add stall parameter, which must be set when swapping needs to stall
>>>   for preceeding commits to stop looking at ->state pointers. Currently
>>>   all drivers need this to be, just prep work for a glorious future.
>> I have to disagree, if you want to stall it should be done in a separate helper before swapping state.
>> That function should also have the ability to fail, since we haven't called swap_state yet. :)
>>
>> Maybe with nonblock as parameter, so it could fail with -EBUSY if it would stall, and -EINTR if interrupted?
> This is not the stalling you're thinking of. The EBUSY check is in
> drm_atomic_helper_setup_commit (and as such entirely optional).
>
> And if you don't ever use the nonblocking helpers, no struct
> drm_crtc_commit will ever show up in crtc->commit_list, which means this
> here also doesn't do anything.
>
> This stall here is just to make sure that the previous commit doesn't get
> confused because we've ripped out crtc/plane/connector->state from
> underneath it. And as soon as we add previous_state pointers to
> drm_atomic_state and wire it up through all the hooks we can set
> stall=false here, since then pipelining with a queue depth > 1 is
> possible.
If a driver supports depth > 1 it could skip the extra help waiter and just call swap_state.
The helper should return -EINTR when needed.

if (nonblock) {
ret = drm_atomic_helper_wait_for_completion(state);
if (ret)
return ret;
}

drm_atomic_helper_swap_state..


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-31  8:43       ` Maarten Lankhorst
@ 2016-05-31 10:46         ` Daniel Vetter
  2016-05-31 12:20           ` Maarten Lankhorst
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-31 10:46 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Tue, May 31, 2016 at 10:43:56AM +0200, Maarten Lankhorst wrote:
> Op 30-05-16 om 17:09 schreef Daniel Vetter:
> > On Mon, May 30, 2016 at 03:08:39PM +0200, Maarten Lankhorst wrote:
> >> Op 29-05-16 om 20:35 schreef Daniel Vetter:
> >>> - dev is redundant, we have state->atomic
> >>> - add stall parameter, which must be set when swapping needs to stall
> >>>   for preceeding commits to stop looking at ->state pointers. Currently
> >>>   all drivers need this to be, just prep work for a glorious future.
> >> I have to disagree, if you want to stall it should be done in a separate helper before swapping state.
> >> That function should also have the ability to fail, since we haven't called swap_state yet. :)
> >>
> >> Maybe with nonblock as parameter, so it could fail with -EBUSY if it would stall, and -EINTR if interrupted?
> > This is not the stalling you're thinking of. The EBUSY check is in
> > drm_atomic_helper_setup_commit (and as such entirely optional).
> >
> > And if you don't ever use the nonblocking helpers, no struct
> > drm_crtc_commit will ever show up in crtc->commit_list, which means this
> > here also doesn't do anything.
> >
> > This stall here is just to make sure that the previous commit doesn't get
> > confused because we've ripped out crtc/plane/connector->state from
> > underneath it. And as soon as we add previous_state pointers to
> > drm_atomic_state and wire it up through all the hooks we can set
> > stall=false here, since then pipelining with a queue depth > 1 is
> > possible.
> If a driver supports depth > 1 it could skip the extra help waiter and just call swap_state.
> The helper should return -EINTR when needed.
> 
> if (nonblock) {
> ret = drm_atomic_helper_wait_for_completion(state);
> if (ret)
> return ret;
> }
> 
> drm_atomic_helper_swap_state..

That's why there's this stall parameter ... Also,
wait_for_completion(state) is not enough, there's 3 different completions.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits
  2016-05-29 18:35 ` [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits Daniel Vetter
@ 2016-05-31 11:02   ` Liviu Dudau
  2016-05-31 11:07     ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Liviu Dudau @ 2016-05-31 11:02 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Sun, May 29, 2016 at 08:35:13PM +0200, Daniel Vetter wrote:
> Again, just doing them as blocking commits isn't cool.
> 
> From a cursory check hdlcd does seem to at least try to handle
> drm_pending_vblank_event, so hopefully this works.
> 
> Cc: Liviu Dudau <Liviu.Dudau@arm.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>

Daniel,

I have a proper implementation for this, which I will send out shortly, so I will
NAK this patch.

Best regards,
Liviu

> ---
>  drivers/gpu/drm/arm/hdlcd_drv.c | 8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index 4f909378d581..6d1877238cf0 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -112,17 +112,11 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
>  		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
>  }
>  
> -static int hdlcd_atomic_commit(struct drm_device *dev,
> -			       struct drm_atomic_state *state, bool nonblock)
> -{
> -	return drm_atomic_helper_commit(dev, state, false);
> -}
> -
>  static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
>  	.fb_create = drm_fb_cma_create,
>  	.output_poll_changed = hdlcd_fb_output_poll_changed,
>  	.atomic_check = drm_atomic_helper_check,
> -	.atomic_commit = hdlcd_atomic_commit,
> +	.atomic_commit = drm_atomic_helper_commit,
>  };
>  
>  static void hdlcd_setup_mode_config(struct drm_device *drm)
> -- 
> 2.8.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits
  2016-05-31 11:02   ` Liviu Dudau
@ 2016-05-31 11:07     ` Daniel Vetter
  2016-05-31 13:13       ` Liviu Dudau
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-05-31 11:07 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Tue, May 31, 2016 at 12:02:23PM +0100, Liviu Dudau wrote:
> On Sun, May 29, 2016 at 08:35:13PM +0200, Daniel Vetter wrote:
> > Again, just doing them as blocking commits isn't cool.
> > 
> > From a cursory check hdlcd does seem to at least try to handle
> > drm_pending_vblank_event, so hopefully this works.
> > 
> > Cc: Liviu Dudau <Liviu.Dudau@arm.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> 
> Daniel,
> 
> I have a proper implementation for this, which I will send out shortly, so I will
> NAK this patch.

Please don't implement your own atomic nonblocking commit any more. I have
a generic solution, which this patch series implements and then also
converts hdlcd over to it. I admit the commit message is a bit unclear
with that.

If you don't want to pick this up from the mailing lists it's also in my
fdo git repo:

https://cgit.freedesktop.org/~danvet/drm/log/

So nack on your nack ;-)

Cheers, Daniel

> 
> Best regards,
> Liviu
> 
> > ---
> >  drivers/gpu/drm/arm/hdlcd_drv.c | 8 +-------
> >  1 file changed, 1 insertion(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> > index 4f909378d581..6d1877238cf0 100644
> > --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> > +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> > @@ -112,17 +112,11 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
> >  		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
> >  }
> >  
> > -static int hdlcd_atomic_commit(struct drm_device *dev,
> > -			       struct drm_atomic_state *state, bool nonblock)
> > -{
> > -	return drm_atomic_helper_commit(dev, state, false);
> > -}
> > -
> >  static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
> >  	.fb_create = drm_fb_cma_create,
> >  	.output_poll_changed = hdlcd_fb_output_poll_changed,
> >  	.atomic_check = drm_atomic_helper_check,
> > -	.atomic_commit = hdlcd_atomic_commit,
> > +	.atomic_commit = drm_atomic_helper_commit,
> >  };
> >  
> >  static void hdlcd_setup_mode_config(struct drm_device *drm)
> > -- 
> > 2.8.1
> > 
> 
> -- 
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ¯\_(ツ)_/¯

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state
  2016-05-29 18:35 ` [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
@ 2016-05-31 12:19   ` Inki Dae
  2016-06-13  0:52   ` Inki Dae
  1 sibling, 0 replies; 76+ messages in thread
From: Inki Dae @ 2016-05-31 12:19 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

2016-05-30 3:35 GMT+09:00 Daniel Vetter <daniel.vetter@ffwll.ch>:
> We want to hide drm_atomic_state internals better.
>

Acked-by: Inki Dae <inki.dae@samsung.com>

> Cc: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 2dd820e23b0c..cabc5fd0246d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  {
>         struct exynos_drm_private *priv = dev->dev_private;
>         struct exynos_atomic_commit *commit;
> +       struct drm_crtc *crtc;
> +       struct drm_crtc_state *crtc_state;
>         int i, ret;
>
>         commit = kzalloc(sizeof(*commit), GFP_KERNEL);
> @@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>         /* Wait until all affected CRTCs have completed previous commits and
>          * mark them as pending.
>          */
> -       for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -               if (state->crtcs[i])
> -                       commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -       }
> +       for_each_crtc_in_state(state, crtc, crtc_state, i)
> +               commit->crtcs |= 1 << drm_crtc_index(crtc);
>
>         wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
>
> --
> 2.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat
  2016-05-31 10:46         ` Daniel Vetter
@ 2016-05-31 12:20           ` Maarten Lankhorst
  0 siblings, 0 replies; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-31 12:20 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Op 31-05-16 om 12:46 schreef Daniel Vetter:
> On Tue, May 31, 2016 at 10:43:56AM +0200, Maarten Lankhorst wrote:
>> Op 30-05-16 om 17:09 schreef Daniel Vetter:
>>> On Mon, May 30, 2016 at 03:08:39PM +0200, Maarten Lankhorst wrote:
>>>> Op 29-05-16 om 20:35 schreef Daniel Vetter:
>>>>> - dev is redundant, we have state->atomic
>>>>> - add stall parameter, which must be set when swapping needs to stall
>>>>>   for preceeding commits to stop looking at ->state pointers. Currently
>>>>>   all drivers need this to be, just prep work for a glorious future.
>>>> I have to disagree, if you want to stall it should be done in a separate helper before swapping state.
>>>> That function should also have the ability to fail, since we haven't called swap_state yet. :)
>>>>
>>>> Maybe with nonblock as parameter, so it could fail with -EBUSY if it would stall, and -EINTR if interrupted?
>>> This is not the stalling you're thinking of. The EBUSY check is in
>>> drm_atomic_helper_setup_commit (and as such entirely optional).
>>>
>>> And if you don't ever use the nonblocking helpers, no struct
>>> drm_crtc_commit will ever show up in crtc->commit_list, which means this
>>> here also doesn't do anything.
>>>
>>> This stall here is just to make sure that the previous commit doesn't get
>>> confused because we've ripped out crtc/plane/connector->state from
>>> underneath it. And as soon as we add previous_state pointers to
>>> drm_atomic_state and wire it up through all the hooks we can set
>>> stall=false here, since then pipelining with a queue depth > 1 is
>>> possible.
>> If a driver supports depth > 1 it could skip the extra help waiter and just call swap_state.
>> The helper should return -EINTR when needed.
>>
>> if (nonblock) {
>> ret = drm_atomic_helper_wait_for_completion(state);
>> if (ret)
>> return ret;
>> }
>>
>> drm_atomic_helper_swap_state..
> That's why there's this stall parameter ... Also,
> wait_for_completion(state) is not enough, there's 3 different completions.
Yeah but this is pseudocode. I don't think waiting belongs to swap_state, should be done before so we can still back out if wait fails..

~Maarten
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits
  2016-05-31 11:07     ` Daniel Vetter
@ 2016-05-31 13:13       ` Liviu Dudau
  0 siblings, 0 replies; 76+ messages in thread
From: Liviu Dudau @ 2016-05-31 13:13 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Tue, May 31, 2016 at 01:07:15PM +0200, Daniel Vetter wrote:
> On Tue, May 31, 2016 at 12:02:23PM +0100, Liviu Dudau wrote:
> > On Sun, May 29, 2016 at 08:35:13PM +0200, Daniel Vetter wrote:
> > > Again, just doing them as blocking commits isn't cool.
> > > 
> > > From a cursory check hdlcd does seem to at least try to handle
> > > drm_pending_vblank_event, so hopefully this works.
> > > 
> > > Cc: Liviu Dudau <Liviu.Dudau@arm.com>
> > > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > 
> > Daniel,
> > 
> > I have a proper implementation for this, which I will send out shortly, so I will
> > NAK this patch.
> 
> Please don't implement your own atomic nonblocking commit any more. I have
> a generic solution, which this patch series implements and then also
> converts hdlcd over to it. I admit the commit message is a bit unclear
> with that.
> 
> If you don't want to pick this up from the mailing lists it's also in my
> fdo git repo:
> 
> https://cgit.freedesktop.org/~danvet/drm/log/
> 
> So nack on your nack ;-)

OK, in that case:

Acked-by: Liviu Dudau <Liviu.Dudau@arm.com>

Working towards validating your patch series with the HDLCD driver as well.

Best regards,
Liviu

> 
> Cheers, Daniel
> 
> > 
> > Best regards,
> > Liviu
> > 
> > > ---
> > >  drivers/gpu/drm/arm/hdlcd_drv.c | 8 +-------
> > >  1 file changed, 1 insertion(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> > > index 4f909378d581..6d1877238cf0 100644
> > > --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> > > +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> > > @@ -112,17 +112,11 @@ static void hdlcd_fb_output_poll_changed(struct drm_device *drm)
> > >  		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
> > >  }
> > >  
> > > -static int hdlcd_atomic_commit(struct drm_device *dev,
> > > -			       struct drm_atomic_state *state, bool nonblock)
> > > -{
> > > -	return drm_atomic_helper_commit(dev, state, false);
> > > -}
> > > -
> > >  static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
> > >  	.fb_create = drm_fb_cma_create,
> > >  	.output_poll_changed = hdlcd_fb_output_poll_changed,
> > >  	.atomic_check = drm_atomic_helper_check,
> > > -	.atomic_commit = hdlcd_atomic_commit,
> > > +	.atomic_commit = drm_atomic_helper_commit,
> > >  };
> > >  
> > >  static void hdlcd_setup_mode_config(struct drm_device *drm)
> > > -- 
> > > 2.8.1
> > > 
> > 
> > -- 
> > ====================
> > | I would like to |
> > | fix the world,  |
> > | but they're not |
> > | giving me the   |
> >  \ source code!  /
> >   ---------------
> >     ¯\_(ツ)_/¯
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ¯\_(ツ)_/¯
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (25 preceding siblings ...)
  2016-05-29 18:35 ` [PATCH 26/26] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
@ 2016-05-31 13:40 ` Patchwork
  2016-05-31 13:42 ` Patchwork
  2016-05-31 14:29 ` Patchwork
  28 siblings, 0 replies; 76+ messages in thread
From: Patchwork @ 2016-05-31 13:40 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: RFC: generic nonblocking support in the atomic helpers
URL   : https://patchwork.freedesktop.org/series/7940/
State : failure

== Summary ==

  CHECK   usr/include/linux/caif/ (2 files)
  CHECK   usr/include/linux/iio/ (2 files)
  CHECK   usr/include/linux/netfilter_ipv4/ (9 files)
  CHECK   usr/include/linux/sunrpc/ (1 files)
  CHECK   usr/include/linux/mmc/ (1 files)
  CHECK   usr/include/linux/spi/ (1 files)
  CHECK   usr/include/linux/netfilter_ipv6/ (12 files)
  CHECK   usr/include/linux/netfilter_bridge/ (17 files)
  CHECK   usr/include/linux/nfsd/ (5 files)
  CHECK   usr/include/linux/isdn/ (1 files)
  CHECK   usr/include/linux/usb/ (11 files)
  CHECK   usr/include/linux/netfilter_arp/ (2 files)
  CHECK   usr/include/linux/tc_act/ (12 files)
  CHECK   usr/include/linux/raid/ (2 files)
  CHECK   usr/include/linux/netfilter/ (85 files)
  CHECK   usr/include/linux/tc_ematch/ (4 files)
  CHECK   usr/include/linux/netfilter/ipset/ (4 files)
  CHECK   usr/include/linux/ (428 files)
  CHECK   usr/include/linux/wimax/ (1 files)
  CHECK   usr/include/asm/ (65 files)
  LINK    vmlinux
  LD      vmlinux.o
  MODPOST vmlinux.o
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
/bin/sh: gcc: command not found
make[1]: *** [init/version.o] Error 127
make: *** [vmlinux] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (26 preceding siblings ...)
  2016-05-31 13:40 ` ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers Patchwork
@ 2016-05-31 13:42 ` Patchwork
  2016-05-31 14:29 ` Patchwork
  28 siblings, 0 replies; 76+ messages in thread
From: Patchwork @ 2016-05-31 13:42 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: RFC: generic nonblocking support in the atomic helpers
URL   : https://patchwork.freedesktop.org/series/7940/
State : failure

== Summary ==

make: gcc: Command not found
cat: write error: Broken pipe
./scripts/gcc-version.sh: line 25: gcc: command not found
./scripts/gcc-version.sh: line 26: gcc: command not found
./scripts/gcc-version.sh: line 25: gcc: command not found
./scripts/gcc-version.sh: line 26: gcc: command not found
make: gcc: Command not found
cat: write error: Broken pipe
./scripts/gcc-version.sh: line 25: gcc: command not found
./scripts/gcc-version.sh: line 26: gcc: command not found
./scripts/gcc-version.sh: line 25: gcc: command not found
./scripts/gcc-version.sh: line 26: gcc: command not found
  HOSTCC  scripts/basic/fixdep
/bin/sh: gcc: command not found
make[1]: *** [scripts/basic/fixdep] Error 127
make: *** [scripts_basic] Error 2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/atomic-helper: nonblocking commit support
  2016-05-30  8:01   ` [PATCH] " Daniel Vetter
@ 2016-05-31 14:22     ` Maarten Lankhorst
  2016-05-31 14:33       ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maarten Lankhorst @ 2016-05-31 14:22 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Daniel Stone, Tomeu Vizoso

Op 30-05-16 om 10:01 schreef Daniel Vetter:
> Design ideas:
>
> - split up the actual commit into different phases, and have
>   completions for each of them. This will be useful for the future
>   when we want to interleave phases much more aggressively, for e.g.
>   queue depth > 1. For not it's just a minimal optimization compared
>   to current common nonblocking implementation patterns from drivers,
>   which all stall for the entire commit to complete, including vblank
>   waits and cleanups.
>
> - Extract a separate atomic_commit_hw hook since that's the part most
>   drivers will need to overwrite, hopefully allowing even more shared
>   code.
>
> - Enforce EBUSY seamntics by attaching one of the completions to the
>   flip_done vblank event. Side benefit of forcing atomic drivers using
>   these helpers to implement event handlign at least semi-correct. I'm
>   evil that way ;-)
>
> - Ridiculously modular, as usual.
>
> - The main tracking unit for a commit stays struct drm_atomic_state,
>   and the ownership rules for that are unchanged. Ownership still
>   gets transferred to the driver (and subsequently to the worker) on
>   successful commits. What is added is a small, per-crtc, refcounted
>   structure to track pending commits called struct drm_crtc_commit.
>   No actual state is attached to that though, it's purely for ordering
>   and waiting.
>
> - Dependencies are implicitly handled by assuming that any CRTC part
>   of &drm_atomic_state is a dependency, and that the current commit
>   must wait for any commits to complete on those CRTC. This way
>   drivers can easily add more depencies using
>   drm_atomic_get_crtc_state(), which is very natural since in most
>   case a dependency exists iff there's some bit of state that needs to
>   be cross checked.
>
>   Removing depencies is not possible, drivers simply need to be
>   careful to not include every CRTC in a commit if that's not
>   necessary. Which is a good idea anyway, since that also avoids
>   ww_mutex lock contention.
>
> - Queue depth > 1 sees some prep work in this patch by adding a stall
>   paramater to drm_atomic_helper_swap_states(). To be able to push
>   commits entirely free-standing and in a deeper queue through the
>   back-end the driver must not access any obj->state pointers. This
>   means we need to track the old state in drm_atomic_state (much
>   easier with the consolidated arrays), and pass them all explicitly
>   to driver backends (this will be serious amounts of churn).
>  
>   Once that's done stall can be set to false in swap_states.
>
> Features: Contains bugs because totally untested.
>
> v2: Dont ask for flip_done signalling when the CRTC is off and stays
> off: Drivers don't handle events in that case. Instead complete right
> away. This way future commits don't need to have special-case logic,
> but can keep blocking for the flip_done completion.
>
> v3: Tons of fixes:
> - Stall for preceeding commit for real, not the current one by
>   accident.
> - Add WARN_ON in case drivers don't fire the drm event.
> - Don't double-free drm events.
>
> v4: Make legacy cursor not stall.
>
> v5: Extend the helper hook to cover the entire commit tail. Some
> drivers need special code for cleanup and vblank waiting, this makes
> it a bit more useful. Inspired by the rockchip driver.
>
> v6: Add WARN_ON to catch drivers who forget to send out the
> drm event.
>
> v7: Fixup the stalls in swap_state for real!!
I don't think stalling belongs to swap_state, that should be a separate helper call.

When nonblocking = false the waiting is still performed uninterruptibly. I believe that this is an error,
and all blocking waiting should be completed before calling swap_state to ensure -EINTR can be
propagated correctly as much as possible. Perhaps also return -EBUSY if wait times out.

You specified a timeout of 10 HZ, why is that? If we wait interruptibly then there's no need for a timeout.
I also think the timeout may be too short, if we commit 3 crtc's it leaves 3.3 seconds for each. In case
there's a modeset enable and disable, that leaves 1.6 seconds for each enable/disable. Might be too short..

Patch is also a bit hard to review with so many lines changed, could this be done in pieces instead of all at once?

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers
  2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
                   ` (27 preceding siblings ...)
  2016-05-31 13:42 ` Patchwork
@ 2016-05-31 14:29 ` Patchwork
  28 siblings, 0 replies; 76+ messages in thread
From: Patchwork @ 2016-05-31 14:29 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

== Series Details ==

Series: RFC: generic nonblocking support in the atomic helpers
URL   : https://patchwork.freedesktop.org/series/7940/
State : failure

== Summary ==

Series 7940v1 RFC: generic nonblocking support in the atomic helpers
http://patchwork.freedesktop.org/api/1.0/series/7940/revisions/1/mbox

Test drv_module_reload_basic:
                pass       -> INCOMPLETE (ro-snb-i7-2620M)
Test gem_busy:
        Subgroup basic-render:
                pass       -> DMESG-WARN (ro-ivb2-i7-3770)
Test gem_close_race:
        Subgroup basic-threads:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
Test gem_exec_basic:
        Subgroup basic-blt:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup gtt-blt:
                dmesg-warn -> PASS       (ro-ivb2-i7-3770)
Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-cmd:
                pass       -> FAIL       (ro-byt-n2820)
        Subgroup basic-batch-kernel-default-uc:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
        Subgroup basic-batch-kernel-default-wb:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
        Subgroup basic-uc-prw-default:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup basic-uc-ro-default:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup basic-uc-rw-default:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup basic-wb-ro-default:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
Test gem_exec_parallel:
        Subgroup basic:
                dmesg-warn -> PASS       (ro-ivb2-i7-3770)
Test gem_exec_parse:
        Subgroup basic-rejected:
                pass       -> DMESG-WARN (ro-ivb2-i7-3770)
Test gem_exec_store:
        Subgroup basic-default:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
Test gem_exec_suspend:
        Subgroup basic:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
Test gem_mmap_gtt:
        Subgroup basic-small-copy-xy:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
Test gem_pread:
        Subgroup basic:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
Test gem_render_tiled_blits:
        Subgroup basic:
                dmesg-warn -> PASS       (ro-ivb2-i7-3770)
Test gem_storedw_loop:
        Subgroup basic-vebox:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
Test kms_addfb_basic:
        Subgroup addfb25-x-tiled:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
        Subgroup bad-pitch-0:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup bad-pitch-999:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup basic:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
        Subgroup too-high:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)
Test kms_force_connector_basic:
        Subgroup force-connector-state:
                dmesg-warn -> PASS       (ro-ivb2-i7-3770)
        Subgroup force-edid:
                pass       -> DMESG-WARN (ro-ivb2-i7-3770)
Test kms_frontbuffer_tracking:
        Subgroup basic:
                dmesg-warn -> PASS       (ro-skl-i7-6700hq)
Test kms_psr_sink_crc:
        Subgroup psr_basic:
                pass       -> DMESG-WARN (ro-skl-i7-6700hq)

fi-bdw-i7-5557u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
fi-bsw-n3050     total:209  pass:167  dwarn:0   dfail:0   fail:2   skip:40 
fi-byt-n2820     total:209  pass:168  dwarn:0   dfail:0   fail:3   skip:38 
fi-hsw-i7-4770r  total:209  pass:186  dwarn:0   dfail:0   fail:0   skip:23 
fi-skl-i7-6700k  total:209  pass:184  dwarn:0   dfail:0   fail:0   skip:25 
fi-snb-i7-2600   total:209  pass:170  dwarn:0   dfail:0   fail:0   skip:39 
ro-bdw-i5-5250u  total:102  pass:93   dwarn:0   dfail:0   fail:0   skip:8  
ro-bdw-i7-5600u  total:102  pass:75   dwarn:0   dfail:0   fail:0   skip:26 
ro-bsw-n3050     total:209  pass:168  dwarn:0   dfail:0   fail:2   skip:39 
ro-byt-n2820     total:209  pass:169  dwarn:0   dfail:0   fail:3   skip:37 
ro-hsw-i3-4010u  total:209  pass:186  dwarn:0   dfail:0   fail:0   skip:23 
ro-hsw-i7-4770r  total:102  pass:82   dwarn:0   dfail:0   fail:0   skip:19 
ro-ilk-i7-620lm  total:1    pass:0    dwarn:0   dfail:0   fail:0   skip:0  
ro-ilk1-i5-650   total:204  pass:146  dwarn:0   dfail:0   fail:1   skip:57 
ro-ivb2-i7-3770  total:102  pass:43   dwarn:36  dfail:0   fail:0   skip:22 
ro-skl-i7-6700hq total:204  pass:169  dwarn:14  dfail:0   fail:0   skip:21 
ro-snb-i7-2620M  total:26   pass:20   dwarn:0   dfail:0   fail:0   skip:5  
fi-bsw-n3050 failed to connect after reboot
ro-ivb-i7-3770 failed to connect after reboot

Results at /archive/results/CI_IGT_test/RO_Patchwork_1066/

031f2bb drm-intel-nightly: 2016y-05m-30d-17h-51m-33s UTC integration manifest
fce9886 drm/virtio: Don't reinvent a flipping wheel
fab9998 drm/rockchip: Nuke pending event handling in preclose
9d67218 drm/rockchip: convert to helper nonblocking atomic commit
1c7131c drm/i915: Roll out the helper nonblock tracking
a6a55f0 drm/i915: Signal drm events for atomic
641326d drm/atomic-helper: nonblocking commit support
a35722d drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset
a4e3c220 drm/sun4i: Implement some semblance of vblank event handling
faa6fa6 drm/hisilicon: Implement some semblance of vblank event handling
10d72b2 drm/fsl-du: Implement some semblance of vblank event handling
e09950d drm/hdlcd: Use helper support for nonblocking commits
a4d6d40 drm/arc: Implement nonblocking commit correctly
1142258 drm/arc: Actually bother with handling atomic events.
574c11f drm/arc: Nuke event_list
a570efd drm/atomic-helper: Massage swap_state signature somewhat
e656bf1 drm/fence: add fence to drm_pending_event
92d7c95 drm: Consolidate crtc arrays in drm_atomic_state
84e3a47c drm: Consolidate plane arrays in drm_atomic_state
117b6e8 drm: Consolidate connector arrays in drm_atomic_state
ec007f5 drm/exynos: Use for_each_crtc_in_state
1850eb8 drm/atomic: Add __drm_atomic_get_current_plane_state
41f5075 drm/vc4: Use for_each_plane_in_state
0a933a4 drm/rcar-du: Use for_each_*_in_state
c1ddfcb drm/msm: Use for_each_*_in_state
c1f05f4 drm/i915: Use drm_atomic_get_existing_plane_state
ecc6a2a drm/atomic-helper: use for_each_*_in_state more

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/atomic-helper: nonblocking commit support
  2016-05-31 14:22     ` [Intel-gfx] " Maarten Lankhorst
@ 2016-05-31 14:33       ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-05-31 14:33 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Daniel Stone, Daniel Vetter, Intel Graphics Development,
	DRI Development, Tomeu Vizoso, Daniel Vetter

On Tue, May 31, 2016 at 04:22:57PM +0200, Maarten Lankhorst wrote:
> Op 30-05-16 om 10:01 schreef Daniel Vetter:
> > Design ideas:
> >
> > - split up the actual commit into different phases, and have
> >   completions for each of them. This will be useful for the future
> >   when we want to interleave phases much more aggressively, for e.g.
> >   queue depth > 1. For not it's just a minimal optimization compared
> >   to current common nonblocking implementation patterns from drivers,
> >   which all stall for the entire commit to complete, including vblank
> >   waits and cleanups.
> >
> > - Extract a separate atomic_commit_hw hook since that's the part most
> >   drivers will need to overwrite, hopefully allowing even more shared
> >   code.
> >
> > - Enforce EBUSY seamntics by attaching one of the completions to the
> >   flip_done vblank event. Side benefit of forcing atomic drivers using
> >   these helpers to implement event handlign at least semi-correct. I'm
> >   evil that way ;-)
> >
> > - Ridiculously modular, as usual.
> >
> > - The main tracking unit for a commit stays struct drm_atomic_state,
> >   and the ownership rules for that are unchanged. Ownership still
> >   gets transferred to the driver (and subsequently to the worker) on
> >   successful commits. What is added is a small, per-crtc, refcounted
> >   structure to track pending commits called struct drm_crtc_commit.
> >   No actual state is attached to that though, it's purely for ordering
> >   and waiting.
> >
> > - Dependencies are implicitly handled by assuming that any CRTC part
> >   of &drm_atomic_state is a dependency, and that the current commit
> >   must wait for any commits to complete on those CRTC. This way
> >   drivers can easily add more depencies using
> >   drm_atomic_get_crtc_state(), which is very natural since in most
> >   case a dependency exists iff there's some bit of state that needs to
> >   be cross checked.
> >
> >   Removing depencies is not possible, drivers simply need to be
> >   careful to not include every CRTC in a commit if that's not
> >   necessary. Which is a good idea anyway, since that also avoids
> >   ww_mutex lock contention.
> >
> > - Queue depth > 1 sees some prep work in this patch by adding a stall
> >   paramater to drm_atomic_helper_swap_states(). To be able to push
> >   commits entirely free-standing and in a deeper queue through the
> >   back-end the driver must not access any obj->state pointers. This
> >   means we need to track the old state in drm_atomic_state (much
> >   easier with the consolidated arrays), and pass them all explicitly
> >   to driver backends (this will be serious amounts of churn).
> >  
> >   Once that's done stall can be set to false in swap_states.
> >
> > Features: Contains bugs because totally untested.
> >
> > v2: Dont ask for flip_done signalling when the CRTC is off and stays
> > off: Drivers don't handle events in that case. Instead complete right
> > away. This way future commits don't need to have special-case logic,
> > but can keep blocking for the flip_done completion.
> >
> > v3: Tons of fixes:
> > - Stall for preceeding commit for real, not the current one by
> >   accident.
> > - Add WARN_ON in case drivers don't fire the drm event.
> > - Don't double-free drm events.
> >
> > v4: Make legacy cursor not stall.
> >
> > v5: Extend the helper hook to cover the entire commit tail. Some
> > drivers need special code for cleanup and vblank waiting, this makes
> > it a bit more useful. Inspired by the rockchip driver.
> >
> > v6: Add WARN_ON to catch drivers who forget to send out the
> > drm event.
> >
> > v7: Fixup the stalls in swap_state for real!!
> I don't think stalling belongs to swap_state, that should be a separate helper call.

Imo swap_state and stalling for hw_done is crucial that they're never
split up. At least until we have queue depth > 1. Splitting it up just
means there's more stuff drivers can get wrong, and I haven't found a
single driver where there's a need to split things up. And I looked at all
17 of them. That's why I don't think splitting makes sense.

All the other helpers might seem like things are split up a lot, but for
each separate helper function I'm adding here there's that absolutely
needs that split to insert/replace a bit.

> When nonblocking = false the waiting is still performed uninterruptibly. I believe that this is an error,
> and all blocking waiting should be completed before calling swap_state to ensure -EINTR can be
> propagated correctly as much as possible. Perhaps also return -EBUSY if wait times out.

The trouble with failing with -EBUSY is that drivers are broken in their
drm even handling, which means they'll fail. By eventually continuing
there's at least some chances that you'll see something on the screen.

Wrt interruptible waits, the stall check does wait interruptible.
Everything else is imo part of the commit, which isn't allowed to fail/get
interrupted. And for queue depth > 1 we'll actually move the stall for
hw_done down into the worker.

> You specified a timeout of 10 HZ, why is that? If we wait interruptibly then there's no need for a timeout.
> I also think the timeout may be too short, if we commit 3 crtc's it leaves 3.3 seconds for each. In case
> there's a modeset enable and disable, that leaves 1.6 seconds for each enable/disable. Might be too short..

Random value between "long enough to never be a problem in practice" and
"short enought that it's still ok to wait it out on boot-up for the
initial modeset". Note that wait_for_dependencies has another wait for
hw_done, and that one is non-optional (and in the async worker).

> Patch is also a bit hard to review with so many lines changed, could this be done in pieces instead of all at once?

The only bits I can split out is extracting commit_tail, and adding events
to drm_atomic_commit->crtcs[]. If I split more that just means the code I
add and the the places where it actually gets used are split up, which imo
doesn't make sense since it's not longer a complete functional change on
its own.

What do you want me to split out to make it easier to read?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 19/26] drm/sun4i: Implement some semblance of vblank event handling
  2016-05-29 18:35 ` [PATCH 19/26] drm/sun4i: " Daniel Vetter
@ 2016-06-01 16:18   ` Maxime Ripard
  2016-06-01 22:02     ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Maxime Ripard @ 2016-06-01 16:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Boris Brezillon, Intel Graphics Development, DRI Development,
	Daniel Vetter


[-- Attachment #1.1: Type: text/plain, Size: 539 bytes --]

Hi Daniel,

On Sun, May 29, 2016 at 08:35:16PM +0200, Daniel Vetter wrote:
> atomic_flush seems to be the right place, right after we commit the
> plane updates. Again use the fullproof version, since the pipe might
> be off.

This looks fine.

How can that be tested? modetest requires async vblank, which is not
there yet, and X doesn't seem to use it at all (since it works fine
without it).

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 19/26] drm/sun4i: Implement some semblance of vblank event handling
  2016-06-01 16:18   ` Maxime Ripard
@ 2016-06-01 22:02     ` Daniel Vetter
  0 siblings, 0 replies; 76+ messages in thread
From: Daniel Vetter @ 2016-06-01 22:02 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development,
	DRI Development, Boris Brezillon

On Wed, Jun 01, 2016 at 06:18:59PM +0200, Maxime Ripard wrote:
> Hi Daniel,
> 
> On Sun, May 29, 2016 at 08:35:16PM +0200, Daniel Vetter wrote:
> > atomic_flush seems to be the right place, right after we commit the
> > plane updates. Again use the fullproof version, since the pipe might
> > be off.
> 
> This looks fine.
> 
> How can that be tested? modetest requires async vblank, which is not
> there yet, and X doesn't seem to use it at all (since it works fine
> without it).

Run the entire series. It implements nonblocking commit for everyone. I'm
just working on submitting the non-RFC version of this series.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-05-30 14:54       ` [Intel-gfx] " Daniel Vetter
@ 2016-06-02 22:54         ` Laurent Pinchart
  2016-06-03  6:55           ` [Intel-gfx] " Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Laurent Pinchart @ 2016-06-02 22:54 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

Hi Daniel,

On Monday 30 May 2016 16:54:10 Daniel Vetter wrote:
> On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
> > Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> >> Hi Daniel,
> >> 
> >> Thank you for the patch.
> >> 
> >> This looks good to me as the resulting code is mostly similar. However,
> >> the for_each_*_in_state macros end with an for_each_if() that tests if
> >> the object's state is NULL, which isn't present in this code. I'm
> >> wondering whether that was an oversight on my side possibly leading to a
> >> crash when dereferencing a NULL state, or an unneeded check in the
> >> macros. Can atomic_state->*_states[i] be NULL if atomic_state->*[i] is
> >> not NULL ?
> > 
> > Not in any normal case.
> 
> Yeah, the drm_atomic_get_*_state functions only ever fill in both of
> neither. If this gets out of sync it's a bug ;-)

Should the check be removed then ? Or replaced by a WARN_ON() ?

-- 
Regards,

Laurent Pinchart

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [Intel-gfx] [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-06-02 22:54         ` Laurent Pinchart
@ 2016-06-03  6:55           ` Daniel Vetter
  2016-06-03  9:40             ` Laurent Pinchart
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-06-03  6:55 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Fri, Jun 03, 2016 at 01:54:44AM +0300, Laurent Pinchart wrote:
> Hi Daniel,
> 
> On Monday 30 May 2016 16:54:10 Daniel Vetter wrote:
> > On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
> > > Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> > >> Hi Daniel,
> > >> 
> > >> Thank you for the patch.
> > >> 
> > >> This looks good to me as the resulting code is mostly similar. However,
> > >> the for_each_*_in_state macros end with an for_each_if() that tests if
> > >> the object's state is NULL, which isn't present in this code. I'm
> > >> wondering whether that was an oversight on my side possibly leading to a
> > >> crash when dereferencing a NULL state, or an unneeded check in the
> > >> macros. Can atomic_state->*_states[i] be NULL if atomic_state->*[i] is
> > >> not NULL ?
> > > 
> > > Not in any normal case.
> > 
> > Yeah, the drm_atomic_get_*_state functions only ever fill in both of
> > neither. If this gets out of sync it's a bug ;-)
> 
> Should the check be removed then ? Or replaced by a WARN_ON() ?

In all the places I converted here I nuked those checks, since they moved
into the loop now. Not sure what checks you're talking about.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-06-03  6:55           ` [Intel-gfx] " Daniel Vetter
@ 2016-06-03  9:40             ` Laurent Pinchart
  2016-06-03  9:45               ` Daniel Vetter
  0 siblings, 1 reply; 76+ messages in thread
From: Laurent Pinchart @ 2016-06-03  9:40 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

Hi Daniel,

On Friday 03 Jun 2016 08:55:36 Daniel Vetter wrote:
> On Fri, Jun 03, 2016 at 01:54:44AM +0300, Laurent Pinchart wrote:
> > On Monday 30 May 2016 16:54:10 Daniel Vetter wrote:
> >> On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
> >>> Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> >>>> Hi Daniel,
> >>>> 
> >>>> Thank you for the patch.
> >>>> 
> >>>> This looks good to me as the resulting code is mostly similar.
> >>>> However, the for_each_*_in_state macros end with an for_each_if()
> >>>> that tests if the object's state is NULL, which isn't present in this
> >>>> code. I'm wondering whether that was an oversight on my side possibly
> >>>> leading to a crash when dereferencing a NULL state, or an unneeded
> >>>> check in the macros. Can atomic_state->*_states[i] be NULL if
> >>>> atomic_state->*[i] is not NULL ?
> >>> 
> >>> Not in any normal case.
> >> 
> >> Yeah, the drm_atomic_get_*_state functions only ever fill in both of
> >> neither. If this gets out of sync it's a bug ;-)
> > 
> > Should the check be removed then ? Or replaced by a WARN_ON() ?
> 
> In all the places I converted here I nuked those checks, since they moved
> into the loop now. Not sure what checks you're talking about.

I'm talking about the for_each_if() check inside the for_each_*_in_state 
macros.

-- 
Regards,

Laurent Pinchart

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-06-03  9:40             ` Laurent Pinchart
@ 2016-06-03  9:45               ` Daniel Vetter
  2016-06-03  9:50                 ` Laurent Pinchart
  0 siblings, 1 reply; 76+ messages in thread
From: Daniel Vetter @ 2016-06-03  9:45 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Fri, Jun 3, 2016 at 11:40 AM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Friday 03 Jun 2016 08:55:36 Daniel Vetter wrote:
>> On Fri, Jun 03, 2016 at 01:54:44AM +0300, Laurent Pinchart wrote:
>> > On Monday 30 May 2016 16:54:10 Daniel Vetter wrote:
>> >> On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
>> >>> Op 30-05-16 om 11:18 schreef Laurent Pinchart:
>> >>>> Hi Daniel,
>> >>>>
>> >>>> Thank you for the patch.
>> >>>>
>> >>>> This looks good to me as the resulting code is mostly similar.
>> >>>> However, the for_each_*_in_state macros end with an for_each_if()
>> >>>> that tests if the object's state is NULL, which isn't present in this
>> >>>> code. I'm wondering whether that was an oversight on my side possibly
>> >>>> leading to a crash when dereferencing a NULL state, or an unneeded
>> >>>> check in the macros. Can atomic_state->*_states[i] be NULL if
>> >>>> atomic_state->*[i] is not NULL ?
>> >>>
>> >>> Not in any normal case.
>> >>
>> >> Yeah, the drm_atomic_get_*_state functions only ever fill in both of
>> >> neither. If this gets out of sync it's a bug ;-)
>> >
>> > Should the check be removed then ? Or replaced by a WARN_ON() ?
>>
>> In all the places I converted here I nuked those checks, since they moved
>> into the loop now. Not sure what checks you're talking about.
>
> I'm talking about the for_each_if() check inside the for_each_*_in_state
> macros.

The rule is drm_atomic_state->plane[i] != NULL iff
drm_atomic_state->plane_state != NULL. So you can check either of them
for the same result. But you still need to check one of them,
otherwise all the loops in drivers and helpers will oops. Not sure why
you want to remove that check, your driver had the equivalent (which I
removed) too.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 04/26] drm/rcar-du: Use for_each_*_in_state
  2016-06-03  9:45               ` Daniel Vetter
@ 2016-06-03  9:50                 ` Laurent Pinchart
  0 siblings, 0 replies; 76+ messages in thread
From: Laurent Pinchart @ 2016-06-03  9:50 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi Daniel,

On Friday 03 Jun 2016 11:45:56 Daniel Vetter wrote:
> On Fri, Jun 3, 2016 at 11:40 AM, Laurent Pinchart wrote:
> > On Friday 03 Jun 2016 08:55:36 Daniel Vetter wrote:
> >> On Fri, Jun 03, 2016 at 01:54:44AM +0300, Laurent Pinchart wrote:
> >>> On Monday 30 May 2016 16:54:10 Daniel Vetter wrote:
> >>>> On Mon, May 30, 2016 at 11:58:27AM +0200, Maarten Lankhorst wrote:
> >>>>> Op 30-05-16 om 11:18 schreef Laurent Pinchart:
> >>>>>> Hi Daniel,
> >>>>>> 
> >>>>>> Thank you for the patch.
> >>>>>> 
> >>>>>> This looks good to me as the resulting code is mostly similar.
> >>>>>> However, the for_each_*_in_state macros end with an for_each_if()
> >>>>>> that tests if the object's state is NULL, which isn't present in
> >>>>>> this code. I'm wondering whether that was an oversight on my side
> >>>>>> possibly leading to a crash when dereferencing a NULL state, or an
> >>>>>> unneeded check in the macros. Can atomic_state->*_states[i] be NULL
> >>>>>> if atomic_state->*[i] is not NULL ?
> >>>>> 
> >>>>> Not in any normal case.
> >>>> 
> >>>> Yeah, the drm_atomic_get_*_state functions only ever fill in both of
> >>>> neither. If this gets out of sync it's a bug ;-)
> >>> 
> >>> Should the check be removed then ? Or replaced by a WARN_ON() ?
> >> 
> >> In all the places I converted here I nuked those checks, since they moved
> >> into the loop now. Not sure what checks you're talking about.
> > 
> > I'm talking about the for_each_if() check inside the for_each_*_in_state
> > macros.
> 
> The rule is drm_atomic_state->plane[i] != NULL iff
> drm_atomic_state->plane_state != NULL. So you can check either of them
> for the same result. But you still need to check one of them,
> otherwise all the loops in drivers and helpers will oops. Not sure why
> you want to remove that check, your driver had the equivalent (which I
> removed) too.

My bad, I had misread the for_each_*_in_state macros and thought they were 
checking both. Sorry for the noise.

-- 
Regards,

Laurent Pinchart

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

* Re: [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state
  2016-05-29 18:35 ` [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
  2016-05-31 12:19   ` Inki Dae
@ 2016-06-13  0:52   ` Inki Dae
  1 sibling, 0 replies; 76+ messages in thread
From: Inki Dae @ 2016-06-13  0:52 UTC (permalink / raw)
  To: Daniel Vetter, DRI Development; +Cc: Daniel Vetter, Intel Graphics Development



2016년 05월 30일 03:35에 Daniel Vetter 이(가) 쓴 글:
> We want to hide drm_atomic_state internals better.

Acked-by: Inki Dae <inki.dae@samsung.com>

Thanks,
Inki Dae

> 
> Cc: Inki Dae <inki.dae@samsung.com>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/exynos/exynos_drm_drv.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 2dd820e23b0c..cabc5fd0246d 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  {
>  	struct exynos_drm_private *priv = dev->dev_private;
>  	struct exynos_atomic_commit *commit;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
>  	int i, ret;
>  
>  	commit = kzalloc(sizeof(*commit), GFP_KERNEL);
> @@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
>  	/* Wait until all affected CRTCs have completed previous commits and
>  	 * mark them as pending.
>  	 */
> -	for (i = 0; i < dev->mode_config.num_crtc; ++i) {
> -		if (state->crtcs[i])
> -			commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
> -	}
> +	for_each_crtc_in_state(state, crtc, crtc_state, i)
> +		commit->crtcs |= 1 << drm_crtc_index(crtc);
>  
>  	wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
>  
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2016-06-13  0:52 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-29 18:34 [PATCH 00/26] RFC: generic nonblocking support in the atomic helpers Daniel Vetter
2016-05-29 18:34 ` [PATCH 01/26] drm/atomic-helper: use for_each_*_in_state more Daniel Vetter
2016-05-30 12:17   ` Maarten Lankhorst
2016-05-30 15:02     ` Daniel Vetter
2016-05-29 18:34 ` [PATCH 02/26] drm/i915: Use drm_atomic_get_existing_plane_state Daniel Vetter
2016-05-30 13:10   ` [Intel-gfx] " Maarten Lankhorst
2016-05-29 18:35 ` [PATCH 03/26] drm/msm: Use for_each_*_in_state Daniel Vetter
2016-05-29 18:35 ` [PATCH 04/26] drm/rcar-du: " Daniel Vetter
2016-05-30  9:18   ` Laurent Pinchart
2016-05-30  9:58     ` Maarten Lankhorst
2016-05-30 14:54       ` [Intel-gfx] " Daniel Vetter
2016-06-02 22:54         ` Laurent Pinchart
2016-06-03  6:55           ` [Intel-gfx] " Daniel Vetter
2016-06-03  9:40             ` Laurent Pinchart
2016-06-03  9:45               ` Daniel Vetter
2016-06-03  9:50                 ` Laurent Pinchart
2016-05-29 18:35 ` [PATCH 05/26] drm/vc4: Use for_each_plane_in_state Daniel Vetter
2016-05-29 18:35 ` [PATCH 06/26] drm/atomic: Add __drm_atomic_get_current_plane_state Daniel Vetter
2016-05-30 11:42   ` [Intel-gfx] " Maarten Lankhorst
2016-05-30 15:05     ` Daniel Vetter
2016-05-31  8:35       ` [Intel-gfx] " Maarten Lankhorst
2016-05-29 18:35 ` [PATCH 07/26] drm/exynos: Use for_each_crtc_in_state Daniel Vetter
2016-05-31 12:19   ` Inki Dae
2016-06-13  0:52   ` Inki Dae
2016-05-29 18:35 ` [PATCH 08/26] drm: Consolidate connector arrays in drm_atomic_state Daniel Vetter
2016-05-30 14:59   ` Ville Syrjälä
2016-05-30 15:13     ` Daniel Vetter
2016-05-30 15:25       ` [Intel-gfx] " Ville Syrjälä
2016-05-30 15:33         ` Daniel Vetter
2016-05-30 15:45           ` Ville Syrjälä
2016-05-30 15:48             ` [Intel-gfx] " Daniel Vetter
2016-05-29 18:35 ` [PATCH 09/26] drm: Consolidate plane " Daniel Vetter
2016-05-29 18:35 ` [PATCH 10/26] drm: Consolidate crtc " Daniel Vetter
2016-05-29 18:35 ` [PATCH 11/26] drm/fence: add fence to drm_pending_event Daniel Vetter
2016-05-29 18:35 ` [PATCH 12/26] drm/atomic-helper: Massage swap_state signature somewhat Daniel Vetter
2016-05-30 13:08   ` Maarten Lankhorst
2016-05-30 15:09     ` [Intel-gfx] " Daniel Vetter
2016-05-31  8:43       ` Maarten Lankhorst
2016-05-31 10:46         ` Daniel Vetter
2016-05-31 12:20           ` Maarten Lankhorst
2016-05-29 18:35 ` [PATCH 13/26] drm/arc: Nuke event_list Daniel Vetter
2016-05-29 18:35   ` Daniel Vetter
2016-05-29 18:35 ` [PATCH 14/26] drm/arc: Actually bother with handling atomic events Daniel Vetter
2016-05-29 18:35   ` Daniel Vetter
2016-05-29 18:35 ` [PATCH 15/26] drm/arc: Implement nonblocking commit correctly Daniel Vetter
2016-05-29 18:35   ` Daniel Vetter
2016-05-30  8:15   ` [Intel-gfx] " Maarten Lankhorst
2016-05-30  8:15     ` Maarten Lankhorst
2016-05-30  9:24     ` Daniel Vetter
2016-05-30  9:24       ` Daniel Vetter
2016-05-30  9:36       ` [Intel-gfx] " Maarten Lankhorst
2016-05-30  9:36         ` Maarten Lankhorst
2016-05-30 15:10         ` [Intel-gfx] " Daniel Vetter
2016-05-30 15:10           ` Daniel Vetter
2016-05-29 18:35 ` [PATCH 16/26] drm/hdlcd: Use helper support for nonblocking commits Daniel Vetter
2016-05-31 11:02   ` Liviu Dudau
2016-05-31 11:07     ` Daniel Vetter
2016-05-31 13:13       ` Liviu Dudau
2016-05-29 18:35 ` [PATCH 17/26] drm/fsl-du: Implement some semblance of vblank event handling Daniel Vetter
2016-05-29 18:35 ` [PATCH 18/26] drm/hisilicon: " Daniel Vetter
2016-05-29 18:35 ` [PATCH 19/26] drm/sun4i: " Daniel Vetter
2016-06-01 16:18   ` Maxime Ripard
2016-06-01 22:02     ` Daniel Vetter
2016-05-29 18:35 ` [PATCH 20/26] drm/atomic: kerneldoc for drm_atomic_crtc_needs_modeset Daniel Vetter
2016-05-29 18:35 ` [PATCH 21/26] drm/atomic-helper: nonblocking commit support Daniel Vetter
2016-05-30  8:01   ` [PATCH] " Daniel Vetter
2016-05-31 14:22     ` [Intel-gfx] " Maarten Lankhorst
2016-05-31 14:33       ` Daniel Vetter
2016-05-29 18:35 ` [PATCH 22/26] drm/i915: Signal drm events for atomic Daniel Vetter
2016-05-29 18:35 ` [PATCH 23/26] drm/i915: Roll out the helper nonblock tracking Daniel Vetter
2016-05-29 18:35 ` [PATCH 24/26] drm/rockchip: convert to helper nonblocking atomic commit Daniel Vetter
2016-05-29 18:35 ` [PATCH 25/26] drm/rockchip: Nuke pending event handling in preclose Daniel Vetter
2016-05-29 18:35 ` [PATCH 26/26] drm/virtio: Don't reinvent a flipping wheel Daniel Vetter
2016-05-31 13:40 ` ✗ Ro.CI.BAT: failure for RFC: generic nonblocking support in the atomic helpers Patchwork
2016-05-31 13:42 ` Patchwork
2016-05-31 14:29 ` Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.