All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-10-31 22:36 ` Rob Clark
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Clark @ 2019-10-31 22:36 UTC (permalink / raw)
  To: dri-devel
  Cc: Rob Clark, Sean Paul, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, David Airlie, Daniel Vetter, open list

From: Rob Clark <robdclark@chromium.org>

Stalling on cleanup_done ensures that any atomic state related to a
nonblock commit no longer has dangling references to per-object state
that can be freed.

Otherwise, if a !nonblock commit completes after a nonblock commit has
swapped state (ie. the synchronous part of the nonblock commit comes
before the !nonblock commit), but before the asynchronous part of the
nonblock commit completes, what was the new per-object state in the
nonblock commit can be freed.

This shows up with the new self-refresh helper, as _update_avg_times()
dereferences the original old and new crtc_state.

Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
---
Other possibilities:
1) maybe block later before freeing atomic state?
2) refcount individual per-object state

 drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 3ef2ac52ce94..a5d95429f91b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
-- 
2.21.0


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

* [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-10-31 22:36 ` Rob Clark
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Clark @ 2019-10-31 22:36 UTC (permalink / raw)
  To: dri-devel
  Cc: Rob Clark, Sean Paul, Maarten Lankhorst, Maxime Ripard,
	Sean Paul, David Airlie, Daniel Vetter, open list

From: Rob Clark <robdclark@chromium.org>

Stalling on cleanup_done ensures that any atomic state related to a
nonblock commit no longer has dangling references to per-object state
that can be freed.

Otherwise, if a !nonblock commit completes after a nonblock commit has
swapped state (ie. the synchronous part of the nonblock commit comes
before the !nonblock commit), but before the asynchronous part of the
nonblock commit completes, what was the new per-object state in the
nonblock commit can be freed.

This shows up with the new self-refresh helper, as _update_avg_times()
dereferences the original old and new crtc_state.

Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
---
Other possibilities:
1) maybe block later before freeing atomic state?
2) refcount individual per-object state

 drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 3ef2ac52ce94..a5d95429f91b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
-- 
2.21.0

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

