aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1425-drm-amdgpu-Adjust-reserve_bo_and_vms.patch
blob: 2f21508b7fc65f1571cff4dd3fdc97275d62ab43 (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
From 543a9a487c2b5f4adc57b1a4965eb65fbe500b4a Mon Sep 17 00:00:00 2001
From: Yong Zhao <yong.zhao@amd.com>
Date: Thu, 28 Apr 2016 16:30:52 -0400
Subject: [PATCH 1425/4131] drm/amdgpu: Adjust reserve_bo_and_vms()

The support of an incoming vm in reserve_bo_and_vms() is moved to
reserve_bo_and_vm(), so reserve_bo_and_vms() is simplified and
renamed to reserve_bo_and_cond_vms(), which only supports a single
vm or all vms that are already associated with a BO.

This way when a BO is already unmapped due to eviction and a single vm
is passed to reserve_bo_and_cond_vms(), the function will not reserve
BOs at all, as no unmapping activity is needed at all.

Change-Id: I98b538d1a3f43cf42aec26b3b59c6e790278c10a
Signed-off-by: Yong Zhao <yong.zhao@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 144 ++++++++++++++++-------
 1 file changed, 102 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index dac2a30..df04747 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -428,18 +428,32 @@ struct bo_vm_reservation_context {
 	bool reserved;
 };
 
-static int reserve_bo_and_vms(struct kgd_mem *mem,
-			      struct amdgpu_vm *vm, bool is_mapped,
+/**
+ * reserve_bo_and_vm - reserve a BO and a VM unconditionally.
+ * @mem: KFD BO structure.
+ * @vm: the VM to reserve.
+ * @ctx: the struct that will be used in unreserve_bo_and_vms().
+ */
+static int reserve_bo_and_vm(struct kgd_mem *mem,
+			      struct amdgpu_vm *vm,
 			      struct bo_vm_reservation_context *ctx)
 {
 	struct amdgpu_bo *bo = mem->data2.bo;
-	struct kfd_bo_va_list *entry;
-	unsigned i;
 	int ret;
 
+	WARN_ON(!vm);
+
+	ctx->reserved = false;
+	ctx->n_vms = 1;
+
 	INIT_LIST_HEAD(&ctx->list);
 	INIT_LIST_HEAD(&ctx->duplicates);
 
+	ctx->vm_pd = kzalloc(sizeof(struct amdgpu_bo_list_entry)
+			      * ctx->n_vms, GFP_KERNEL);
+	if (ctx->vm_pd == NULL)
+		return -ENOMEM;
+
 	ctx->kfd_bo.robj = bo;
 	ctx->kfd_bo.priority = 0;
 	ctx->kfd_bo.tv.bo = &bo->tbo;
@@ -447,43 +461,91 @@ static int reserve_bo_and_vms(struct kgd_mem *mem,
 	ctx->kfd_bo.user_pages = NULL;
 	list_add(&ctx->kfd_bo.tv.head, &ctx->list);
 
-	ctx->reserved = false;
+	amdgpu_vm_get_pd_bo(vm, &ctx->list, &ctx->vm_pd[0]);
+	amdgpu_vm_get_pt_bos(bo->adev, vm, &ctx->duplicates);
+
+	ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
+				     false, &ctx->duplicates);
+	if (!ret)
+		ctx->reserved = true;
+	else
+		pr_err("amdkfd: Failed to reserve buffers in ttm\n");
 
+	if (ret) {
+		kfree(ctx->vm_pd);
+		ctx->vm_pd = NULL;
+	}
+
+	return ret;
+}
+
+enum VA_TYPE {
+	VA_NOT_MAPPED = 0,
+	VA_MAPPED,
+	VA_DO_NOT_CARE,
+};
+
+/**
+ * reserve_bo_and_vm - reserve a BO and some VMs that the BO has been added
+ * to, conditionally based on map_type.
+ * @mem: KFD BO structure.
+ * @vm: the VM to reserve. If NULL, then all VMs associated with the BO
+ * is used. Otherwise, a single VM associated with the BO.
+ * @map_type: the mapping status that will be used to filter the VMs.
+ * @ctx: the struct that will be used in unreserve_bo_and_vms().
+ */
+static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
+			      struct amdgpu_vm *vm, enum VA_TYPE map_type,
+			      struct bo_vm_reservation_context *ctx)
+{
+	struct amdgpu_bo *bo = mem->data2.bo;
+	struct kfd_bo_va_list *entry;
+	unsigned i;
+	int ret;
+
+	ctx->reserved = false;
 	ctx->n_vms = 0;
+	ctx->vm_pd = NULL;
 
-	if (vm)
-		ctx->n_vms = 1;
-	else {
-		list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
-			if (entry->is_mapped == is_mapped)
-				ctx->n_vms++;
-		}
+	INIT_LIST_HEAD(&ctx->list);
+	INIT_LIST_HEAD(&ctx->duplicates);
+
+	list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
+		if ((vm && vm != entry->bo_va->vm) ||
+			(entry->is_mapped != map_type
+			&& map_type != VA_DO_NOT_CARE))
+			continue;
+
+		ctx->n_vms++;
 	}
 
 	if (ctx->n_vms == 0)
-		ctx->vm_pd = NULL;
-	else {
-		ctx->vm_pd = kzalloc(sizeof(struct amdgpu_bo_list_entry)
-				      * ctx->n_vms, GFP_KERNEL);
-		if (ctx->vm_pd == NULL)
-			return -ENOMEM;
-	}
+		return 0;
 
-	if (vm) {
-		amdgpu_vm_get_pd_bo(vm, &ctx->list, &ctx->vm_pd[0]);
-		amdgpu_vm_get_pt_bos(vm, &ctx->duplicates);
-	} else {
-		i = 0;
-		list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
-			if (entry->is_mapped != is_mapped)
-				continue;
+	ctx->vm_pd = kzalloc(sizeof(struct amdgpu_bo_list_entry)
+			      * ctx->n_vms, GFP_KERNEL);
+	if (ctx->vm_pd == NULL)
+		return -ENOMEM;
 
-			amdgpu_vm_get_pd_bo(entry->bo_va->vm, &ctx->list,
-					&ctx->vm_pd[i]);
-			amdgpu_vm_get_pt_bos(entry->bo_va->vm,
-					&ctx->duplicates);
-			i++;
-		}
+	ctx->kfd_bo.robj = bo;
+	ctx->kfd_bo.priority = 0;
+	ctx->kfd_bo.tv.bo = &bo->tbo;
+	ctx->kfd_bo.tv.shared = true;
+	ctx->kfd_bo.user_pages = NULL;
+	list_add(&ctx->kfd_bo.tv.head, &ctx->list);
+
+	i = 0;
+	list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
+		if ((vm && vm != entry->bo_va->vm) ||
+			(entry->is_mapped != map_type
+			&& map_type != VA_DO_NOT_CARE))
+			continue;
+
+		amdgpu_vm_get_pd_bo(entry->bo_va->vm, &ctx->list,
+				&ctx->vm_pd[i]);
+		amdgpu_vm_get_pt_bos(bo->adev, entry->bo_va->vm,
+				&ctx->duplicates);
+		i++;
 	}
 
 	ret = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->list,
