[PATCH v6 11/16] drm/msm/gem: Set resv before exposing obj
From: Rob Clark
Date: Fri Jul 17 2026 - 16:53:11 EST
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 <robin.clark@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/adreno/a6xx_gmu.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 +-
4 files changed, 23 insertions(+), 17 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/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 59143be07428..cb00bdf21ef6 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1134,10 +1134,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);
@@ -1145,15 +1152,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 */
@@ -1245,7 +1243,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;
@@ -1262,6 +1262,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;
@@ -1298,6 +1303,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
if (ret)
return ERR_PTR(ret);
+ obj->resv = dmabuf->resv;
drm_gem_private_object_init(dev, obj, size);
npages = size / PAGE_SIZE;
@@ -1331,7 +1337,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 762e546d25ef..47ff2bbc1915 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