xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c (revision b133207deb72609ad4da40c4d50128a5e150677b)
1 /*
2  * Copyright 2017 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 #include "amdgpu_ids.h"
24 
25 #include <linux/idr.h>
26 #include <linux/dma-fence-array.h>
27 
28 
29 #include "amdgpu.h"
30 #include "amdgpu_trace.h"
31 
32 /*
33  * PASID manager
34  *
35  * PASIDs are global address space identifiers that can be shared
36  * between the GPU, an IOMMU and the driver. VMs on different devices
37  * may use the same PASID if they share the same address
38  * space. Therefore PASIDs are allocated using IDR cyclic allocator
39  * (similar to kernel PID allocation) which naturally delays reuse.
40  * VMs are looked up from the PASID per amdgpu_device.
41  */
42 
43 static DEFINE_IDR(amdgpu_pasid_idr);
44 static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock);
45 
46 /* Helper to free pasid from a fence callback */
47 struct amdgpu_pasid_cb {
48 	struct dma_fence_cb cb;
49 	u32 pasid;
50 };
51 
52 /**
53  * amdgpu_pasid_alloc - Allocate a PASID
54  * @bits: Maximum width of the PASID in bits, must be at least 1
55  *
56  * Uses kernel's IDR cyclic allocator (same as PID allocation).
57  * Allocates sequentially with automatic wrap-around.
58  *
59  * Returns a positive integer on success. Returns %-EINVAL if bits==0.
60  * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
61  * memory allocation failure.
62  */
63 int amdgpu_pasid_alloc(unsigned int bits)
64 {
65 	int pasid;
66 
67 	if (bits == 0)
68 		return -EINVAL;
69 
70 	spin_lock(&amdgpu_pasid_idr_lock);
71 	pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
72 				 1U << bits, GFP_KERNEL);
73 	spin_unlock(&amdgpu_pasid_idr_lock);
74 
75 	if (pasid >= 0)
76 		trace_amdgpu_pasid_allocated(pasid);
77 
78 	return pasid;
79 }
80 
81 /**
82  * amdgpu_pasid_free - Free a PASID
83  * @pasid: PASID to free
84  */
85 void amdgpu_pasid_free(u32 pasid)
86 {
87 	trace_amdgpu_pasid_freed(pasid);
88 
89 	spin_lock(&amdgpu_pasid_idr_lock);
90 	idr_remove(&amdgpu_pasid_idr, pasid);
91 	spin_unlock(&amdgpu_pasid_idr_lock);
92 }
93 
94 static void amdgpu_pasid_free_cb(struct dma_fence *fence,
95 				 struct dma_fence_cb *_cb)
96 {
97 	struct amdgpu_pasid_cb *cb =
98 		container_of(_cb, struct amdgpu_pasid_cb, cb);
99 
100 	amdgpu_pasid_free(cb->pasid);
101 	dma_fence_put(fence);
102 	kfree(cb);
103 }
104 
105 /**
106  * amdgpu_pasid_free_delayed - free pasid when fences signal
107  *
108  * @resv: reservation object with the fences to wait for
109  * @pasid: pasid to free
110  *
111  * Free the pasid only after all the fences in resv are signaled.
112  */
113 void amdgpu_pasid_free_delayed(struct dma_resv *resv,
114 			       u32 pasid)
115 {
116 	struct amdgpu_pasid_cb *cb;
117 	struct dma_fence *fence;
118 	int r;
119 
120 	r = dma_resv_get_singleton(resv, DMA_RESV_USAGE_BOOKKEEP, &fence);
121 	if (r)
122 		goto fallback;
123 
124 	if (!fence) {
125 		amdgpu_pasid_free(pasid);
126 		return;
127 	}
128 
129 	cb = kmalloc_obj(*cb);
130 	if (!cb) {
131 		/* Last resort when we are OOM */
132 		dma_fence_wait(fence, false);
133 		dma_fence_put(fence);
134 		amdgpu_pasid_free(pasid);
135 	} else {
136 		cb->pasid = pasid;
137 		if (dma_fence_add_callback(fence, &cb->cb,
138 					   amdgpu_pasid_free_cb))
139 			amdgpu_pasid_free_cb(fence, &cb->cb);
140 	}
141 
142 	return;
143 
144 fallback:
145 	/* Not enough memory for the delayed delete, as last resort
146 	 * block for all the fences to complete.
147 	 */
148 	dma_resv_wait_timeout(resv, DMA_RESV_USAGE_BOOKKEEP,
149 			      false, MAX_SCHEDULE_TIMEOUT);
150 	amdgpu_pasid_free(pasid);
151 }
152 
153 /*
154  * VMID manager
155  *
156  * VMIDs are a per VMHUB identifier for page tables handling.
157  */
158 
159 /**
160  * amdgpu_vmid_had_gpu_reset - check if reset occured since last use
161  *
162  * @adev: amdgpu_device pointer
163  * @id: VMID structure
164  *
165  * Check if GPU reset occured since last use of the VMID.
166  */
167 bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
168 			       struct amdgpu_vmid *id)
169 {
170 	return id->current_gpu_reset_count !=
171 		atomic_read(&adev->gpu_reset_counter);
172 }
173 
174 /* Check if we need to switch to another set of resources */
175 static bool amdgpu_vmid_gds_switch_needed(struct amdgpu_vmid *id,
176 					  struct amdgpu_job *job)
177 {
178 	return id->gds_base != job->gds_base ||
179 		id->gds_size != job->gds_size ||
180 		id->gws_base != job->gws_base ||
181 		id->gws_size != job->gws_size ||
182 		id->oa_base != job->oa_base ||
183 		id->oa_size != job->oa_size;
184 }
185 
186 /* Check if the id is compatible with the job */
187 static bool amdgpu_vmid_compatible(struct amdgpu_vmid *id,
188 				   struct amdgpu_job *job)
189 {
190 	return  id->pd_gpu_addr == job->vm_pd_addr &&
191 		!amdgpu_vmid_gds_switch_needed(id, job);
192 }
193 
194 /**
195  * amdgpu_vmid_grab_idle - grab idle VMID
196  *
197  * @ring: ring we want to submit job to
198  * @idle: resulting idle VMID
199  * @fence: fence to wait for if no id could be grabbed
200  *
201  * Try to find an idle VMID, if none is idle add a fence to wait to the sync
202  * object. Returns -ENOMEM when we are out of memory.
203  */
204 static int amdgpu_vmid_grab_idle(struct amdgpu_ring *ring,
205 				 struct amdgpu_vmid **idle,
206 				 struct dma_fence **fence)
207 {
208 	struct amdgpu_device *adev = ring->adev;
209 	unsigned vmhub = ring->vm_hub;
210 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
211 
212 	/* If anybody is waiting for a VMID let everybody wait for fairness */
213 	if (!dma_fence_is_signaled(ring->vmid_wait)) {
214 		*fence = dma_fence_get(ring->vmid_wait);
215 		return 0;
216 	}
217 
218 	/* Check if we have an idle VMID */
219 	list_for_each_entry_reverse((*idle), &id_mgr->ids_lru, list) {
220 		/* Don't use per engine and per process VMID at the same time */
221 		struct amdgpu_ring *r = adev->vm_manager.concurrent_flush ?
222 			NULL : ring;
223 
224 		*fence = amdgpu_sync_peek_fence(&(*idle)->active, r);
225 		if (!(*fence))
226 			return 0;
227 	}
228 
229 	/*
230 	 * If we can't find a idle VMID to use, wait on a fence from the least
231 	 * recently used in the hope that it will be available soon.
232 	 */
233 	*idle = NULL;
234 	dma_fence_put(ring->vmid_wait);
235 	ring->vmid_wait = dma_fence_get(*fence);
236 
237 	/* This is the reference we return */
238 	dma_fence_get(*fence);
239 	return 0;
240 }
241 
242 /**
243  * amdgpu_vmid_grab_reserved - try to assign reserved VMID
244  *
245  * @vm: vm to allocate id for
246  * @ring: ring we want to submit job to
247  * @job: job who wants to use the VMID
248  * @id: resulting VMID
249  * @fence: fence to wait for if no id could be grabbed
250  *
251  * Try to assign a reserved VMID.
252  */
253 static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
254 				     struct amdgpu_ring *ring,
255 				     struct amdgpu_job *job,
256 				     struct amdgpu_vmid **id,
257 				     struct dma_fence **fence)
258 {
259 	struct amdgpu_device *adev = ring->adev;
260 	unsigned vmhub = ring->vm_hub;
261 	uint64_t fence_context = adev->fence_context + ring->idx;
262 	bool needs_flush = vm->use_cpu_for_update;
263 	uint64_t updates = amdgpu_vm_tlb_seq(vm);
264 	int r;
265 
266 	*id = vm->reserved_vmid[vmhub];
267 	if ((*id)->owner != vm->immediate.fence_context ||
268 	    !amdgpu_vmid_compatible(*id, job) ||
269 	    (*id)->flushed_updates < updates ||
270 	    !(*id)->last_flush ||
271 	    ((*id)->last_flush->context != fence_context &&
272 	     !dma_fence_is_signaled((*id)->last_flush)))
273 		needs_flush = true;
274 
275 	if ((*id)->owner != vm->immediate.fence_context ||
276 	    (!adev->vm_manager.concurrent_flush && needs_flush)) {
277 		struct dma_fence *tmp;
278 
279 		/* Don't use per engine and per process VMID at the
280 		 * same time
281 		 */
282 		if (adev->vm_manager.concurrent_flush)
283 			ring = NULL;
284 
285 		/* to prevent one context starved by another context */
286 		(*id)->pd_gpu_addr = 0;
287 		tmp = amdgpu_sync_peek_fence(&(*id)->active, ring);
288 		if (tmp) {
289 			*id = NULL;
290 			*fence = dma_fence_get(tmp);
291 			return 0;
292 		}
293 	}
294 
295 	/* Good we can use this VMID. Remember this submission as
296 	* user of the VMID.
297 	*/
298 	r = amdgpu_sync_fence(&(*id)->active, &job->base.s_fence->finished,
299 			      GFP_ATOMIC);
300 	if (r)
301 		return r;
302 
303 	job->vm_needs_flush = needs_flush;
304 	job->spm_update_needed = true;
305 	return 0;
306 }
307 
308 /**
309  * amdgpu_vmid_grab_used - try to reuse a VMID
310  *
311  * @vm: vm to allocate id for
312  * @ring: ring we want to submit job to
313  * @job: job who wants to use the VMID
314  * @id: resulting VMID
315  *
316  * Try to reuse a VMID for this submission.
317  */
318 static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
319 				 struct amdgpu_ring *ring,
320 				 struct amdgpu_job *job,
321 				 struct amdgpu_vmid **id)
322 {
323 	struct amdgpu_device *adev = ring->adev;
324 	unsigned vmhub = ring->vm_hub;
325 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
326 	uint64_t fence_context = adev->fence_context + ring->idx;
327 	uint64_t updates = amdgpu_vm_tlb_seq(vm);
328 	int r;
329 
330 	job->vm_needs_flush = vm->use_cpu_for_update;
331 
332 	/* Check if we can use a VMID already assigned to this VM */
333 	list_for_each_entry_reverse((*id), &id_mgr->ids_lru, list) {
334 		bool needs_flush = vm->use_cpu_for_update;
335 
336 		/* Check all the prerequisites to using this VMID */
337 		if ((*id)->owner != vm->immediate.fence_context)
338 			continue;
339 
340 		if (!amdgpu_vmid_compatible(*id, job))
341 			continue;
342 
343 		if (!(*id)->last_flush ||
344 		    ((*id)->last_flush->context != fence_context &&
345 		     !dma_fence_is_signaled((*id)->last_flush)))
346 			needs_flush = true;
347 
348 		if ((*id)->flushed_updates < updates)
349 			needs_flush = true;
350 
351 		if (needs_flush && !adev->vm_manager.concurrent_flush)
352 			continue;
353 
354 		/* Good, we can use this VMID. Remember this submission as
355 		 * user of the VMID.
356 		 */
357 		r = amdgpu_sync_fence(&(*id)->active,
358 				      &job->base.s_fence->finished,
359 				      GFP_ATOMIC);
360 		if (r)
361 			return r;
362 
363 		job->vm_needs_flush |= needs_flush;
364 		return 0;
365 	}
366 
367 	*id = NULL;
368 	return 0;
369 }
370 
371 /**
372  * amdgpu_vmid_grab - allocate the next free VMID
373  *
374  * @vm: vm to allocate id for
375  * @ring: ring we want to submit job to
376  * @job: job who wants to use the VMID
377  * @fence: fence to wait for if no id could be grabbed
378  *
379  * Allocate an id for the vm, adding fences to the sync obj as necessary.
380  */
381 int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
382 		     struct amdgpu_job *job, struct dma_fence **fence)
383 {
384 	struct amdgpu_device *adev = ring->adev;
385 	unsigned vmhub = ring->vm_hub;
386 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
387 	struct amdgpu_vmid *idle = NULL;
388 	struct amdgpu_vmid *id = NULL;
389 	int r = 0;
390 
391 	mutex_lock(&id_mgr->lock);
392 	r = amdgpu_vmid_grab_idle(ring, &idle, fence);
393 	if (r || !idle)
394 		goto error;
395 
396 	if (amdgpu_vmid_uses_reserved(vm, vmhub)) {
397 		r = amdgpu_vmid_grab_reserved(vm, ring, job, &id, fence);
398 		if (r || !id)
399 			goto error;
400 	} else {
401 		r = amdgpu_vmid_grab_used(vm, ring, job, &id);
402 		if (r)
403 			goto error;
404 
405 		if (!id) {
406 			/* Still no ID to use? Then use the idle one found earlier */
407 			id = idle;
408 
409 			/* Remember this submission as user of the VMID */
410 			r = amdgpu_sync_fence(&id->active,
411 					      &job->base.s_fence->finished,
412 					      GFP_ATOMIC);
413 			if (r)
414 				goto error;
415 
416 			job->vm_needs_flush = true;
417 		}
418 
419 		list_move_tail(&id->list, &id_mgr->ids_lru);
420 	}
421 
422 	job->gds_switch_needed = amdgpu_vmid_gds_switch_needed(id, job);
423 	if (job->vm_needs_flush) {
424 		id->flushed_updates = amdgpu_vm_tlb_seq(vm);
425 		dma_fence_put(id->last_flush);
426 		id->last_flush = NULL;
427 	}
428 	job->vmid = id - id_mgr->ids;
429 	job->pasid = vm->pasid;
430 
431 	id->gds_base = job->gds_base;
432 	id->gds_size = job->gds_size;
433 	id->gws_base = job->gws_base;
434 	id->gws_size = job->gws_size;
435 	id->oa_base = job->oa_base;
436 	id->oa_size = job->oa_size;
437 	id->pd_gpu_addr = job->vm_pd_addr;
438 	id->owner = vm->immediate.fence_context;
439 
440 	trace_amdgpu_vm_grab_id(vm, ring, job);
441 
442 error:
443 	mutex_unlock(&id_mgr->lock);
444 	return r;
445 }
446 
447 /*
448  * amdgpu_vmid_uses_reserved - check if a VM will use a reserved VMID
449  * @vm: the VM to check
450  * @vmhub: the VMHUB which will be used
451  *
452  * Returns: True if the VM will use a reserved VMID.
453  */
454 bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub)
455 {
456 	return vm->reserved_vmid[vmhub];
457 }
458 
459 /*
460  * amdgpu_vmid_alloc_reserved - reserve a specific VMID for this vm
461  * @adev: amdgpu device structure
462  * @vm: the VM to reserve an ID for
463  * @vmhub: the VMHUB which should be used
464  *
465  * Mostly used to have a reserved VMID for debugging and SPM.
466  *
467  * Returns: 0 for success, -ENOENT if an ID is already reserved.
468  */
469 int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
470 			       unsigned vmhub)
471 {
472 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
473 	struct amdgpu_vmid *id;
474 	int r = 0;
475 
476 	mutex_lock(&id_mgr->lock);
477 	if (vm->reserved_vmid[vmhub])
478 		goto unlock;
479 	if (id_mgr->reserved_vmid) {
480 		r = -ENOENT;
481 		goto unlock;
482 	}
483 	/* Remove from normal round robin handling */
484 	id = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vmid, list);
485 	list_del_init(&id->list);
486 	vm->reserved_vmid[vmhub] = id;
487 	id_mgr->reserved_vmid = true;
488 	mutex_unlock(&id_mgr->lock);
489 
490 	return 0;
491 unlock:
492 	mutex_unlock(&id_mgr->lock);
493 	return r;
494 }
495 
496 /*
497  * amdgpu_vmid_free_reserved - free up a reserved VMID again
498  * @adev: amdgpu device structure
499  * @vm: the VM with the reserved ID
500  * @vmhub: the VMHUB which should be used
501  */
502 void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm,
503 			       unsigned vmhub)
504 {
505 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
506 
507 	mutex_lock(&id_mgr->lock);
508 	if (vm->reserved_vmid[vmhub]) {
509 		list_add(&vm->reserved_vmid[vmhub]->list,
510 			&id_mgr->ids_lru);
511 		vm->reserved_vmid[vmhub] = NULL;
512 		id_mgr->reserved_vmid = false;
513 	}
514 	mutex_unlock(&id_mgr->lock);
515 }
516 
517 /**
518  * amdgpu_vmid_reset - reset VMID to zero
519  *
520  * @adev: amdgpu device structure
521  * @vmhub: vmhub type
522  * @vmid: vmid number to use
523  *
524  * Reset saved GDW, GWS and OA to force switch on next flush.
525  */
526 void amdgpu_vmid_reset(struct amdgpu_device *adev, unsigned vmhub,
527 		       unsigned vmid)
528 {
529 	struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
530 	struct amdgpu_vmid *id = &id_mgr->ids[vmid];
531 
532 	mutex_lock(&id_mgr->lock);
533 	id->owner = 0;
534 	id->gds_base = 0;
535 	id->gds_size = 0;
536 	id->gws_base = 0;
537 	id->gws_size = 0;
538 	id->oa_base = 0;
539 	id->oa_size = 0;
540 	mutex_unlock(&id_mgr->lock);
541 }
542 
543 /**
544  * amdgpu_vmid_reset_all - reset VMID to zero
545  *
546  * @adev: amdgpu device structure
547  *
548  * Reset VMID to force flush on next use
549  */
550 void amdgpu_vmid_reset_all(struct amdgpu_device *adev)
551 {
552 	unsigned i, j;
553 
554 	for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
555 		struct amdgpu_vmid_mgr *id_mgr =
556 			&adev->vm_manager.id_mgr[i];
557 
558 		for (j = 1; j < id_mgr->num_ids; ++j)
559 			amdgpu_vmid_reset(adev, i, j);
560 	}
561 }
562 
563 /**
564  * amdgpu_vmid_mgr_init - init the VMID manager
565  *
566  * @adev: amdgpu_device pointer
567  *
568  * Initialize the VM manager structures
569  */
570 void amdgpu_vmid_mgr_init(struct amdgpu_device *adev)
571 {
572 	unsigned i, j;
573 
574 	for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
575 		struct amdgpu_vmid_mgr *id_mgr =
576 			&adev->vm_manager.id_mgr[i];
577 
578 		mutex_init(&id_mgr->lock);
579 		INIT_LIST_HEAD(&id_mgr->ids_lru);
580 
581 		/* for GC <10, SDMA uses MMHUB so use first_kfd_vmid for both GC and MM */
582 		if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 0, 0))
583 			/* manage only VMIDs not used by KFD */
584 			id_mgr->num_ids = adev->vm_manager.first_kfd_vmid;
585 		else if (AMDGPU_IS_MMHUB0(i) ||
586 			 AMDGPU_IS_MMHUB1(i))
587 			id_mgr->num_ids = 16;
588 		else
589 			/* manage only VMIDs not used by KFD */
590 			id_mgr->num_ids = adev->vm_manager.first_kfd_vmid;
591 
592 		/* skip over VMID 0, since it is the system VM */
593 		for (j = 1; j < id_mgr->num_ids; ++j) {
594 			amdgpu_vmid_reset(adev, i, j);
595 			amdgpu_sync_create(&id_mgr->ids[j].active);
596 			list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru);
597 		}
598 	}
599 }
600 
601 /**
602  * amdgpu_vmid_mgr_fini - cleanup VM manager
603  *
604  * @adev: amdgpu_device pointer
605  *
606  * Cleanup the VM manager and free resources.
607  */
608 void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
609 {
610 	unsigned i, j;
611 
612 	for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
613 		struct amdgpu_vmid_mgr *id_mgr =
614 			&adev->vm_manager.id_mgr[i];
615 
616 		mutex_destroy(&id_mgr->lock);
617 		for (j = 0; j < AMDGPU_NUM_VMID; ++j) {
618 			struct amdgpu_vmid *id = &id_mgr->ids[j];
619 
620 			amdgpu_sync_free(&id->active);
621 			dma_fence_put(id->last_flush);
622 			dma_fence_put(id->pasid_mapping);
623 		}
624 	}
625 }
626 
627 /**
628  * amdgpu_pasid_mgr_cleanup - cleanup PASID manager
629  *
630  * Cleanup the IDR allocator.
631  */
632 void amdgpu_pasid_mgr_cleanup(void)
633 {
634 	spin_lock(&amdgpu_pasid_idr_lock);
635 	idr_destroy(&amdgpu_pasid_idr);
636 	spin_unlock(&amdgpu_pasid_idr_lock);
637 }
638