[PATCH] drm/msm: move submit fence wait out of struct_mutex

Rob Clark robdclark at gmail.com
Sat Feb 25 16:03:43 UTC 2017


On Sat, Feb 25, 2017 at 10:43 AM, Rob Clark <robdclark at gmail.com> wrote:
> Probably a symptom of needing finer grained locking, but if we wait on
> the incoming fence-fd (which could come from a different context) while
> holding struct_mutex, that blocks retire_worker so gpu fences cannot get
> scheduled.

s/scheduled/signalled/

> This causes a problem if userspace manages to get more than a frame
> ahead, leaving the atomic-commit worker blocked waiting on fences that
> cannot be signaled because submit is blocked waiting for a fence
> signalled from vblank (after the atomic commit which is blocked).
>
> If we start having multiple fence ctxs for the gpu, submit_fence_sync()
> would probably need to move outside of struct_mutex as well.
>
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
>  drivers/gpu/drm/msm/msm_gem_submit.c | 39 +++++++++++++++++-------------------
>  1 file changed, 18 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
> index 1172fe7..1c545eb 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -404,6 +404,24 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
>         if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS)
>                 return -EINVAL;
>
> +       if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
> +               in_fence = sync_file_get_fence(args->fence_fd);
> +
> +               if (!in_fence)
> +                       return -EINVAL;
> +
> +               /* TODO if we get an array-fence due to userspace merging multiple
> +                * fences, we need a way to determine if all the backing fences
> +                * are from our own context..
> +                */
> +
> +               if (in_fence->context != gpu->fctx->context) {
> +                       ret = dma_fence_wait(in_fence, true);
> +                       if (ret)
> +                               return ret;
> +               }
> +       }
> +
>         ret = mutex_lock_interruptible(&dev->struct_mutex);
>         if (ret)
>                 return ret;
> @@ -431,27 +449,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
>         if (ret)
>                 goto out;
>
> -       if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
> -               in_fence = sync_file_get_fence(args->fence_fd);
> -
> -               if (!in_fence) {
> -                       ret = -EINVAL;
> -                       goto out;
> -               }
> -
> -               /* TODO if we get an array-fence due to userspace merging multiple
> -                * fences, we need a way to determine if all the backing fences
> -                * are from our own context..
> -                */
> -
> -               if (in_fence->context != gpu->fctx->context) {
> -                       ret = dma_fence_wait(in_fence, true);
> -                       if (ret)
> -                               goto out;
> -               }
> -
> -       }
> -
>         if (!(args->fence & MSM_SUBMIT_NO_IMPLICIT)) {
>                 ret = submit_fence_sync(submit);
>                 if (ret)
> --
> 2.9.3
>


More information about the dri-devel mailing list