* [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-10-31 22:36 ` Rob Clark
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Clark @ 2019-10-31 22:36 UTC (permalink / raw)
  To: dri-devel; +Cc: Rob Clark, David Airlie, open list, Sean Paul, Sean Paul

From: Rob Clark <robdclark@chromium.org>

Stalling on cleanup_done ensures that any atomic state related to a
nonblock commit no longer has dangling references to per-object state
that can be freed.

Otherwise, if a !nonblock commit completes after a nonblock commit has
swapped state (ie. the synchronous part of the nonblock commit comes
before the !nonblock commit), but before the asynchronous part of the
nonblock commit completes, what was the new per-object state in the
nonblock commit can be freed.

This shows up with the new self-refresh helper, as _update_avg_times()
dereferences the original old and new crtc_state.

Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
---
Other possibilities:
1) maybe block later before freeing atomic state?
2) refcount individual per-object state

 drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 3ef2ac52ce94..a5d95429f91b 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
@@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 			if (!commit)
 				continue;
 
-			ret = wait_for_completion_interruptible(&commit->hw_done);
+			ret = wait_for_completion_interruptible(&commit->cleanup_done);
 			if (ret)
 				return ret;
 		}
-- 
2.21.0

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

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:46   ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 14:46 UTC (permalink / raw)
  To: Rob Clark, dri-devel
  Cc: Rob Clark, Sean Paul, Maxime Ripard, Sean Paul, David Airlie,
	Daniel Vetter, open list

Op 31-10-2019 om 23:36 schreef Rob Clark:
> From: Rob Clark <robdclark@chromium.org>
>
> Stalling on cleanup_done ensures that any atomic state related to a
> nonblock commit no longer has dangling references to per-object state
> that can be freed.
>
> Otherwise, if a !nonblock commit completes after a nonblock commit has
> swapped state (ie. the synchronous part of the nonblock commit comes
> before the !nonblock commit), but before the asynchronous part of the
> nonblock commit completes, what was the new per-object state in the
> nonblock commit can be freed.
>
> This shows up with the new self-refresh helper, as _update_avg_times()
> dereferences the original old and new crtc_state.
>
> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> Other possibilities:
> 1) maybe block later before freeing atomic state?
> 2) refcount individual per-object state
>
>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3ef2ac52ce94..a5d95429f91b 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}

Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.

Self refresh helpers should be fixed. :)


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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:46   ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 14:46 UTC (permalink / raw)
  To: Rob Clark, dri-devel
  Cc: Rob Clark, David Airlie, open list, Sean Paul, Sean Paul

Op 31-10-2019 om 23:36 schreef Rob Clark:
> From: Rob Clark <robdclark@chromium.org>
>
> Stalling on cleanup_done ensures that any atomic state related to a
> nonblock commit no longer has dangling references to per-object state
> that can be freed.
>
> Otherwise, if a !nonblock commit completes after a nonblock commit has
> swapped state (ie. the synchronous part of the nonblock commit comes
> before the !nonblock commit), but before the asynchronous part of the
> nonblock commit completes, what was the new per-object state in the
> nonblock commit can be freed.
>
> This shows up with the new self-refresh helper, as _update_avg_times()
> dereferences the original old and new crtc_state.
>
> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> Other possibilities:
> 1) maybe block later before freeing atomic state?
> 2) refcount individual per-object state
>
>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3ef2ac52ce94..a5d95429f91b 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}

Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.

Self refresh helpers should be fixed. :)

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

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
  2019-10-31 22:36 ` Rob Clark
  (?)
@ 2019-11-01 14:56   ` Maarten Lankhorst
  -1 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 14:56 UTC (permalink / raw)
  To: Rob Clark, dri-devel
  Cc: Rob Clark, Sean Paul, Maxime Ripard, Sean Paul, David Airlie,
	Daniel Vetter, open list

Op 31-10-2019 om 23:36 schreef Rob Clark:
> From: Rob Clark <robdclark@chromium.org>
>
> Stalling on cleanup_done ensures that any atomic state related to a
> nonblock commit no longer has dangling references to per-object state
> that can be freed.
>
> Otherwise, if a !nonblock commit completes after a nonblock commit has
> swapped state (ie. the synchronous part of the nonblock commit comes
> before the !nonblock commit), but before the asynchronous part of the
> nonblock commit completes, what was the new per-object state in the
> nonblock commit can be freed.
>
> This shows up with the new self-refresh helper, as _update_avg_times()
> dereferences the original old and new crtc_state.
>
> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> Other possibilities:
> 1) maybe block later before freeing atomic state?
> 2) refcount individual per-object state
>
>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3ef2ac52ce94..a5d95429f91b 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}

From setup_commit():

 * Completion of the hardware commit step must be signalled using
 * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed
 * to read or change any permanent software or hardware modeset state. The only
 * exception is state protected by other means than &drm_modeset_lock locks.
 * Only the free standing @state with pointers to the old state structures can
 * be inspected, e.g. to clean up old buffers using
 * drm_atomic_helper_cleanup_planes().

And the hw_done function says pretty much the same thing. :)


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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:56   ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 14:56 UTC (permalink / raw)
  To: Rob Clark, dri-devel
  Cc: Rob Clark, Sean Paul, Maxime Ripard, Sean Paul, David Airlie,
	Daniel Vetter, open list

Op 31-10-2019 om 23:36 schreef Rob Clark:
> From: Rob Clark <robdclark@chromium.org>
>
> Stalling on cleanup_done ensures that any atomic state related to a
> nonblock commit no longer has dangling references to per-object state
> that can be freed.
>
> Otherwise, if a !nonblock commit completes after a nonblock commit has
> swapped state (ie. the synchronous part of the nonblock commit comes
> before the !nonblock commit), but before the asynchronous part of the
> nonblock commit completes, what was the new per-object state in the
> nonblock commit can be freed.
>
> This shows up with the new self-refresh helper, as _update_avg_times()
> dereferences the original old and new crtc_state.
>
> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> Other possibilities:
> 1) maybe block later before freeing atomic state?
> 2) refcount individual per-object state
>
>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3ef2ac52ce94..a5d95429f91b 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}

>From setup_commit():

 * Completion of the hardware commit step must be signalled using
 * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed
 * to read or change any permanent software or hardware modeset state. The only
 * exception is state protected by other means than &drm_modeset_lock locks.
 * Only the free standing @state with pointers to the old state structures can
 * be inspected, e.g. to clean up old buffers using
 * drm_atomic_helper_cleanup_planes().

And the hw_done function says pretty much the same thing. :)

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:56   ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 14:56 UTC (permalink / raw)
  To: Rob Clark, dri-devel
  Cc: Rob Clark, David Airlie, open list, Sean Paul, Sean Paul

Op 31-10-2019 om 23:36 schreef Rob Clark:
> From: Rob Clark <robdclark@chromium.org>
>
> Stalling on cleanup_done ensures that any atomic state related to a
> nonblock commit no longer has dangling references to per-object state
> that can be freed.
>
> Otherwise, if a !nonblock commit completes after a nonblock commit has
> swapped state (ie. the synchronous part of the nonblock commit comes
> before the !nonblock commit), but before the asynchronous part of the
> nonblock commit completes, what was the new per-object state in the
> nonblock commit can be freed.
>
> This shows up with the new self-refresh helper, as _update_avg_times()
> dereferences the original old and new crtc_state.
>
> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> Cc: Sean Paul <seanpaul@chromium.org>
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
> Other possibilities:
> 1) maybe block later before freeing atomic state?
> 2) refcount individual per-object state
>
>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 3ef2ac52ce94..a5d95429f91b 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}
> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>  			if (!commit)
>  				continue;
>  
> -			ret = wait_for_completion_interruptible(&commit->hw_done);
> +			ret = wait_for_completion_interruptible(&commit->cleanup_done);
>  			if (ret)
>  				return ret;
>  		}

From setup_commit():

 * Completion of the hardware commit step must be signalled using
 * drm_atomic_helper_commit_hw_done(). After this step the driver is not allowed
 * to read or change any permanent software or hardware modeset state. The only
 * exception is state protected by other means than &drm_modeset_lock locks.
 * Only the free standing @state with pointers to the old state structures can
 * be inspected, e.g. to clean up old buffers using
 * drm_atomic_helper_cleanup_planes().

And the hw_done function says pretty much the same thing. :)

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

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:59     ` Rob Clark
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Clark @ 2019-11-01 14:59 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: dri-devel, Rob Clark, Sean Paul, Maxime Ripard, Sean Paul,
	David Airlie, Daniel Vetter, open list

On Fri, Nov 1, 2019 at 7:47 AM Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Op 31-10-2019 om 23:36 schreef Rob Clark:
> > From: Rob Clark <robdclark@chromium.org>
> >
> > Stalling on cleanup_done ensures that any atomic state related to a
> > nonblock commit no longer has dangling references to per-object state
> > that can be freed.
> >
> > Otherwise, if a !nonblock commit completes after a nonblock commit has
> > swapped state (ie. the synchronous part of the nonblock commit comes
> > before the !nonblock commit), but before the asynchronous part of the
> > nonblock commit completes, what was the new per-object state in the
> > nonblock commit can be freed.
> >
> > This shows up with the new self-refresh helper, as _update_avg_times()
> > dereferences the original old and new crtc_state.
> >
> > Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> > Cc: Sean Paul <seanpaul@chromium.org>
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > ---
> > Other possibilities:
> > 1) maybe block later before freeing atomic state?
> > 2) refcount individual per-object state
> >
> >  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 3ef2ac52ce94..a5d95429f91b 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
> > @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
> > @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
>
> Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.
>

