[PATCH 4/6] drm/amdgpu: separate BO from GEM object
Felix Kuehling
Felix.Kuehling at amd.com
Wed Jul 12 05:29:25 UTC 2017
From: Christian König <christian.koenig at amd.com>
This allows us to have multiple GEM objects for one BO.
Signed-off-by: Christian König <christian.koenig at amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling at amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 12 +++++++--
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 41 +++++++++++++++++++++++-------
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 7 +----
drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 20 ++++++++++++++-
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 17 +++++++++++--
5 files changed, 77 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index f6345b9..9fa3cee 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -417,6 +417,12 @@ struct amdgpu_bo_va {
#define AMDGPU_GEM_DOMAIN_MAX 0x3
+struct amdgpu_gem_object {
+ struct drm_gem_object base;
+ struct list_head list;
+ struct amdgpu_bo *bo;
+};
+
struct amdgpu_bo {
/* Protected by tbo.reserved */
u32 prefered_domains;
@@ -433,12 +439,14 @@ 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;
@@ -447,7 +455,7 @@ struct amdgpu_bo {
struct list_head mn_list;
struct list_head shadow_list;
};
-#define gem_to_amdgpu_bo(gobj) container_of((gobj), struct amdgpu_bo, gem_base)
+#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 917ac5e..b625ee5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -33,14 +33,20 @@
void amdgpu_gem_object_free(struct drm_gem_object *gobj)
{
- struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
+ struct amdgpu_gem_object *aobj;
- if (robj) {
- if (robj->gem_base.import_attach)
- drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
- amdgpu_mn_unregister(robj);
- amdgpu_bo_unref(&robj);
- }
+ 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);
}
int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
@@ -49,6 +55,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;
int r;
*obj = NULL;
@@ -71,7 +78,23 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
}
return r;
}
- *obj = &robj->gem_base;
+
+ 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 = robj;
+ *obj = &gobj->base;
return 0;
}
@@ -691,7 +714,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
struct drm_amdgpu_gem_create_in info;
void __user *out = (void __user *)(uintptr_t)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->prefered_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 6e24339..776de77 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -95,7 +95,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
amdgpu_update_memory_usage(adev, &bo->tbo.mem, NULL);
- drm_gem_object_release(&bo->gem_base);
amdgpu_bo_unref(&bo->parent);
if (!list_empty(&bo->shadow_list)) {
mutex_lock(&adev->shadow_list_lock);
@@ -344,13 +343,9 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
bo = kzalloc(sizeof(struct amdgpu_bo), GFP_KERNEL);
if (bo == NULL)
return -ENOMEM;
- r = drm_gem_object_init(adev->ddev, &bo->gem_base, size);
- if (unlikely(r)) {
- kfree(bo);
- return r;
- }
INIT_LIST_HEAD(&bo->shadow_list);
INIT_LIST_HEAD(&bo->va);
+ INIT_LIST_HEAD(&bo->gem_objects);
bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_CPU |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 6bdc866..b9425ed 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -65,6 +65,7 @@ struct drm_gem_object *
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 @@ struct drm_gem_object *
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 7cda5dd..1d18570 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -256,11 +256,24 @@ 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 (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,
+ file_priv);
+ }
+ ww_mutex_unlock(&abo->tbo.resv->lock);
+
+ return -EPERM;
}
static void amdgpu_move_null(struct ttm_buffer_object *bo,
--
1.9.1
More information about the dri-devel
mailing list