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 <[email protected]>
---
 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

Reply via email to