hmm, it would be nice if the for_each_blah_in_state() iterators would
splat on incorrect usage, then..  it tool a while to track down what
was going wrong.  And Sean claimed the self refresh helpers worked for
him on rockchip/i915 (although I'm starting to suspect maybe he just
didn't have enough debug options enabled to poison freed memory?)

> Self refresh helpers should be fixed. :)

Looks like what they need out of crtc_state is pretty minimal, maybe
they could extract out crtc_state->self_refresh_active earlier..

BR,
-R

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 14:59     ` Rob Clark
  0 siblings, 0 replies; 12+ messages in thread
From: Rob Clark @ 2019-11-01 14:59 UTC (permalink / raw)
  To: Maarten Lankhorst
  Cc: Rob Clark, David Airlie, open list, Sean Paul, dri-devel, Sean Paul

On Fri, Nov 1, 2019 at 7:47 AM Maarten Lankhorst
<maarten.lankhorst@linux.intel.com> wrote:
>
> Op 31-10-2019 om 23:36 schreef Rob Clark:
> > From: Rob Clark <robdclark@chromium.org>
> >
> > Stalling on cleanup_done ensures that any atomic state related to a
> > nonblock commit no longer has dangling references to per-object state
> > that can be freed.
> >
> > Otherwise, if a !nonblock commit completes after a nonblock commit has
> > swapped state (ie. the synchronous part of the nonblock commit comes
> > before the !nonblock commit), but before the asynchronous part of the
> > nonblock commit completes, what was the new per-object state in the
> > nonblock commit can be freed.
> >
> > This shows up with the new self-refresh helper, as _update_avg_times()
> > dereferences the original old and new crtc_state.
> >
> > Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
> > Cc: Sean Paul <seanpaul@chromium.org>
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > ---
> > Other possibilities:
> > 1) maybe block later before freeing atomic state?
> > 2) refcount individual per-object state
> >
> >  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> > index 3ef2ac52ce94..a5d95429f91b 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
> > @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
> > @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> >                       if (!commit)
> >                               continue;
> >
> > -                     ret = wait_for_completion_interruptible(&commit->hw_done);
> > +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
> >                       if (ret)
> >                               return ret;
> >               }
>
> Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.
>

hmm, it would be nice if the for_each_blah_in_state() iterators would
splat on incorrect usage, then..  it tool a while to track down what
was going wrong.  And Sean claimed the self refresh helpers worked for
him on rockchip/i915 (although I'm starting to suspect maybe he just
didn't have enough debug options enabled to poison freed memory?)

> Self refresh helpers should be fixed. :)

Looks like what they need out of crtc_state is pretty minimal, maybe
they could extract out crtc_state->self_refresh_active earlier..

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

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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 16:00       ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 16:00 UTC (permalink / raw)
  To: Rob Clark
  Cc: dri-devel, Rob Clark, Sean Paul, Maxime Ripard, Sean Paul,
	David Airlie, Daniel Vetter, open list

Op 01-11-2019 om 15:59 schreef Rob Clark:
> On Fri, Nov 1, 2019 at 7:47 AM Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Op 31-10-2019 om 23:36 schreef Rob Clark:
>>> From: Rob Clark <robdclark@chromium.org>
>>>
>>> Stalling on cleanup_done ensures that any atomic state related to a
>>> nonblock commit no longer has dangling references to per-object state
>>> that can be freed.
>>>
>>> Otherwise, if a !nonblock commit completes after a nonblock commit has
>>> swapped state (ie. the synchronous part of the nonblock commit comes
>>> before the !nonblock commit), but before the asynchronous part of the
>>> nonblock commit completes, what was the new per-object state in the
>>> nonblock commit can be freed.
>>>
>>> This shows up with the new self-refresh helper, as _update_avg_times()
>>> dereferences the original old and new crtc_state.
>>>
>>> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
>>> Cc: Sean Paul <seanpaul@chromium.org>
>>> Signed-off-by: Rob Clark <robdclark@chromium.org>
>>> ---
>>> Other possibilities:
>>> 1) maybe block later before freeing atomic state?
>>> 2) refcount individual per-object state
>>>
>>>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>> index 3ef2ac52ce94..a5d95429f91b 100644
>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>>> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>>> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>> Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.
>>
> hmm, it would be nice if the for_each_blah_in_state() iterators would
> splat on incorrect usage, then..  it tool a while to track down what
> was going wrong.  And Sean claimed the self refresh helpers worked for
> him on rockchip/i915 (although I'm starting to suspect maybe he just
> didn't have enough debug options enabled to poison freed memory?)
Could do a memset on the new arrays after hw_done?
>> Self refresh helpers should be fixed. :)
> Looks like what they need out of crtc_state is pretty minimal, maybe
> they could extract out crtc_state->self_refresh_active earlier..

Yeah, something like that would work. :)


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

* Re: [PATCH] drm/atomic: swap_state should stall on cleanup_done
@ 2019-11-01 16:00       ` Maarten Lankhorst
  0 siblings, 0 replies; 12+ messages in thread
