diff options
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.patch | 175 |
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 + |