aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch237
1 files changed, 237 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch
new file mode 100644
index 00000000..52e36116
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/5032-drm-amdgpu-allocate-the-bo_list-array-after-the-list.patch
@@ -0,0 +1,237 @@
+From a001a34d8c17dcbd12ff418a7e79efe3879fb631 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Mon, 30 Jul 2018 16:16:01 +0200
+Subject: [PATCH 5032/5725] drm/amdgpu: allocate the bo_list array after the
+ list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This avoids multiple allocations for the head and the array.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 114 +++++++++++-----------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 17 +++--
+ 2 files changed, 57 insertions(+), 74 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+index 3f96f38..b603249 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+@@ -35,13 +35,15 @@
+ #define AMDGPU_BO_LIST_MAX_PRIORITY 32u
+ #define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1)
+
+-static int amdgpu_bo_list_set(struct amdgpu_device *adev,
+- struct drm_file *filp,
+- struct amdgpu_bo_list *list,
+- struct drm_amdgpu_bo_list_entry *info,
+- unsigned num_entries);
++static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
++{
++ struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
++ rhead);
++
++ kvfree(list);
++}
+
+-static void amdgpu_bo_list_release_rcu(struct kref *ref)
++static void amdgpu_bo_list_free(struct kref *ref)
+ {
+ struct amdgpu_bo_list *list = container_of(ref, struct amdgpu_bo_list,
+ refcount);
+@@ -50,67 +52,36 @@ static void amdgpu_bo_list_release_rcu(struct kref *ref)
+ amdgpu_bo_list_for_each_entry(e, list)
+ amdgpu_bo_unref(&e->robj);
+
+- kvfree(list->array);
+- kfree_rcu(list, rhead);
++ call_rcu(&list->rhead, amdgpu_bo_list_free_rcu);
+ }
+
+-int amdgpu_bo_list_create(struct amdgpu_device *adev,
+- struct drm_file *filp,
+- struct drm_amdgpu_bo_list_entry *info,
+- unsigned num_entries,
+- struct amdgpu_bo_list **list_out)
++int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,
++ struct drm_amdgpu_bo_list_entry *info,
++ unsigned num_entries, struct amdgpu_bo_list **result)
+ {
++ unsigned last_entry = 0, first_userptr = num_entries;
++ struct amdgpu_bo_list_entry *array;
+ struct amdgpu_bo_list *list;
++ uint64_t total_size = 0;
++ size_t size;
++ unsigned i;
+ int r;
+
++ if (num_entries > SIZE_MAX / sizeof(struct amdgpu_bo_list_entry))
++ return -EINVAL;
+
+- list = kzalloc(sizeof(struct amdgpu_bo_list), GFP_KERNEL);
++ size = sizeof(struct amdgpu_bo_list);
++ size += num_entries * sizeof(struct amdgpu_bo_list_entry);
++ list = kvmalloc(size, GFP_KERNEL);
+ if (!list)
+ return -ENOMEM;
+
+- /* initialize bo list*/
+ kref_init(&list->refcount);
+- r = amdgpu_bo_list_set(adev, filp, list, info, num_entries);
+- if (r) {
+- kfree(list);
+- return r;
+- }
+-
+- *list_out = list;
+- return 0;
+-}
+-
+-static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
+-{
+- struct amdgpu_bo_list *list;
+-
+- mutex_lock(&fpriv->bo_list_lock);
+- list = idr_remove(&fpriv->bo_list_handles, id);
+- mutex_unlock(&fpriv->bo_list_lock);
+- if (list)
+- kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
+-}
+-
+-static int amdgpu_bo_list_set(struct amdgpu_device *adev,
+- struct drm_file *filp,
+- struct amdgpu_bo_list *list,
+- struct drm_amdgpu_bo_list_entry *info,
+- unsigned num_entries)
+-{
+- struct amdgpu_bo_list_entry *array;
+- struct amdgpu_bo *gds_obj = adev->gds.gds_gfx_bo;
+- struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo;
+- struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo;
+-
+- unsigned last_entry = 0, first_userptr = num_entries;
+- struct amdgpu_bo_list_entry *e;
+- uint64_t total_size = 0;
+- unsigned i;
+- int r;
++ list->gds_obj = adev->gds.gds_gfx_bo;
++ list->gws_obj = adev->gds.gws_gfx_bo;
++ list->oa_obj = adev->gds.oa_gfx_bo;
+
+- array = kvmalloc_array(num_entries, sizeof(struct amdgpu_bo_list_entry), GFP_KERNEL);
+- if (!array)
+- return -ENOMEM;
++ array = amdgpu_bo_list_array_entry(list, 0);
+ memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry));
+
+ for (i = 0; i < num_entries; ++i) {
+@@ -147,36 +118,41 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
+ entry->tv.shared = !entry->robj->prime_shared_count;
+
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GDS)
+- gds_obj = entry->robj;
++ list->gds_obj = entry->robj;
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_GWS)
+- gws_obj = entry->robj;
++ list->gws_obj = entry->robj;
+ if (entry->robj->preferred_domains == AMDGPU_GEM_DOMAIN_OA)
+- oa_obj = entry->robj;
++ list->oa_obj = entry->robj;
+
+ total_size += amdgpu_bo_size(entry->robj);
+ trace_amdgpu_bo_list_set(list, entry->robj);
+ }
+
+- amdgpu_bo_list_for_each_entry(e, list)
+- amdgpu_bo_unref(&list->array[i].robj);
+-
+- kvfree(list->array);
+-
+- list->gds_obj = gds_obj;
+- list->gws_obj = gws_obj;
+- list->oa_obj = oa_obj;
+ list->first_userptr = first_userptr;
+- list->array = array;
+ list->num_entries = num_entries;
+
+ trace_amdgpu_cs_bo_status(list->num_entries, total_size);
++
++ *result = list;
+ return 0;
+
+ error_free:
+ while (i--)
+ amdgpu_bo_unref(&array[i].robj);
+- kvfree(array);
++ kvfree(list);
+ return r;
++
++}
++
++static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id)
++{
++ struct amdgpu_bo_list *list;
++
++ mutex_lock(&fpriv->bo_list_lock);
++ list = idr_remove(&fpriv->bo_list_handles, id);
++ mutex_unlock(&fpriv->bo_list_lock);
++ if (list)
++ kref_put(&list->refcount, amdgpu_bo_list_free);
+ }
+
+ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+@@ -229,7 +205,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
+
+ void amdgpu_bo_list_put(struct amdgpu_bo_list *list)
+ {
+- kref_put(&list->refcount, amdgpu_bo_list_release_rcu);
++ kref_put(&list->refcount, amdgpu_bo_list_free);
+ }
+
+ int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+index 3d77abf..61b0897 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+@@ -48,7 +48,6 @@ struct amdgpu_bo_list {
+ struct amdgpu_bo *oa_obj;
+ unsigned first_userptr;
+ unsigned num_entries;
+- struct amdgpu_bo_list_entry *array;
+ };
+
+ int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
+@@ -65,14 +64,22 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev,
+ unsigned num_entries,
+ struct amdgpu_bo_list **list);
+
++static inline struct amdgpu_bo_list_entry *
++amdgpu_bo_list_array_entry(struct amdgpu_bo_list *list, unsigned index)
++{
++ struct amdgpu_bo_list_entry *array = (void *)&list[1];
++
++ return &array[index];
++}
++
+ #define amdgpu_bo_list_for_each_entry(e, list) \
+- for (e = &(list)->array[0]; \
+- e != &(list)->array[(list)->num_entries]; \
++ for (e = amdgpu_bo_list_array_entry(list, 0); \
++ e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
+ ++e)
+
+ #define amdgpu_bo_list_for_each_userptr_entry(e, list) \
+- for (e = &(list)->array[(list)->first_userptr]; \
+- e != &(list)->array[(list)->num_entries]; \
++ for (e = amdgpu_bo_list_array_entry(list, (list)->first_userptr); \
++ e != amdgpu_bo_list_array_entry(list, (list)->num_entries); \
+ ++e)
+
+ #endif
+--
+2.7.4
+