[RFT 1/5] drm/msm: Cleanup if pages_to_sg() fails
From: Rob Clark
Date: Tue Oct 06 2026 - 09:11:19 EST
We never really handled this. But in practice mapping to smmu would
have failed without an sgt, which would have been pretty obvious.
Signed-off-by: Rob Clark <robin.clark@xxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/msm/msm_gem.c | 41 ++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 130ae27ee00b..181b9ad32672 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -190,6 +190,7 @@ static void update_lru(struct drm_gem_object *obj)
static struct page **get_pages(struct drm_gem_object *obj)
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
+ int ret = 0;
msm_gem_assert_locked(obj);
@@ -209,19 +210,17 @@ static struct page **get_pages(struct drm_gem_object *obj)
return p;
}
- update_device_mem(dev->dev_private, obj->size);
-
msm_obj->pages = p;
msm_obj->sgt = drm_prime_pages_to_sg(obj->dev, p, npages);
if (IS_ERR(msm_obj->sgt)) {
- void *ptr = ERR_CAST(msm_obj->sgt);
-
DRM_DEV_ERROR(dev->dev, "failed to allocate sgt\n");
- msm_obj->sgt = NULL;
- return ptr;
+ ret = PTR_ERR(msm_obj->sgt);
+ goto error;
}
+ update_device_mem(dev->dev_private, obj->size);
+
/* For non-cached buffers, ensure the new pages are clean
* because display controller, GPU, etc. are not coherent:
*/
@@ -232,6 +231,14 @@ static struct page **get_pages(struct drm_gem_object *obj)
}
return msm_obj->pages;
+
+error:
+ msm_obj->sgt = NULL;
+
+ drm_gem_put_pages(obj, msm_obj->pages, false, false);
+ msm_obj->pages = NULL;
+
+ return ERR_PTR(ret);
}
static void put_pages(struct drm_gem_object *obj)
@@ -246,18 +253,16 @@ static void put_pages(struct drm_gem_object *obj)
drm_gpuvm_bo_gem_evict(obj, true);
if (msm_obj->pages) {
- if (msm_obj->sgt) {
- /* For non-cached buffers, ensure the new
- * pages are clean because display controller,
- * GPU, etc. are not coherent:
- */
- if (msm_obj->flags & MSM_BO_WC)
- sync_for_cpu(msm_obj);
-
- sg_free_table(msm_obj->sgt);
- kfree(msm_obj->sgt);
- msm_obj->sgt = NULL;
- }
+ /* For non-cached buffers, ensure the new
+ * pages are clean because display controller,
+ * GPU, etc. are not coherent:
+ */
+ if (msm_obj->flags & MSM_BO_WC)
+ sync_for_cpu(msm_obj);
+
+ sg_free_table(msm_obj->sgt);
+ kfree(msm_obj->sgt);
+ msm_obj->sgt = NULL;
update_device_mem(obj->dev->dev_private, -obj->size);
--
2.55.0