Don't swap the resv object _after_ exposing the newly created obj in LRU
or global objects list, as that creates a race condition where another
thread could lock the object using the original (per-obj) resv, but then
unlock after the resv is replaced.

Signed-off-by: Rob Clark <[email protected]>
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c    |  2 +-
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c |  2 +-
 drivers/gpu/drm/msm/msm_fb.c             |  4 +--
 drivers/gpu/drm/msm/msm_gem.c            | 32 ++++++++++++++----------
 drivers/gpu/drm/msm/msm_gem.h            |  2 +-
 5 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 2e5d7b53a0c3..9aed142faea1 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -1546,7 +1546,7 @@ static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, 
struct a6xx_gmu_bo *bo,
                flags |= MSM_BO_MAP_PRIV;
        }
 
-       bo->obj = msm_gem_new(dev, size, flags);
+       bo->obj = msm_gem_new(dev, size, flags, NULL);
        if (IS_ERR(bo->obj))
                return PTR_ERR(bo->obj);
 
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
index 7726edb0d4ed..c289dff78cd5 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
@@ -463,7 +463,7 @@ static int mdp4_kms_init(struct drm_device *dev)
                goto fail;
        }
 
-       mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | 
MSM_BO_SCANOUT);
+       mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | 
MSM_BO_SCANOUT, NULL);
        if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
                ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
                DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: 
%d\n", ret);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 9b681e144c07..ee17a47f31c4 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -267,11 +267,11 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, 
int p, uint32_t format
        /* allocate backing bo */
        size = mode_cmd.pitches[0] * mode_cmd.height;
        DBG("allocating %d bytes for fb %d", size, dev->primary->index);
-       bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
+       bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN, 
NULL);
        if (IS_ERR(bo)) {
                dev_warn(dev->dev, "could not allocate stolen bo\n");
                /* try regular bo: */
-               bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+               bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC, NULL);
        }
        if (IS_ERR(bo)) {
                DRM_DEV_ERROR(dev->dev, "failed to allocate buffer object\n");
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 3c36b1c4a4d5..535c6e1acb3c 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1136,10 +1136,17 @@ int msm_gem_new_handle(struct drm_device *dev, struct 
drm_file *file,
                size_t size, uint32_t flags, uint32_t *handle,
                char *name)
 {
-       struct drm_gem_object *obj;
+       struct drm_gem_object *obj, *r_obj = NULL;
        int ret;
 
-       obj = msm_gem_new(dev, size, flags);
+       if (flags & MSM_BO_NO_SHARE) {
+               struct msm_context *ctx = file->driver_priv;
+               struct drm_gpuvm *vm = msm_context_vm(dev, ctx);
+
+               r_obj = drm_gpuvm_resv_obj(vm);
+       }
+
+       obj = msm_gem_new(dev, size, flags, r_obj);
 
        if (IS_ERR(obj))
                return PTR_ERR(obj);
@@ -1147,15 +1154,6 @@ int msm_gem_new_handle(struct drm_device *dev, struct 
drm_file *file,
        if (name)
                msm_gem_object_set_name(obj, "%s", name);
 
-       if (flags & MSM_BO_NO_SHARE) {
-               struct msm_context *ctx = file->driver_priv;
-               struct drm_gem_object *r_obj = drm_gpuvm_resv_obj(ctx->vm);
-
-               drm_gem_object_get(r_obj);
-
-               obj->resv = r_obj->resv;
-       }
-
        ret = drm_gem_handle_create(file, obj, handle);
 
        /* drop reference from allocate - handle holds it now */
@@ -1251,7 +1249,9 @@ static int msm_gem_init_bookkeeping(struct drm_gem_object 
*obj)
        return drm_gem_create_mmap_offset(obj);
 }
 
-struct drm_gem_object *msm_gem_new(struct drm_device *dev, size_t size, 
uint32_t flags)
+struct drm_gem_object *
+msm_gem_new(struct drm_device *dev, size_t size, uint32_t flags,
+           struct drm_gem_object *r_obj)
 {
        struct drm_gem_object *obj = NULL;
        int ret;
@@ -1268,6 +1268,11 @@ struct drm_gem_object *msm_gem_new(struct drm_device 
*dev, size_t size, uint32_t
        if (ret)
                return ERR_PTR(ret);
 
+       if (flags & MSM_BO_NO_SHARE) {
+               drm_gem_object_get(r_obj);
+               obj->resv = r_obj->resv;
+       }
+
        ret = drm_gem_object_init(dev, obj, size);
        if (ret)
                goto fail;
@@ -1311,6 +1316,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device 
*dev,
         * up in drm_gem_object_put() -> msm_gem_free_object()
         */
        obj->import_attach = attach;
+       obj->resv = dmabuf->resv;
        drm_gem_private_object_init(dev, obj, size);
 
        npages = size / PAGE_SIZE;
@@ -1346,7 +1352,7 @@ void *msm_gem_kernel_new(struct drm_device *dev, size_t 
size, uint32_t flags,
                         uint64_t *iova)
 {
        void *vaddr;
-       struct drm_gem_object *obj = msm_gem_new(dev, size, flags);
+       struct drm_gem_object *obj = msm_gem_new(dev, size, flags, NULL);
        int ret;
 
        if (IS_ERR(obj))
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 86dc93cc1804..dff60cbc9d95 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -296,7 +296,7 @@ int msm_gem_cpu_fini(struct drm_gem_object *obj);
 int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
                size_t size, uint32_t flags, uint32_t *handle, char *name);
 struct drm_gem_object *msm_gem_new(struct drm_device *dev,
-               size_t size, uint32_t flags);
+               size_t size, uint32_t flags, struct drm_gem_object *r_obj);
 void *msm_gem_kernel_new(struct drm_device *dev, size_t size, uint32_t flags,
                         struct drm_gpuvm *vm, struct drm_gem_object **bo,
                         uint64_t *iova);
-- 
2.55.0

Reply via email to