[Intel-gfx] [PATCH v2 1/2] drm/atomic: move waiting for hw_done to a helper
Ville Syrjälä
ville.syrjala at linux.intel.com
Wed Jun 14 14:52:35 UTC 2017
On Wed, Jun 14, 2017 at 11:08:41AM +0200, Maarten Lankhorst wrote:
> Moving the wait to a helper allows callers outside of the core to
> wait for pending updates to complete.
>
> This can be used to prevent races against nonblocking modesets.
> Only the hw_done call in swap_state is moved to a helper, doing
> it for the other callers requires too many changes and I think this
> is the only useful one to export.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> ---
> drivers/gpu/drm/drm_atomic_helper.c | 51 +++++++++++++++++++++++++++----------
> include/drm/drm_atomic_helper.h | 1 +
> 2 files changed, 38 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 86d3093c6c9b..1b068ce1aea9 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -2067,6 +2067,41 @@ void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
> EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
>
> /**
> + * drm_atomic_helper_wait_for_hw_done - wait for all previous hw updates to complete.
> + * @crtc: crtc to wait on.
> + *
> + * This function waits for all previous hardware updates queued on @crtc
> + * to complete.
> + *
> + * Returns:
> + * 0 on success, negative error code on failure.
> + */
> +int drm_atomic_helper_wait_for_hw_done(struct drm_crtc *crtc)
> +{
> + struct drm_crtc_commit *commit;
> + long ret;
> +
> + 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)
> + return 0;
> +
> + ret = wait_for_completion_timeout(&commit->hw_done, 10 * HZ);
> + drm_crtc_commit_put(commit);
> +
> + if (ret == 0)
> + return -EBUSY;
-ETIMEDOUT ?
> +
> + return ret > 0 ? 0 : ret;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_wait_for_hw_done);
> +
> +/**
> * drm_atomic_helper_swap_state - store atomic state into current sw state
> * @state: atomic state
> * @stall: stall for proceeding commits
> @@ -2107,28 +2142,16 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> struct drm_crtc_state *old_crtc_state, *new_crtc_state;
> struct drm_plane *plane;
> struct drm_plane_state *old_plane_state, *new_plane_state;
> - struct drm_crtc_commit *commit;
> void *obj, *obj_state;
> const struct drm_private_state_funcs *funcs;
>
> if (stall) {
> for_each_new_crtc_in_state(state, crtc, new_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);
> + ret = drm_atomic_helper_wait_for_hw_done(crtc);
>
> - if (!commit)
> - continue;
> -
> - ret = wait_for_completion_timeout(&commit->hw_done,
> - 10*HZ);
> - if (ret == 0)
> + if (ret < 0)
> DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
> crtc->base.id, crtc->name);
> - drm_crtc_commit_put(commit);
> }
> }
>
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index f0a8678ae98e..175a1a3fed36 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -77,6 +77,7 @@ void
> drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
> bool atomic);
>
> +int drm_atomic_helper_wait_for_hw_done(struct drm_crtc *crtc);
> void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
> bool stall);
>
> --
> 2.11.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
More information about the dri-devel
mailing list