@@ -785,7 +847,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
 	if (mem->data2.work.work.func)
 		cancel_delayed_work_sync(&mem->data2.work);
 
-	ret = reserve_bo_and_vms(mem, NULL, false, &ctx);
+	ret = reserve_bo_and_cond_vms(mem, NULL, VA_DO_NOT_CARE, &ctx);
 	if (unlikely(ret != 0))
 		return ret;
 
@@ -844,7 +906,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
 	pr_debug("amdgpu: try to map VA 0x%llx domain %d\n",
 			mem->data2.va, domain);
 
-	ret = reserve_bo_and_vms(mem, vm, false, &ctx);
+	ret = reserve_bo_and_vm(mem, vm, &ctx);
 	if (unlikely(ret != 0))
 		goto bo_reserve_failed;
 
@@ -870,7 +932,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
 	}
 
 	list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
-		if (entry->bo_va->vm == vm && entry->is_mapped == false) {
+		if (entry->bo_va->vm == vm && !entry->is_mapped) {
 			if (mem->data2.evicted) {
 				/* If the BO is evicted, just mark the
 				 * mapping as mapped and stop the GPU's
@@ -1072,14 +1134,12 @@ int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
 	}
 	mapped_before = mem->data2.mapped_to_gpu_memory;
 
-	ret = reserve_bo_and_vms(mem, vm, true, &ctx);
+	ret = reserve_bo_and_cond_vms(mem, vm, VA_MAPPED, &ctx);
 	if (unlikely(ret != 0))
 		goto out;
 
 	list_for_each_entry(entry, &mem->data2.bo_va_list, bo_list) {
-		if (entry->kgd_dev == kgd &&
-				entry->bo_va->vm == vm &&
-				entry->is_mapped) {
+		if (entry->bo_va->vm == vm && entry->is_mapped) {
 			if (mem->data2.evicted) {
 				/* If the BO is evicted, just mark the
 				 * mapping as unmapped and allow the
@@ -1409,7 +1469,7 @@ int amdgpu_amdkfd_gpuvm_evict_mem(struct kgd_mem *mem, struct mm_struct *mm)
 	 * goes wrong. */
 	n_evicted = 0;
 
-	r = reserve_bo_and_vms(mem, NULL, true, &ctx);
+	r = reserve_bo_and_cond_vms(mem, NULL, VA_MAPPED, &ctx);
 	if (unlikely(r != 0))
 		return r;
 
@@ -1483,7 +1543,7 @@ int amdgpu_amdkfd_gpuvm_restore_mem(struct kgd_mem *mem, struct mm_struct *mm)
 
 	domain = mem->data2.domain;
 
-	ret = reserve_bo_and_vms(mem, NULL, true, &ctx);
+	ret = reserve_bo_and_cond_vms(mem, NULL, VA_MAPPED, &ctx);
 	if (likely(ret == 0)) {
 		ret = update_user_pages(mem, mm, &ctx);
 		have_pages = !ret;
-- 
2.7.4