aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch231
1 files changed, 231 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch
new file mode 100644
index 00000000..f7097d07
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0823-drm-amdgpu-separate-BO-from-GEM-object.patch
@@ -0,0 +1,231 @@
+From e8c49e4545565a5fbcfca34425d86de16280316c Mon Sep 17 00:00:00 2001
+From: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com>
+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 <christian.koenig@amd.com>
+Signed-off-by: Kalyan Alle <kalyan.alle@amd.com>
+
+Signed-off-by: Chaudhary Amit Kumar <chaudharyamit.kumar@amd.com>
+---
+ 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
+