drm: Reserve/unreserve GEM VRAM BOs from within pin/unpin functions
authorThomas Zimmermann <tzimmermann@suse.de>
Thu, 16 May 2019 16:27:46 +0000 (18:27 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Fri, 17 May 2019 11:14:11 +0000 (13:14 +0200)
The original bochs and vbox implementations of pin and unpin functions
automatically reserved BOs during validation. This functionality got lost
while converting the code to a generic implementation. This may result
in validating unlocked TTM BOs.

Adding the reserve and unreserve operations to GEM VRAM's pin and unpin
functions fixes the bochs and vbox drivers. Additionally the patch changes
the mgag200, ast and hibmc drivers to not reserve BOs by themselves.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reported-by: kernel test robot <lkp@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20190516162746.11636-3-tzimmermann@suse.de
Fixes: a3232987fdbf ("drm/bochs: Convert bochs driver to |struct drm_gem_vram_object|")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/drm_gem_vram_helper.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c
drivers/gpu/drm/mgag200/mgag200_mode.c

index 3475591a22c3fa703ba0e0a3e5c2278cde25192e..9aca9135a5ccb60dedb5c2f892f70a63e6f1cd27 100644 (file)
@@ -539,24 +539,16 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
                ast_fb = to_ast_framebuffer(fb);
                obj = ast_fb->obj;
                gbo = drm_gem_vram_of_gem(obj);
-               ret = drm_gem_vram_reserve(gbo, false);
-               if (ret)
-                       return ret;
                drm_gem_vram_push_to_system(gbo);
-               drm_gem_vram_unreserve(gbo);
        }
 
        ast_fb = to_ast_framebuffer(crtc->primary->fb);
        obj = ast_fb->obj;
        gbo = drm_gem_vram_of_gem(obj);
 
-       ret = drm_gem_vram_reserve(gbo, false);
-       if (ret)
-               return ret;
-
        ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
        if (ret)
-               goto err_drm_gem_vram_unreserve;
+               return ret;
        gpu_addr = drm_gem_vram_offset(gbo);
        if (gpu_addr < 0) {
                ret = (int)gpu_addr;
@@ -573,7 +565,6 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
                        ast_fbdev_set_base(ast, gpu_addr);
                }
        }
-       drm_gem_vram_unreserve(gbo);
 
        ast_set_offset_reg(crtc);
        ast_set_start_address_crt1(crtc, (u32)gpu_addr);
@@ -582,8 +573,6 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
 
 err_drm_gem_vram_unpin:
        drm_gem_vram_unpin(gbo);
-err_drm_gem_vram_unreserve:
-       drm_gem_vram_unreserve(gbo);
        return ret;
 }
 
@@ -630,8 +619,6 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc,
 
 static void ast_crtc_disable(struct drm_crtc *crtc)
 {
-       int ret;
-
        DRM_DEBUG_KMS("\n");
        ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
        if (crtc->primary->fb) {
@@ -639,11 +626,7 @@ static void ast_crtc_disable(struct drm_crtc *crtc)
                struct drm_gem_object *obj = ast_fb->obj;
                struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj);
 
-               ret = drm_gem_vram_reserve(gbo, false);
-               if (ret)
-                       return;
                drm_gem_vram_push_to_system(gbo);
-               drm_gem_vram_unreserve(gbo);
        }
        crtc->primary->fb = NULL;
 }
@@ -939,12 +922,7 @@ static int ast_cursor_init(struct drm_device *dev)
        if (ret)
                return ret;
        gbo = drm_gem_vram_of_gem(obj);
-       ret = drm_gem_vram_reserve(gbo, false);
-       if (unlikely(ret != 0))
-               goto fail;
-
        ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
-       drm_gem_vram_unreserve(gbo);
        if (ret)
                goto fail;
        gpu_addr = drm_gem_vram_offset(gbo);