From: Maarten Lankhorst @ 2019-11-01 16:00 UTC (permalink / raw)
  To: Rob Clark
  Cc: Rob Clark, David Airlie, open list, Sean Paul, dri-devel, Sean Paul

Op 01-11-2019 om 15:59 schreef Rob Clark:
> On Fri, Nov 1, 2019 at 7:47 AM Maarten Lankhorst
> <maarten.lankhorst@linux.intel.com> wrote:
>> Op 31-10-2019 om 23:36 schreef Rob Clark:
>>> From: Rob Clark <robdclark@chromium.org>
>>>
>>> Stalling on cleanup_done ensures that any atomic state related to a
>>> nonblock commit no longer has dangling references to per-object state
>>> that can be freed.
>>>
>>> Otherwise, if a !nonblock commit completes after a nonblock commit has
>>> swapped state (ie. the synchronous part of the nonblock commit comes
>>> before the !nonblock commit), but before the asynchronous part of the
>>> nonblock commit completes, what was the new per-object state in the
>>> nonblock commit can be freed.
>>>
>>> This shows up with the new self-refresh helper, as _update_avg_times()
>>> dereferences the original old and new crtc_state.
>>>
>>> Fixes: d4da4e33341c ("drm: Measure Self Refresh Entry/Exit times to avoid thrashing")
>>> Cc: Sean Paul <seanpaul@chromium.org>
>>> Signed-off-by: Rob Clark <robdclark@chromium.org>
>>> ---
>>> Other possibilities:
>>> 1) maybe block later before freeing atomic state?
>>> 2) refcount individual per-object state
>>>
>>>  drivers/gpu/drm/drm_atomic_helper.c | 6 +++---
>>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
>>> index 3ef2ac52ce94..a5d95429f91b 100644
>>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>>> @@ -2711,7 +2711,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>>> @@ -2722,7 +2722,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>>> @@ -2733,7 +2733,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
>>>                       if (!commit)
>>>                               continue;
>>>
>>> -                     ret = wait_for_completion_interruptible(&commit->hw_done);
>>> +                     ret = wait_for_completion_interruptible(&commit->cleanup_done);
>>>                       if (ret)
>>>                               return ret;
>>>               }
>> Nack, hw_done means all new_crtc_state (from the old commit pov) dereferences are done.
>>
> hmm, it would be nice if the for_each_blah_in_state() iterators would
> splat on incorrect usage, then..  it tool a while to track down what
> was going wrong.  And Sean claimed the self refresh helpers worked for
> him on rockchip/i915 (although I'm starting to suspect maybe he just
> didn't have enough debug options enabled to poison freed memory?)
Could do a memset on the new arrays after hw_done?
>> Self refresh helpers should be fixed. :)
> Looks like what they need out of crtc_state is pretty minimal, maybe
> they could extract out crtc_state->self_refresh_active earlier..

Yeah, something like that would work. :)

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

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

end of thread, other threads:[~2019-11-01 16:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-31 22:36 [PATCH] drm/atomic: swap_state should stall on cleanup_done Rob Clark
2019-10-31 22:36 ` Rob Clark
2019-10-31 22:36 ` Rob Clark
2019-11-01 14:46 ` Maarten Lankhorst
2019-11-01 14:46   ` Maarten Lankhorst
2019-11-01 14:59   ` Rob Clark
2019-11-01 14:59     ` Rob Clark
2019-11-01 16:00     ` Maarten Lankhorst
2019-11-01 16:00       ` Maarten Lankhorst
2019-11-01 14:56 ` Maarten Lankhorst
2019-11-01 14:56   ` Maarten Lankhorst
2019-11-01 14:56   ` Maarten Lankhorst

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.