From d5c26b333c160b5583160ae1ddeecb8e34f4e737 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 31 Jul 2012 22:09:29 -0400 Subject: [PATCH] drm/radeon: free virtual address early to avoid issue with delayed delete ttm might delay the bo deletion and userspace might try to reuse the virtual address before it happens. To avoid this delete the virtual address early on. Should fix : https://bugs.freedesktop.org/show_bug.cgi?id=45018 Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon_gem.c | 59 +++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d0452..5809053 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -37,6 +37,39 @@ int radeon_gem_object_init(struct drm_gem_object *obj) return 0; } +void radeon_gem_object_va_free(struct drm_gem_object *gobj, + struct drm_file *file_priv) +{ + struct radeon_bo *rbo = gem_to_radeon_bo(gobj); + struct radeon_device *rdev = rbo->rdev; + struct radeon_vm *vm = NULL; + struct radeon_bo_va *bo_va, *tmp; + + if (rdev->family < CHIP_CAYMAN) { + return; + } + if (file_priv) { + struct radeon_fpriv *fpriv = file_priv->driver_priv; + vm = &fpriv->vm; + } + + if (radeon_bo_reserve(rbo, false)) { + return; + } + list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { + if (vm && bo_va->vm != vm) { + continue; + } + /* remove from this vm address space */ + mutex_lock(&vm->mutex); + list_del(&bo_va->vm_list); + mutex_unlock(&vm->mutex); + list_del(&bo_va->bo_list); + kfree(bo_va); + } + radeon_bo_unreserve(rbo); +} + void radeon_gem_object_free(struct drm_gem_object *gobj) { struct radeon_bo *robj = gem_to_radeon_bo(gobj); @@ -44,6 +77,7 @@ void radeon_gem_object_free(struct drm_gem_object *gobj) if (robj) { if (robj->gem_base.import_attach) drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); + radeon_gem_object_va_free(gobj, NULL); radeon_bo_unref(&robj); } } @@ -130,30 +164,7 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri void radeon_gem_object_close(struct drm_gem_object *obj, struct drm_file *file_priv) { - struct radeon_bo *rbo = gem_to_radeon_bo(obj); - struct radeon_device *rdev = rbo->rdev; - struct radeon_fpriv *fpriv = file_priv->driver_priv; - struct radeon_vm *vm = &fpriv->vm; - struct radeon_bo_va *bo_va, *tmp; - - if (rdev->family < CHIP_CAYMAN) { - return; - } - - if (radeon_bo_reserve(rbo, false)) { - return; - } - list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { - if (bo_va->vm == vm) { - /* remove from this vm address space */ - mutex_lock(&vm->mutex); - list_del(&bo_va->vm_list); - mutex_unlock(&vm->mutex); - list_del(&bo_va->bo_list); - kfree(bo_va); - } - } - radeon_bo_unreserve(rbo); + radeon_gem_object_va_free(gobj, file_priv); } static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) -- 1.7.10.4