index a002c03eaf4c974bf5846536aab28c444665edbe..bde8237e80212bfba8212f80d0c71a7a63f2bfa3 100644 (file)
@@ -235,10 +235,12 @@ int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
        int i, ret;
        struct ttm_operation_ctx ctx = { false, false };
 
-       if (gbo->pin_count) {
-               ++gbo->pin_count;
-               return 0;
-       }
+       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+       if (ret < 0)
+               return ret;
+
+       if (gbo->pin_count)
+               goto out;
 
        drm_gem_vram_placement(gbo, pl_flag);
        for (i = 0; i < gbo->placement.num_placement; ++i)
@@ -246,11 +248,17 @@ int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
 
        ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
        if (ret < 0)
-               return ret;
+               goto err_ttm_bo_unreserve;
 
-       gbo->pin_count = 1;
+out:
+       ++gbo->pin_count;
+       ttm_bo_unreserve(&gbo->bo);
 
        return 0;
+
+err_ttm_bo_unreserve:
+       ttm_bo_unreserve(&gbo->bo);
+       return ret;
 }
 EXPORT_SYMBOL(drm_gem_vram_pin);
 
@@ -308,21 +316,32 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
        int i, ret;
        struct ttm_operation_ctx ctx = { false, false };
 
+       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+       if (ret < 0)
+               return ret;
+
        if (WARN_ON_ONCE(!gbo->pin_count))
-               return 0;
+               goto out;
 
        --gbo->pin_count;
        if (gbo->pin_count)
-               return 0;
+               goto out;
 
        for (i = 0; i < gbo->placement.num_placement ; ++i)
                gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
 
        ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
        if (ret < 0)
-               return ret;
+               goto err_ttm_bo_unreserve;
+
+out:
+       ttm_bo_unreserve(&gbo->bo);
 
        return 0;
+
+err_ttm_bo_unreserve:
+       ttm_bo_unreserve(&gbo->bo);
+       return ret;
 }
 EXPORT_SYMBOL(drm_gem_vram_unpin);
 
@@ -377,12 +396,16 @@ int drm_gem_vram_push_to_system(struct drm_gem_vram_object *gbo)
        int i, ret;
        struct ttm_operation_ctx ctx = { false, false };
 
+       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+       if (ret < 0)
+               return ret;
+
        if (WARN_ON_ONCE(!gbo->pin_count))
-               return 0;
+               goto out;
 
        --gbo->pin_count;
        if (gbo->pin_count)
-               return 0;
+               goto out;
 
        if (gbo->kmap.virtual)
                ttm_bo_kunmap(&gbo->kmap);
@@ -393,9 +416,16 @@ int drm_gem_vram_push_to_system(struct drm_gem_vram_object *gbo)
 
        ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
        if (ret)
-               return ret;
+               goto err_ttm_bo_unreserve;
+
+out:
+       ttm_bo_unreserve(&gbo->bo);
 
        return 0;
+
+err_ttm_bo_unreserve:
+       ttm_bo_unreserve(&gbo->bo);
+       return ret;
 }
 EXPORT_SYMBOL(drm_gem_vram_push_to_system);
 
