aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch175
1 files changed, 175 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch
new file mode 100644
index 00000000..c4775782
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/1521-drm-amdgpu-Impose-KFD-memory-usage-limits.patch
@@ -0,0 +1,175 @@
+From 681b5e4b64faf63d9913b6b7e9a6d93619a112f1 Mon Sep 17 00:00:00 2001
+From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+Date: Tue, 26 Jul 2016 18:59:10 -0400
+Subject: [PATCH 1521/4131] drm/amdgpu: Impose KFD memory usage limits
+
+Change-Id: Ic51260e6b8a7513dfa9a60ddd5c459f6b19da05a
+Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
+
+ Conflicts:
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 99 ++++++++++++++++++++++++
+ 3 files changed, 102 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+index 0bf1fb3..f18cbfa 100755
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -59,7 +59,7 @@ int amdgpu_amdkfd_init(void)
+ #else
+ ret = -ENOENT;
+ #endif
+-
++ amdgpu_amdkfd_gpuvm_init_mem_limits();
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+index a291577..2db28e5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+@@ -205,5 +205,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct kgd_dev *kgd, int dma_buf_fd,
+ int amdgpu_amdkfd_gpuvm_evict_mem(struct kgd_mem *mem, struct mm_struct *mm);
+ int amdgpu_amdkfd_gpuvm_restore_mem(struct kgd_mem *mem, struct mm_struct *mm);
+
++void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
++
+ #endif /* AMDGPU_AMDKFD_H_INCLUDED */
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 2abce72..eed9aca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -43,6 +43,18 @@
+ * a HW bug. */
+ #define VI_BO_SIZE_ALIGN (0x8000)
+
++/* Impose limit on how much memory KFD can use */
++struct kfd_mem_usage_limit {
++ uint64_t max_system_mem_limit;
++ uint64_t max_userptr_mem_limit;
++ int64_t system_mem_used;
++ int64_t userptr_mem_used;
++ spinlock_t mem_limit_lock;
++};
++
++static struct kfd_mem_usage_limit kfd_mem_limit;
++
++
+ static inline struct amdgpu_device *get_amdgpu_device(struct kgd_dev *kgd)
+ {
+ return (struct amdgpu_device *)kgd;
+@@ -66,6 +78,85 @@ static bool check_if_add_bo_to_vm(struct amdgpu_vm *avm,
+ return true;
+ }
+
++/* Set memory usage limits. Current, limits are
++ * System (kernel) memory - 1/4th System RAM
++ * Userptr memory - 3/4th System RAM
++ */
++void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
++{
++ struct sysinfo si;
++ uint64_t mem;
++
++ si_meminfo(&si);
++ mem = si.totalram - si.totalhigh;
++ mem *= si.mem_unit;
++
++ spin_lock_init(&kfd_mem_limit.mem_limit_lock);
++ kfd_mem_limit.max_system_mem_limit = (mem >> 2) - (mem >> 4);
++ kfd_mem_limit.max_userptr_mem_limit = mem - (mem >> 4);
++ pr_debug("Kernel memory limit %lluM, userptr limit %lluM\n",
++ (kfd_mem_limit.max_system_mem_limit >> 20),
++ (kfd_mem_limit.max_userptr_mem_limit >> 20));
++}
++
++static int check_and_reserve_system_mem_limit(struct amdgpu_device *adev,
++ uint64_t size, u32 domain)
++{
++ size_t acc_size;
++ int ret = 0;
++
++ acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size,
++ sizeof(struct amdgpu_bo));
++
++ spin_lock(&kfd_mem_limit.mem_limit_lock);
++ if (domain == AMDGPU_GEM_DOMAIN_GTT) {
++ if (kfd_mem_limit.system_mem_used + (acc_size + size) >
++ kfd_mem_limit.max_system_mem_limit) {
++ ret = -ENOMEM;
++ goto err_no_mem;
++ }
++ kfd_mem_limit.system_mem_used += (acc_size + size);
++
++ } else if (domain == AMDGPU_GEM_DOMAIN_CPU) {
++ if ((kfd_mem_limit.system_mem_used + acc_size >
++ kfd_mem_limit.max_system_mem_limit) &&
++ (kfd_mem_limit.userptr_mem_used + (size + acc_size) >
++ kfd_mem_limit.max_userptr_mem_limit)) {
++ ret = -ENOMEM;
++ goto err_no_mem;
++ }
++ kfd_mem_limit.system_mem_used += acc_size;
++ kfd_mem_limit.userptr_mem_used += size;
++ }
++
++err_no_mem:
++ spin_unlock(&kfd_mem_limit.mem_limit_lock);
++ return ret;
++}
++
++static void unreserve_system_memory_limit(struct amdgpu_bo *bo)
++{
++ spin_lock(&kfd_mem_limit.mem_limit_lock);
++
++ if (bo->prefered_domains == AMDGPU_GEM_DOMAIN_GTT)
++ kfd_mem_limit.system_mem_used -=
++ (bo->tbo.acc_size + amdgpu_bo_size(bo));
++ else if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
++ kfd_mem_limit.system_mem_used -= bo->tbo.acc_size;
++ kfd_mem_limit.userptr_mem_used -= amdgpu_bo_size(bo);
++ }
++ if (kfd_mem_limit.system_mem_used < 0) {
++ pr_warn("kfd system memory size ref. error\n");
++ kfd_mem_limit.system_mem_used = 0;
++ }
++ if (kfd_mem_limit.userptr_mem_used < 0) {
++ pr_warn("kfd userptr memory size ref. error\n");
++ kfd_mem_limit.userptr_mem_used = 0;
++ }
++
++ spin_unlock(&kfd_mem_limit.mem_limit_lock);
++}
++
+ static int add_bo_to_vm(struct amdgpu_device *adev, struct kgd_mem *mem,
+ struct amdgpu_vm *avm, bool is_aql,
+ struct kfd_bo_va_list **p_bo_va_entry)
+@@ -359,6 +450,13 @@ static int __alloc_memory_of_gpu(struct kgd_dev *kgd, uint64_t va,
+ pr_debug("amdkfd: allocating BO on domain %d with size %llu\n",
+ alloc_domain, size);
+
++ ret = check_and_reserve_system_mem_limit(adev, size, alloc_domain);
++ if (ret) {
++ pr_err("amdkfd: Insufficient system memory\n");
++ goto err_bo_create;
++ }
++
++
+ /* Allocate buffer object. Userptr objects need to start out
+ * in the CPU domain, get moved to GTT when pinned. */
+ ret = amdgpu_bo_create(adev, size, byte_align, false,
+@@ -944,6 +1042,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
+ }
+
+ /* Free the BO*/
++ unreserve_system_memory_limit(mem->data2.bo);
+ bo_list_entry = &mem->data2.bo_list_entry;
+ mutex_lock(&master_vm->lock);
+ list_del(&bo_list_entry->tv.head);
+--
+2.7.4
+