From 91d7956c48b020a6e4858394a9844306a5261be6 Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Mon, 27 Jun 2016 12:20:18 -0400 Subject: [PATCH 1510/4131] drm/amdgpu: Introduce amdkfd_vm structure For KFD process use amdkfd_vm instead of amdgpu_vm but keep pointer compatability between these two structures. struct amdkfd_vm will aid KGD in keeping track of all KFD BOs and VMs belonging to a KFD process. This is useful for KFD memory eviction and restore since KFD eviction / restore is done per process. Change-Id: I83383a183c7f0c6b95d46c72b37dbaaaaa1e93f8 Signed-off-by: Harish Kasiviswanathan --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 29 ++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 18 ++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 70b8652..b66b03a 100755 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -29,6 +29,7 @@ #include #include #include +#include "amdgpu.h" extern const struct kgd2kfd_calls *kgd2kfd; @@ -70,6 +71,34 @@ struct kgd_mem { }; +/* struct amdkfd_vm - + * For Memory Eviction KGD requires a mechanism to keep track of all KFD BOs + * belonging to a KFD process. All the VMs belonging to the same process point + * to the same master VM. The master VM points to itself. + * For master VM kfd_bo_list will contain the list of all KFD BOs and it will + * be empty for all the other VMs. The master VM is decided by KFD and it will + * pass it on KGD via create_process_vm interface + */ +struct amdkfd_vm { + /* Keep base as the first parameter for pointer compatibility between + * amdkfd_vm and amdgpu_vm. + */ + struct amdgpu_vm base; + /* Points to master VM of the KFD process */ + struct amdkfd_vm *master; + /* List Head for all KFD BOs that belong to a KFD process. Non-empty + * only for Master VM. + */ + struct list_head kfd_bo_list; + /* Lock to protect kfd_bo_list */ + struct mutex lock; + /* List of VMs that belong to a KFD process */ + struct list_head kfd_vm_list; + /* Number of VMs including master VM */ + unsigned n_vms; + struct amdgpu_device *adev; +}; + int amdgpu_amdkfd_init(void); void amdgpu_amdkfd_fini(void); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index fefdfe2..123adfb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -27,7 +27,6 @@ #include #include #include -#include "amdgpu.h" #include "amdgpu_amdkfd.h" #include "amdgpu_ucode.h" #include "gca/gfx_8_0_sh_mask.h" @@ -1038,14 +1037,14 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm) { int ret; - struct amdgpu_vm *new_vm; + struct amdkfd_vm *new_vm; struct amdgpu_bo *pd; struct amdgpu_device *adev = get_amdgpu_device(kgd); BUG_ON(kgd == NULL); BUG_ON(vm == NULL); - new_vm = kzalloc(sizeof(struct amdgpu_vm), GFP_KERNEL); + new_vm = kzalloc(sizeof(struct amdkfd_vm), GFP_KERNEL); if (new_vm == NULL) return -ENOMEM; @@ -1054,11 +1053,14 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm) if (ret != 0) { pr_err("amdgpu: failed init vm ret %d\n", ret); /* Undo everything related to the new VM context */ - amdgpu_vm_fini(adev, new_vm); + amdgpu_vm_fini(adev, &new_vm->base); kfree(new_vm); new_vm = NULL; } - + new_vm->adev = adev; + mutex_init(&new_vm->lock); + INIT_LIST_HEAD(&new_vm->kfd_bo_list); + INIT_LIST_HEAD(&new_vm->kfd_vm_list); *vm = (void *) new_vm; /* @@ -1066,12 +1068,12 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm) * removed from PT. This function is called here because it requires * the radeon_vm::mutex to be locked and PT to be reserved */ - ret = amdgpu_vm_clear_freed(adev, new_vm); + ret = amdgpu_vm_clear_freed(adev, &new_vm->base); if (ret != 0) pr_err("amdgpu: Failed to amdgpu_vm_clear_freed\n"); /* Pin the PD directory */ - pd = new_vm->page_directory; + pd = new_vm->base.page_directory; amdgpu_bo_reserve(pd, true); ret = try_pin_bo(pd, AMDGPU_GEM_DOMAIN_VRAM); amdgpu_bo_unreserve(pd); @@ -1079,7 +1081,7 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm) pr_err("amdkfd: Failed to pin PD\n"); pr_debug("amdgpu: created process vm with address 0x%llx\n", - amdgpu_bo_gpu_offset(new_vm->page_directory)); + amdgpu_bo_gpu_offset(new_vm->base.page_directory)); return ret; } -- 2.7.4