From b1164ce49705ab2db8f716fa6f6445a5f923aa79 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..6462dd0 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(obj, file_priv); } static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) -- 1.7.10.4