summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2017-06-12 09:16:44 -0600
committerJordan Crouse <jcrouse@codeaurora.org>2017-06-12 15:11:51 -0600
commit5fb06424004f2d27a06e599bdc51faee8ca36c17 (patch)
treea74fe0f80e4c62f5afd066fe88e658390eb8aba6
parent8416e6772114538b0208e063eb991249296b2ce7 (diff)
drm/msm: fix leak in failed submit path
Change-Id: Ic0dedbadf485dd63ef727402b653a9d996a13632 Signed-off-by: Rob Clark <robdclark@gmail.com> Git-commit: 40e6815bba6e34e5560e8855b43cd3eb17b24b09 Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git [jcrouse@codeaurora.org: fix merge conflicts and initialize node at create] Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h1
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c22
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c3
3 files changed, 22 insertions, 4 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 8f56a3126008..408e05158827 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -437,6 +437,7 @@ struct msm_gem_address_space *
msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu,
const char *name);
+void msm_gem_submit_free(struct msm_gem_submit *submit);
int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
struct drm_file *file);
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index c861bfd77537..4c1a211fa3c9 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -59,6 +59,11 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
submit->secure = false;
+ /*
+ * Initalize node so we can safely list_del() on it if
+ * we fail in the submit path
+ */
+ INIT_LIST_HEAD(&submit->node);
INIT_LIST_HEAD(&submit->bo_list);
ww_acquire_init(&submit->ticket, &reservation_ww_class);
}
@@ -74,6 +79,15 @@ copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
return -EFAULT;
}
+void msm_gem_submit_free(struct msm_gem_submit *submit)
+{
+ if (!submit)
+ return;
+
+ list_del(&submit->node);
+ kfree(submit);
+}
+
static int submit_lookup_objects(struct msm_gpu *gpu,
struct msm_gem_submit *submit,
struct drm_msm_gem_submit *args, struct drm_file *file)
@@ -381,6 +395,9 @@ static void submit_cleanup(struct msm_gpu *gpu, struct msm_gem_submit *submit,
{
unsigned i;
+ if (!submit)
+ return;
+
for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj;
submit_unlock_unpin_bo(gpu, submit, i);
@@ -506,8 +523,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
args->fence = submit->fence;
out:
- if (submit)
- submit_cleanup(gpu, submit, !!ret);
+ submit_cleanup(gpu, submit, !!ret);
+ if (ret)
+ msm_gem_submit_free(submit);
mutex_unlock(&dev->struct_mutex);
return ret;
}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 81bab9cc22af..439fafdb198e 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -479,8 +479,7 @@ static void retire_submits(struct msm_gpu *gpu, uint32_t fence)
list_for_each_entry_safe(submit, tmp, &gpu->submit_list, node) {
if (COMPARE_FENCE_LTE(submit->fence, fence)) {
- list_del(&submit->node);
- kfree(submit);
+ msm_gem_submit_free(submit);
}
}
}