Commit 964d2f97 authored by Rob Clark's avatar Rob Clark

drm/msm: Refcount submits

Before we remove dev->struct_mutex from the retire path, we have to deal
with the situation of a submit retiring before the submit ioctl returns.

To deal with this, ring->submits will hold a reference to the submit,
which is dropped when the submit is retired.  And the submit ioctl path
holds it's own ref, which it drops when it is done with the submit.

Also, add to submit list *after* getting/pinning bo's, to prevent badness
in case the completed fence is corrupted, and retire_worker mistakenly
believes the submit is done too early.
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Reviewed-by: default avatarKristian H. Kristensen <hoegsberg@google.com>
Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
parent 77d20529
...@@ -278,7 +278,6 @@ void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu); ...@@ -278,7 +278,6 @@ void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
bool msm_use_mmu(struct drm_device *dev); bool msm_use_mmu(struct drm_device *dev);
void msm_gem_submit_free(struct msm_gem_submit *submit);
int msm_ioctl_gem_submit(struct drm_device *dev, void *data, int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct drm_file *file); struct drm_file *file);
......
...@@ -213,6 +213,7 @@ void msm_gem_free_work(struct work_struct *work); ...@@ -213,6 +213,7 @@ void msm_gem_free_work(struct work_struct *work);
* lasts for the duration of the submit-ioctl. * lasts for the duration of the submit-ioctl.
*/ */
struct msm_gem_submit { struct msm_gem_submit {
struct kref ref;
struct drm_device *dev; struct drm_device *dev;
struct msm_gpu *gpu; struct msm_gpu *gpu;
struct msm_gem_address_space *aspace; struct msm_gem_address_space *aspace;
...@@ -249,6 +250,18 @@ struct msm_gem_submit { ...@@ -249,6 +250,18 @@ struct msm_gem_submit {
} bos[]; } bos[];
}; };
void __msm_gem_submit_destroy(struct kref *kref);
static inline void msm_gem_submit_get(struct msm_gem_submit *submit)
{
kref_get(&submit->ref);
}
static inline void msm_gem_submit_put(struct msm_gem_submit *submit)
{
kref_put(&submit->ref, __msm_gem_submit_destroy);
}
/* helper to determine of a buffer in submit should be dumped, used for both /* helper to determine of a buffer in submit should be dumped, used for both
* devcoredump and debugfs cmdstream dumping: * devcoredump and debugfs cmdstream dumping:
*/ */
......
...@@ -42,6 +42,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, ...@@ -42,6 +42,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
if (!submit) if (!submit)
return NULL; return NULL;
kref_init(&submit->ref);
submit->dev = dev; submit->dev = dev;
submit->aspace = queue->ctx->aspace; submit->aspace = queue->ctx->aspace;
submit->gpu = gpu; submit->gpu = gpu;
...@@ -60,14 +61,13 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, ...@@ -60,14 +61,13 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
return submit; return submit;
} }
void msm_gem_submit_free(struct msm_gem_submit *submit) void __msm_gem_submit_destroy(struct kref *kref)
{ {
struct msm_gem_submit *submit =
container_of(kref, struct msm_gem_submit, ref);
unsigned i; unsigned i;
dma_fence_put(submit->fence); dma_fence_put(submit->fence);
spin_lock(&submit->ring->submit_lock);
list_del(&submit->node);
spin_unlock(&submit->ring->submit_lock);
put_pid(submit->pid); put_pid(submit->pid);
msm_submitqueue_put(submit->queue); msm_submitqueue_put(submit->queue);
...@@ -847,8 +847,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -847,8 +847,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
submit_cleanup(submit); submit_cleanup(submit);
if (has_ww_ticket) if (has_ww_ticket)
ww_acquire_fini(&submit->ticket); ww_acquire_fini(&submit->ticket);
if (ret) msm_gem_submit_put(submit);
msm_gem_submit_free(submit);
out_unlock: out_unlock:
if (ret && (out_fence_fd >= 0)) if (ret && (out_fence_fd >= 0))
put_unused_fd(out_fence_fd); put_unused_fd(out_fence_fd);
......
...@@ -718,7 +718,12 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, ...@@ -718,7 +718,12 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
pm_runtime_mark_last_busy(&gpu->pdev->dev); pm_runtime_mark_last_busy(&gpu->pdev->dev);
pm_runtime_put_autosuspend(&gpu->pdev->dev); pm_runtime_put_autosuspend(&gpu->pdev->dev);
msm_gem_submit_free(submit);
spin_lock(&ring->submit_lock);
list_del(&submit->node);
spin_unlock(&ring->submit_lock);
msm_gem_submit_put(submit);
} }
static void retire_submits(struct msm_gpu *gpu) static void retire_submits(struct msm_gpu *gpu)
...@@ -791,10 +796,6 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) ...@@ -791,10 +796,6 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
submit->seqno = ++ring->seqno; submit->seqno = ++ring->seqno;
spin_lock(&ring->submit_lock);
list_add_tail(&submit->node, &ring->submits);
spin_unlock(&ring->submit_lock);
msm_rd_dump_submit(priv->rd, submit, NULL); msm_rd_dump_submit(priv->rd, submit, NULL);
update_sw_cntrs(gpu); update_sw_cntrs(gpu);
...@@ -821,6 +822,16 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) ...@@ -821,6 +822,16 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
msm_gem_active_get(drm_obj, gpu); msm_gem_active_get(drm_obj, gpu);
} }
/*
* ring->submits holds a ref to the submit, to deal with the case
* that a submit completes before msm_ioctl_gem_submit() returns.
*/
msm_gem_submit_get(submit);
spin_lock(&ring->submit_lock);
list_add_tail(&submit->node, &ring->submits);
spin_unlock(&ring->submit_lock);
gpu->funcs->submit(gpu, submit); gpu->funcs->submit(gpu, submit);
priv->lastctx = submit->queue->ctx; priv->lastctx = submit->queue->ctx;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment