aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1510-drm-amdgpu-Introduce-amdkfd_vm-structure.patch
blob: 3f5351fb9c6a003893d2a1a36e7e4e0392caf10f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
From 91d7956c48b020a6e4858394a9844306a5261be6 Mon Sep 17 00:00:00 2001
From: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
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 <Harish.Kasiviswanathan@amd.com>
---
 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 <linux/mm.h>
 #include <linux/workqueue.h>
 #include <kgd_kfd_interface.h>
+#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 <linux/list.h>
 #include <drm/drmP.h>
 #include <linux/dma-buf.h>
-#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