From e8c49e4545565a5fbcfca34425d86de16280316c Mon Sep 17 00:00:00 2001 From: Chaudhary Amit Kumar Date: Wed, 17 Oct 2018 16:52:04 +0530 Subject: [PATCH 0823/4131] drm/amdgpu: separate BO from GEM object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to have multiple GEM objects for one BO. Change-Id: I0cb30db4177ddcb18cb7ff294c220e700c9a26bc Signed-off-by: Christian König Signed-off-by: Kalyan Alle Signed-off-by: Chaudhary Amit Kumar --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 9 ++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 42 +++++++++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 4 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 20 +++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 17 ++++++++++-- 6 files changed, 81 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e7ffabe..d17a6a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -382,7 +382,14 @@ struct amdgpu_clock { */ #define AMDGPU_GEM_DOMAIN_MAX 0x3 -#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base) + +struct amdgpu_gem_object { + struct drm_gem_object base; + struct list_head list; + struct amdgpu_bo *bo; +}; + +#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_gem_object, base)->bo void amdgpu_gem_object_free(struct drm_gem_object *obj); int amdgpu_gem_object_open(struct drm_gem_object *obj, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index c6e5ecd..6689e5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -33,12 +33,21 @@ void amdgpu_gem_object_free(struct drm_gem_object *gobj) { - struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj); + struct amdgpu_gem_object *aobj; + + aobj = container_of((gobj), struct amdgpu_gem_object, base); + if (aobj->base.import_attach) + drm_prime_gem_destroy(&aobj->base, aobj->bo->tbo.sg); + + ww_mutex_lock(&aobj->bo->tbo.resv->lock, NULL); + list_del(&aobj->list); + ww_mutex_unlock(&aobj->bo->tbo.resv->lock); + + amdgpu_mn_unregister(aobj->bo); + amdgpu_bo_unref(&aobj->bo); + drm_gem_object_release(&aobj->base); + kfree(aobj); - if (robj) { - amdgpu_mn_unregister(robj); - amdgpu_bo_unref(&robj); - } } int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, @@ -47,6 +56,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, struct drm_gem_object **obj) { struct amdgpu_bo *robj; + struct amdgpu_gem_object *gobj; unsigned long max_size; int r; @@ -87,7 +97,25 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, } return r; } - *obj = &robj->gem_base; + robj->pid = task_pid_nr(current); + + gobj = kzalloc(sizeof(struct amdgpu_gem_object), GFP_KERNEL); + if (unlikely(!gobj)) { + amdgpu_bo_unref(&robj); + return -ENOMEM; + } + + r = drm_gem_object_init(adev->ddev, &gobj->base, amdgpu_bo_size(robj)); + if (unlikely(r)) { + kfree(gobj); + amdgpu_bo_unref(&robj); + return r; + } + + list_add(&gobj->list, &robj->gem_objects); + gobj->bo = amdgpu_bo_ref(robj); + *obj = &gobj->base; + return 0; } @@ -793,7 +821,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, struct drm_amdgpu_gem_create_in info; void __user *out = u64_to_user_ptr(args->value); - info.bo_size = robj->gem_base.size; + info.bo_size = amdgpu_bo_size(robj); info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; info.domains = robj->preferred_domains; info.domain_flags = robj->flags; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index d514840..1a22368 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -50,7 +50,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) if (bo->gem_base.import_attach) drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg); - drm_gem_object_release(&bo->gem_base); amdgpu_bo_unref(&bo->parent); if (!list_empty(&bo->shadow_list)) { mutex_lock(&adev->shadow_list_lock); @@ -368,6 +367,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, } INIT_LIST_HEAD(&bo->shadow_list); INIT_LIST_HEAD(&bo->va); + INIT_LIST_HEAD(&bo->gem_objects); bo->preferred_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_CPU | diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 36f2133..18d1932 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -72,10 +72,12 @@ struct amdgpu_bo { void *metadata; u32 metadata_size; unsigned prime_shared_count; + /* GEM objects refereing to this BO */ + struct list_head gem_objects; + /* list of all virtual address to which this bo is associated to */ struct list_head va; /* Constant after initialization */ - struct drm_gem_object gem_base; struct amdgpu_bo *parent; struct amdgpu_bo *shadow; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 5b3f928..2a76a57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -65,6 +65,7 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, struct reservation_object *resv = attach->dmabuf->resv; struct amdgpu_device *adev = dev->dev_private; struct amdgpu_bo *bo; + struct amdgpu_gem_object *gobj; int ret; ww_mutex_lock(&resv->lock, NULL); @@ -75,7 +76,24 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, return ERR_PTR(ret); bo->prime_shared_count = 1; - return &bo->gem_base; + + gobj = kzalloc(sizeof(struct amdgpu_gem_object), GFP_KERNEL); + if (unlikely(!gobj)) { + amdgpu_bo_unref(&bo); + return ERR_PTR(-ENOMEM); + } + + ret = drm_gem_object_init(adev->ddev, &gobj->base, amdgpu_bo_size(bo)); + if (unlikely(ret)) { + kfree(gobj); + amdgpu_bo_unref(&bo); + return ERR_PTR(ret); + } + + list_add(&gobj->list, &bo->gem_objects); + gobj->bo = amdgpu_bo_ref(bo); + + return &gobj->base; } int amdgpu_gem_prime_pin(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9eac161..a80d9cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -277,13 +277,26 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) { struct amdgpu_bo *abo = container_of(bo, struct amdgpu_bo, tbo); + struct drm_file *file_priv = filp->private_data; + struct amdgpu_gem_object *gobj; if (filp == NULL) return 0; if (amdgpu_ttm_tt_get_usermm(bo->ttm)) return -EPERM; - return drm_vma_node_verify_access(&abo->gem_base.vma_node, - filp->private_data); + + ww_mutex_lock(&abo->tbo.resv->lock, NULL); + list_for_each_entry(gobj, &abo->gem_objects, list) { + if (gobj->base.dev != file_priv->minor->dev) + continue; + + ww_mutex_unlock(&abo->tbo.resv->lock); + return drm_vma_node_verify_access(&gobj->base.vma_node, + filp->private_data); + } + ww_mutex_unlock(&abo->tbo.resv->lock); + + return -EPERM; } static void amdgpu_move_null(struct ttm_buffer_object *bo, -- 2.7.4