From: Christian König <christian.koe...@amd.com>

This allows us to have multiple GEM objects for one BO.

Signed-off-by: Christian König <christian.koe...@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehl...@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 a019556..bd70baf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -96,7 +96,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object 
*tbo)
        amdgpu_bo_kunmap(bo);
        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);
@@ -345,13 +344,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 4d2a454..53cb7fb 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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to