index db0dfa57844e48cf846696dd044bd671e9ebdf01..fbdf495779e058c9ea13c97a751c8a364011013c 100644 (file)
@@ -107,14 +107,8 @@ static void hibmc_plane_atomic_update(struct drm_plane *plane,
 
        hibmc_fb = to_hibmc_framebuffer(state->fb);
        gbo = drm_gem_vram_of_gem(hibmc_fb->obj);
-       ret = drm_gem_vram_reserve(gbo, false);
-       if (ret) {
-               DRM_ERROR("failed to reserve BO: %d", ret);
-               return;
-       }
 
        ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
-       drm_gem_vram_unreserve(gbo);
        if (ret) {
                DRM_ERROR("failed to pin bo: %d", ret);
                return;
index 9d2025fa16f8b05799954a2de7ea2c164c608fa6..bd5fbb23973ab43cdbbe06757f2c5465170bf56a 100644 (file)
@@ -63,7 +63,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
        struct drm_mode_fb_cmd2 mode_cmd;
        struct drm_gem_object *gobj = NULL;
        int ret = 0;
-       int ret1;
        size_t size;
        unsigned int bytes_per_pixel;
        struct drm_gem_vram_object *gbo = NULL;
@@ -91,16 +90,10 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
 
        gbo = drm_gem_vram_of_gem(gobj);
 
-       ret = drm_gem_vram_reserve(gbo, false);
-       if (ret) {
-               DRM_ERROR("failed to reserve bo: %d\n", ret);
-               goto out_unref_gem;
-       }
-
        ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
        if (ret) {
                DRM_ERROR("failed to pin fbcon: %d\n", ret);
-               goto out_unreserve_ttm_bo;
+               goto out_unref_gem;
        }
 
        base = drm_gem_vram_kmap(gbo, true, NULL);
@@ -109,7 +102,6 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
                DRM_ERROR("failed to kmap fbcon: %d\n", ret);
                goto out_unpin_bo;
        }
-       drm_gem_vram_unreserve(gbo);
 
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
@@ -141,16 +133,9 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper,
        return 0;
 
 out_release_fbi:
-       ret1 = drm_gem_vram_reserve(gbo, false);
-       if (ret1) {
-               DRM_ERROR("failed to rsv ttm_bo when release fbi: %d\n", ret1);
-               goto out_unref_gem;
-       }
        drm_gem_vram_kunmap(gbo);
 out_unpin_bo:
        drm_gem_vram_unpin(gbo);
-out_unreserve_ttm_bo:
-       drm_gem_vram_unreserve(gbo);
 out_unref_gem:
        drm_gem_object_put_unlocked(gobj);
 
index 3098bf5c174496778a31f3c8609eacb7b8728fc4..e79872c968bf64776742f5a4eea5cc64592a3c0d 100644 (file)
@@ -877,24 +877,16 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc,
                mga_fb = to_mga_framebuffer(fb);
                obj = mga_fb->obj;
                gbo = drm_gem_vram_of_gem(obj);
-               ret = drm_gem_vram_reserve(gbo, false);
-               if (ret)
-                       return ret;
                drm_gem_vram_push_to_system(gbo);
-               drm_gem_vram_unreserve(gbo);
        }
 
        mga_fb = to_mga_framebuffer(crtc->primary->fb);
        obj = mga_fb->obj;
        gbo = drm_gem_vram_of_gem(obj);
 
-       ret = drm_gem_vram_reserve(gbo, false);
-       if (ret)
-               return ret;
-
        ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
        if (ret)
-               goto err_drm_gem_vram_unreserve;
+               return ret;
        gpu_addr = drm_gem_vram_offset(gbo);
        if (gpu_addr < 0) {
                ret = (int)gpu_addr;
@@ -910,16 +902,12 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc,
                }
        }
 
-       drm_gem_vram_unreserve(gbo);
-
        mga_set_start_address(crtc, (u32)gpu_addr);
 
        return 0;
 
 err_drm_gem_vram_unpin:
        drm_gem_vram_unpin(gbo);
-err_drm_gem_vram_unreserve:
-       drm_gem_vram_unreserve(gbo);
        return ret;
 }
 
@@ -1434,7 +1422,6 @@ static void mga_crtc_destroy(struct drm_crtc *crtc)
 
 static void mga_crtc_disable(struct drm_crtc *crtc)
 {
-       int ret;
        DRM_DEBUG_KMS("\n");
        mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
        if (crtc->primary->fb) {
@@ -1442,11 +1429,7 @@ static void mga_crtc_disable(struct drm_crtc *crtc)
                struct drm_gem_object *obj = mga_fb->obj;
                struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj);
 
-               ret = drm_gem_vram_reserve(gbo, false);
-               if (ret)
-                       return;
                drm_gem_vram_push_to_system(gbo);
-               drm_gem_vram_unreserve(gbo);
        }
        crtc->primary->fb = NULL;
 }