]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drm/amdgpu: keep the prefered/allowed domains in the BO
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vm.c
1 /*
2  * Copyright 2008 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 #include <drm/drmP.h>
29 #include <drm/amdgpu_drm.h>
30 #include "amdgpu.h"
31 #include "amdgpu_trace.h"
32
33 /*
34  * GPUVM
35  * GPUVM is similar to the legacy gart on older asics, however
36  * rather than there being a single global gart table
37  * for the entire GPU, there are multiple VM page tables active
38  * at any given time.  The VM page tables can contain a mix
39  * vram pages and system memory pages and system memory pages
40  * can be mapped as snooped (cached system pages) or unsnooped
41  * (uncached system pages).
42  * Each VM has an ID associated with it and there is a page table
43  * associated with each VMID.  When execting a command buffer,
44  * the kernel tells the the ring what VMID to use for that command
45  * buffer.  VMIDs are allocated dynamically as commands are submitted.
46  * The userspace drivers maintain their own address space and the kernel
47  * sets up their pages tables accordingly when they submit their
48  * command buffers and a VMID is assigned.
49  * Cayman/Trinity support up to 8 active VMs at any given time;
50  * SI supports 16.
51  */
52
53 /**
54  * amdgpu_vm_num_pde - return the number of page directory entries
55  *
56  * @adev: amdgpu_device pointer
57  *
58  * Calculate the number of page directory entries (cayman+).
59  */
60 static unsigned amdgpu_vm_num_pdes(struct amdgpu_device *adev)
61 {
62         return adev->vm_manager.max_pfn >> amdgpu_vm_block_size;
63 }
64
65 /**
66  * amdgpu_vm_directory_size - returns the size of the page directory in bytes
67  *
68  * @adev: amdgpu_device pointer
69  *
70  * Calculate the size of the page directory in bytes (cayman+).
71  */
72 static unsigned amdgpu_vm_directory_size(struct amdgpu_device *adev)
73 {
74         return AMDGPU_GPU_PAGE_ALIGN(amdgpu_vm_num_pdes(adev) * 8);
75 }
76
77 /**
78  * amdgpu_vm_get_pd_bo - add the VM PD to a validation list
79  *
80  * @vm: vm providing the BOs
81  * @validated: head of validation list
82  * @entry: entry to add
83  *
84  * Add the page directory to the list of BOs to
85  * validate for command submission.
86  */
87 void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,
88                          struct list_head *validated,
89                          struct amdgpu_bo_list_entry *entry)
90 {
91         entry->robj = vm->page_directory;
92         entry->priority = 0;
93         entry->tv.bo = &vm->page_directory->tbo;
94         entry->tv.shared = true;
95         list_add(&entry->tv.head, validated);
96 }
97
98 /**
99  * amdgpu_vm_get_bos - add the vm BOs to a duplicates list
100  *
101  * @vm: vm providing the BOs
102  * @duplicates: head of duplicates list
103  *
104  * Add the page directory to the BO duplicates list
105  * for command submission.
106  */
107 void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates)
108 {
109         unsigned i;
110
111         /* add the vm page table to the list */
112         for (i = 0; i <= vm->max_pde_used; ++i) {
113                 struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry;
114
115                 if (!entry->robj)
116                         continue;
117
118                 list_add(&entry->tv.head, duplicates);
119         }
120
121 }
122
123 /**
124  * amdgpu_vm_move_pt_bos_in_lru - move the PT BOs to the LRU tail
125  *
126  * @adev: amdgpu device instance
127  * @vm: vm providing the BOs
128  *
129  * Move the PT BOs to the tail of the LRU.
130  */
131 void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
132                                   struct amdgpu_vm *vm)
133 {
134         struct ttm_bo_global *glob = adev->mman.bdev.glob;
135         unsigned i;
136
137         spin_lock(&glob->lru_lock);
138         for (i = 0; i <= vm->max_pde_used; ++i) {
139                 struct amdgpu_bo_list_entry *entry = &vm->page_tables[i].entry;
140
141                 if (!entry->robj)
142                         continue;
143
144                 ttm_bo_move_to_lru_tail(&entry->robj->tbo);
145         }
146         spin_unlock(&glob->lru_lock);
147 }
148
149 /**
150  * amdgpu_vm_grab_id - allocate the next free VMID
151  *
152  * @vm: vm to allocate id for
153  * @ring: ring we want to submit job to
154  * @sync: sync object where we add dependencies
155  *
156  * Allocate an id for the vm, adding fences to the sync obj as necessary.
157  *
158  * Global mutex must be locked!
159  */
160 int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
161                       struct amdgpu_sync *sync)
162 {
163         struct fence *best[AMDGPU_MAX_RINGS] = {};
164         struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx];
165         struct amdgpu_device *adev = ring->adev;
166
167         unsigned choices[2] = {};
168         unsigned i;
169
170         /* check if the id is still valid */
171         if (vm_id->id) {
172                 unsigned id = vm_id->id;
173                 long owner;
174
175                 owner = atomic_long_read(&adev->vm_manager.ids[id].owner);
176                 if (owner == (long)vm) {
177                         trace_amdgpu_vm_grab_id(vm_id->id, ring->idx);
178                         return 0;
179                 }
180         }
181
182         /* we definately need to flush */
183         vm_id->pd_gpu_addr = ~0ll;
184
185         /* skip over VMID 0, since it is the system VM */
186         for (i = 1; i < adev->vm_manager.nvm; ++i) {
187                 struct fence *fence = adev->vm_manager.ids[i].active;
188                 struct amdgpu_ring *fring;
189
190                 if (fence == NULL) {
191                         /* found a free one */
192                         vm_id->id = i;
193                         trace_amdgpu_vm_grab_id(i, ring->idx);
194                         return 0;
195                 }
196
197                 fring = amdgpu_ring_from_fence(fence);
198                 if (best[fring->idx] == NULL ||
199                     fence_is_later(best[fring->idx], fence)) {
200                         best[fring->idx] = fence;
201                         choices[fring == ring ? 0 : 1] = i;
202                 }
203         }
204
205         for (i = 0; i < 2; ++i) {
206                 if (choices[i]) {
207                         struct fence *fence;
208
209                         fence  = adev->vm_manager.ids[choices[i]].active;
210                         vm_id->id = choices[i];
211
212                         trace_amdgpu_vm_grab_id(choices[i], ring->idx);
213                         return amdgpu_sync_fence(ring->adev, sync, fence);
214                 }
215         }
216
217         /* should never happen */
218         BUG();
219         return -EINVAL;
220 }
221
222 /**
223  * amdgpu_vm_flush - hardware flush the vm
224  *
225  * @ring: ring to use for flush
226  * @vm: vm we want to flush
227  * @updates: last vm update that we waited for
228  *
229  * Flush the vm (cayman+).
230  *
231  * Global and local mutex must be locked!
232  */
233 void amdgpu_vm_flush(struct amdgpu_ring *ring,
234                      struct amdgpu_vm *vm,
235                      struct fence *updates)
236 {
237         uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory);
238         struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx];
239         struct fence *flushed_updates = vm_id->flushed_updates;
240         bool is_later;
241
242         if (!flushed_updates)
243                 is_later = true;
244         else if (!updates)
245                 is_later = false;
246         else
247                 is_later = fence_is_later(updates, flushed_updates);
248
249         if (pd_addr != vm_id->pd_gpu_addr || is_later) {
250                 trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id);
251                 if (is_later) {
252                         vm_id->flushed_updates = fence_get(updates);
253                         fence_put(flushed_updates);
254                 }
255                 vm_id->pd_gpu_addr = pd_addr;
256                 amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr);
257         }
258 }
259
260 /**
261  * amdgpu_vm_fence - remember fence for vm
262  *
263  * @adev: amdgpu_device pointer
264  * @vm: vm we want to fence
265  * @fence: fence to remember
266  *
267  * Fence the vm (cayman+).
268  * Set the fence used to protect page table and id.
269  *
270  * Global and local mutex must be locked!
271  */
272 void amdgpu_vm_fence(struct amdgpu_device *adev,
273                      struct amdgpu_vm *vm,
274                      struct fence *fence)
275 {
276         struct amdgpu_ring *ring = amdgpu_ring_from_fence(fence);
277         unsigned vm_id = vm->ids[ring->idx].id;
278
279         fence_put(adev->vm_manager.ids[vm_id].active);
280         adev->vm_manager.ids[vm_id].active = fence_get(fence);
281         atomic_long_set(&adev->vm_manager.ids[vm_id].owner, (long)vm);
282 }
283
284 /**
285  * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo
286  *
287  * @vm: requested vm
288  * @bo: requested buffer object
289  *
290  * Find @bo inside the requested vm (cayman+).
291  * Search inside the @bos vm list for the requested vm
292  * Returns the found bo_va or NULL if none is found
293  *
294  * Object has to be reserved!
295  */
296 struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
297                                        struct amdgpu_bo *bo)
298 {
299         struct amdgpu_bo_va *bo_va;
300
301         list_for_each_entry(bo_va, &bo->va, bo_list) {
302                 if (bo_va->vm == vm) {
303                         return bo_va;
304                 }
305         }
306         return NULL;
307 }
308
309 /**
310  * amdgpu_vm_update_pages - helper to call the right asic function
311  *
312  * @adev: amdgpu_device pointer
313  * @ib: indirect buffer to fill with commands
314  * @pe: addr of the page entry
315  * @addr: dst addr to write into pe
316  * @count: number of page entries to update
317  * @incr: increase next addr by incr bytes
318  * @flags: hw access flags
319  * @gtt_flags: GTT hw access flags
320  *
321  * Traces the parameters and calls the right asic functions
322  * to setup the page table using the DMA.
323  */
324 static void amdgpu_vm_update_pages(struct amdgpu_device *adev,
325                                    struct amdgpu_ib *ib,
326                                    uint64_t pe, uint64_t addr,
327                                    unsigned count, uint32_t incr,
328                                    uint32_t flags, uint32_t gtt_flags)
329 {
330         trace_amdgpu_vm_set_page(pe, addr, count, incr, flags);
331
332         if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) {
333                 uint64_t src = adev->gart.table_addr + (addr >> 12) * 8;
334                 amdgpu_vm_copy_pte(adev, ib, pe, src, count);
335
336         } else if ((flags & AMDGPU_PTE_SYSTEM) || (count < 3)) {
337                 amdgpu_vm_write_pte(adev, ib, pe, addr,
338                                       count, incr, flags);
339
340         } else {
341                 amdgpu_vm_set_pte_pde(adev, ib, pe, addr,
342                                       count, incr, flags);
343         }
344 }
345
346 int amdgpu_vm_free_job(struct amdgpu_job *job)
347 {
348         int i;
349         for (i = 0; i < job->num_ibs; i++)
350                 amdgpu_ib_free(job->adev, &job->ibs[i]);
351         kfree(job->ibs);
352         return 0;
353 }
354
355 /**
356  * amdgpu_vm_clear_bo - initially clear the page dir/table
357  *
358  * @adev: amdgpu_device pointer
359  * @bo: bo to clear
360  *
361  * need to reserve bo first before calling it.
362  */
363 static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
364                               struct amdgpu_bo *bo)
365 {
366         struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring;
367         struct fence *fence = NULL;
368         struct amdgpu_ib *ib;
369         unsigned entries;
370         uint64_t addr;
371         int r;
372
373         r = reservation_object_reserve_shared(bo->tbo.resv);
374         if (r)
375                 return r;
376
377         r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
378         if (r)
379                 goto error;
380
381         addr = amdgpu_bo_gpu_offset(bo);
382         entries = amdgpu_bo_size(bo) / 8;
383
384         ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
385         if (!ib)
386                 goto error;
387
388         r = amdgpu_ib_get(ring, NULL, entries * 2 + 64, ib);
389         if (r)
390                 goto error_free;
391
392         ib->length_dw = 0;
393
394         amdgpu_vm_update_pages(adev, ib, addr, 0, entries, 0, 0, 0);
395         amdgpu_vm_pad_ib(adev, ib);
396         WARN_ON(ib->length_dw > 64);
397         r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
398                                                  &amdgpu_vm_free_job,
399                                                  AMDGPU_FENCE_OWNER_VM,
400                                                  &fence);
401         if (!r)
402                 amdgpu_bo_fence(bo, fence, true);
403         fence_put(fence);
404         if (amdgpu_enable_scheduler)
405                 return 0;
406
407 error_free:
408         amdgpu_ib_free(adev, ib);
409         kfree(ib);
410
411 error:
412         return r;
413 }
414
415 /**
416  * amdgpu_vm_map_gart - get the physical address of a gart page
417  *
418  * @adev: amdgpu_device pointer
419  * @addr: the unmapped addr
420  *
421  * Look up the physical address of the page that the pte resolves
422  * to (cayman+).
423  * Returns the physical address of the page.
424  */
425 uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr)
426 {
427         uint64_t result;
428
429         /* page table offset */
430         result = adev->gart.pages_addr[addr >> PAGE_SHIFT];
431
432         /* in case cpu page size != gpu page size*/
433         result |= addr & (~PAGE_MASK);
434
435         return result;
436 }
437
438 /**
439  * amdgpu_vm_update_pdes - make sure that page directory is valid
440  *
441  * @adev: amdgpu_device pointer
442  * @vm: requested vm
443  * @start: start of GPU address range
444  * @end: end of GPU address range
445  *
446  * Allocates new page tables if necessary
447  * and updates the page directory (cayman+).
448  * Returns 0 for success, error for failure.
449  *
450  * Global and local mutex must be locked!
451  */
452 int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
453                                     struct amdgpu_vm *vm)
454 {
455         struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring;
456         struct amdgpu_bo *pd = vm->page_directory;
457         uint64_t pd_addr = amdgpu_bo_gpu_offset(pd);
458         uint32_t incr = AMDGPU_VM_PTE_COUNT * 8;
459         uint64_t last_pde = ~0, last_pt = ~0;
460         unsigned count = 0, pt_idx, ndw;
461         struct amdgpu_ib *ib;
462         struct fence *fence = NULL;
463
464         int r;
465
466         /* padding, etc. */
467         ndw = 64;
468
469         /* assume the worst case */
470         ndw += vm->max_pde_used * 6;
471
472         /* update too big for an IB */
473         if (ndw > 0xfffff)
474                 return -ENOMEM;
475
476         ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
477         if (!ib)
478                 return -ENOMEM;
479
480         r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
481         if (r) {
482                 kfree(ib);
483                 return r;
484         }
485         ib->length_dw = 0;
486
487         /* walk over the address space and update the page directory */
488         for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) {
489                 struct amdgpu_bo *bo = vm->page_tables[pt_idx].entry.robj;
490                 uint64_t pde, pt;
491
492                 if (bo == NULL)
493                         continue;
494
495                 pt = amdgpu_bo_gpu_offset(bo);
496                 if (vm->page_tables[pt_idx].addr == pt)
497                         continue;
498                 vm->page_tables[pt_idx].addr = pt;
499
500                 pde = pd_addr + pt_idx * 8;
501                 if (((last_pde + 8 * count) != pde) ||
502                     ((last_pt + incr * count) != pt)) {
503
504                         if (count) {
505                                 amdgpu_vm_update_pages(adev, ib, last_pde,
506                                                        last_pt, count, incr,
507                                                        AMDGPU_PTE_VALID, 0);
508                         }
509
510                         count = 1;
511                         last_pde = pde;
512                         last_pt = pt;
513                 } else {
514                         ++count;
515                 }
516         }
517
518         if (count)
519                 amdgpu_vm_update_pages(adev, ib, last_pde, last_pt, count,
520                                        incr, AMDGPU_PTE_VALID, 0);
521
522         if (ib->length_dw != 0) {
523                 amdgpu_vm_pad_ib(adev, ib);
524                 amdgpu_sync_resv(adev, &ib->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM);
525                 WARN_ON(ib->length_dw > ndw);
526                 r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
527                                                          &amdgpu_vm_free_job,
528                                                          AMDGPU_FENCE_OWNER_VM,
529                                                          &fence);
530                 if (r)
531                         goto error_free;
532
533                 amdgpu_bo_fence(pd, fence, true);
534                 fence_put(vm->page_directory_fence);
535                 vm->page_directory_fence = fence_get(fence);
536                 fence_put(fence);
537         }
538
539         if (!amdgpu_enable_scheduler || ib->length_dw == 0) {
540                 amdgpu_ib_free(adev, ib);
541                 kfree(ib);
542         }
543
544         return 0;
545
546 error_free:
547         amdgpu_ib_free(adev, ib);
548         kfree(ib);
549         return r;
550 }
551
552 /**
553  * amdgpu_vm_frag_ptes - add fragment information to PTEs
554  *
555  * @adev: amdgpu_device pointer
556  * @ib: IB for the update
557  * @pe_start: first PTE to handle
558  * @pe_end: last PTE to handle
559  * @addr: addr those PTEs should point to
560  * @flags: hw mapping flags
561  * @gtt_flags: GTT hw mapping flags
562  *
563  * Global and local mutex must be locked!
564  */
565 static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev,
566                                 struct amdgpu_ib *ib,
567                                 uint64_t pe_start, uint64_t pe_end,
568                                 uint64_t addr, uint32_t flags,
569                                 uint32_t gtt_flags)
570 {
571         /**
572          * The MC L1 TLB supports variable sized pages, based on a fragment
573          * field in the PTE. When this field is set to a non-zero value, page
574          * granularity is increased from 4KB to (1 << (12 + frag)). The PTE
575          * flags are considered valid for all PTEs within the fragment range
576          * and corresponding mappings are assumed to be physically contiguous.
577          *
578          * The L1 TLB can store a single PTE for the whole fragment,
579          * significantly increasing the space available for translation
580          * caching. This leads to large improvements in throughput when the
581          * TLB is under pressure.
582          *
583          * The L2 TLB distributes small and large fragments into two
584          * asymmetric partitions. The large fragment cache is significantly
585          * larger. Thus, we try to use large fragments wherever possible.
586          * Userspace can support this by aligning virtual base address and
587          * allocation size to the fragment size.
588          */
589
590         /* SI and newer are optimized for 64KB */
591         uint64_t frag_flags = AMDGPU_PTE_FRAG_64KB;
592         uint64_t frag_align = 0x80;
593
594         uint64_t frag_start = ALIGN(pe_start, frag_align);
595         uint64_t frag_end = pe_end & ~(frag_align - 1);
596
597         unsigned count;
598
599         /* system pages are non continuously */
600         if ((flags & AMDGPU_PTE_SYSTEM) || !(flags & AMDGPU_PTE_VALID) ||
601             (frag_start >= frag_end)) {
602
603                 count = (pe_end - pe_start) / 8;
604                 amdgpu_vm_update_pages(adev, ib, pe_start, addr, count,
605                                        AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags);
606                 return;
607         }
608
609         /* handle the 4K area at the beginning */
610         if (pe_start != frag_start) {
611                 count = (frag_start - pe_start) / 8;
612                 amdgpu_vm_update_pages(adev, ib, pe_start, addr, count,
613                                        AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags);
614                 addr += AMDGPU_GPU_PAGE_SIZE * count;
615         }
616
617         /* handle the area in the middle */
618         count = (frag_end - frag_start) / 8;
619         amdgpu_vm_update_pages(adev, ib, frag_start, addr, count,
620                                AMDGPU_GPU_PAGE_SIZE, flags | frag_flags,
621                                gtt_flags);
622
623         /* handle the 4K area at the end */
624         if (frag_end != pe_end) {
625                 addr += AMDGPU_GPU_PAGE_SIZE * count;
626                 count = (pe_end - frag_end) / 8;
627                 amdgpu_vm_update_pages(adev, ib, frag_end, addr, count,
628                                        AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags);
629         }
630 }
631
632 /**
633  * amdgpu_vm_update_ptes - make sure that page tables are valid
634  *
635  * @adev: amdgpu_device pointer
636  * @vm: requested vm
637  * @start: start of GPU address range
638  * @end: end of GPU address range
639  * @dst: destination address to map to
640  * @flags: mapping flags
641  *
642  * Update the page tables in the range @start - @end (cayman+).
643  *
644  * Global and local mutex must be locked!
645  */
646 static int amdgpu_vm_update_ptes(struct amdgpu_device *adev,
647                                  struct amdgpu_vm *vm,
648                                  struct amdgpu_ib *ib,
649                                  uint64_t start, uint64_t end,
650                                  uint64_t dst, uint32_t flags,
651                                  uint32_t gtt_flags)
652 {
653         uint64_t mask = AMDGPU_VM_PTE_COUNT - 1;
654         uint64_t last_pte = ~0, last_dst = ~0;
655         void *owner = AMDGPU_FENCE_OWNER_VM;
656         unsigned count = 0;
657         uint64_t addr;
658
659         /* sync to everything on unmapping */
660         if (!(flags & AMDGPU_PTE_VALID))
661                 owner = AMDGPU_FENCE_OWNER_UNDEFINED;
662
663         /* walk over the address space and update the page tables */
664         for (addr = start; addr < end; ) {
665                 uint64_t pt_idx = addr >> amdgpu_vm_block_size;
666                 struct amdgpu_bo *pt = vm->page_tables[pt_idx].entry.robj;
667                 unsigned nptes;
668                 uint64_t pte;
669                 int r;
670
671                 amdgpu_sync_resv(adev, &ib->sync, pt->tbo.resv, owner);
672                 r = reservation_object_reserve_shared(pt->tbo.resv);
673                 if (r)
674                         return r;
675
676                 if ((addr & ~mask) == (end & ~mask))
677                         nptes = end - addr;
678                 else
679                         nptes = AMDGPU_VM_PTE_COUNT - (addr & mask);
680
681                 pte = amdgpu_bo_gpu_offset(pt);
682                 pte += (addr & mask) * 8;
683
684                 if ((last_pte + 8 * count) != pte) {
685
686                         if (count) {
687                                 amdgpu_vm_frag_ptes(adev, ib, last_pte,
688                                                     last_pte + 8 * count,
689                                                     last_dst, flags,
690                                                     gtt_flags);
691                         }
692
693                         count = nptes;
694                         last_pte = pte;
695                         last_dst = dst;
696                 } else {
697                         count += nptes;
698                 }
699
700                 addr += nptes;
701                 dst += nptes * AMDGPU_GPU_PAGE_SIZE;
702         }
703
704         if (count) {
705                 amdgpu_vm_frag_ptes(adev, ib, last_pte,
706                                     last_pte + 8 * count,
707                                     last_dst, flags, gtt_flags);
708         }
709
710         return 0;
711 }
712
713 /**
714  * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table
715  *
716  * @adev: amdgpu_device pointer
717  * @vm: requested vm
718  * @mapping: mapped range and flags to use for the update
719  * @addr: addr to set the area to
720  * @gtt_flags: flags as they are used for GTT
721  * @fence: optional resulting fence
722  *
723  * Fill in the page table entries for @mapping.
724  * Returns 0 for success, -EINVAL for failure.
725  *
726  * Object have to be reserved and mutex must be locked!
727  */
728 static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
729                                        struct amdgpu_vm *vm,
730                                        struct amdgpu_bo_va_mapping *mapping,
731                                        uint64_t addr, uint32_t gtt_flags,
732                                        struct fence **fence)
733 {
734         struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring;
735         unsigned nptes, ncmds, ndw;
736         uint32_t flags = gtt_flags;
737         struct amdgpu_ib *ib;
738         struct fence *f = NULL;
739         int r;
740
741         /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here
742          * but in case of something, we filter the flags in first place
743          */
744         if (!(mapping->flags & AMDGPU_PTE_READABLE))
745                 flags &= ~AMDGPU_PTE_READABLE;
746         if (!(mapping->flags & AMDGPU_PTE_WRITEABLE))
747                 flags &= ~AMDGPU_PTE_WRITEABLE;
748
749         trace_amdgpu_vm_bo_update(mapping);
750
751         nptes = mapping->it.last - mapping->it.start + 1;
752
753         /*
754          * reserve space for one command every (1 << BLOCK_SIZE)
755          *  entries or 2k dwords (whatever is smaller)
756          */
757         ncmds = (nptes >> min(amdgpu_vm_block_size, 11)) + 1;
758
759         /* padding, etc. */
760         ndw = 64;
761
762         if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) {
763                 /* only copy commands needed */
764                 ndw += ncmds * 7;
765
766         } else if (flags & AMDGPU_PTE_SYSTEM) {
767                 /* header for write data commands */
768                 ndw += ncmds * 4;
769
770                 /* body of write data command */
771                 ndw += nptes * 2;
772
773         } else {
774                 /* set page commands needed */
775                 ndw += ncmds * 10;
776
777                 /* two extra commands for begin/end of fragment */
778                 ndw += 2 * 10;
779         }
780
781         /* update too big for an IB */
782         if (ndw > 0xfffff)
783                 return -ENOMEM;
784
785         ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL);
786         if (!ib)
787                 return -ENOMEM;
788
789         r = amdgpu_ib_get(ring, NULL, ndw * 4, ib);
790         if (r) {
791                 kfree(ib);
792                 return r;
793         }
794
795         ib->length_dw = 0;
796
797         r = amdgpu_vm_update_ptes(adev, vm, ib, mapping->it.start,
798                                   mapping->it.last + 1, addr + mapping->offset,
799                                   flags, gtt_flags);
800
801         if (r) {
802                 amdgpu_ib_free(adev, ib);
803                 kfree(ib);
804                 return r;
805         }
806
807         amdgpu_vm_pad_ib(adev, ib);
808         WARN_ON(ib->length_dw > ndw);
809         r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1,
810                                                  &amdgpu_vm_free_job,
811                                                  AMDGPU_FENCE_OWNER_VM,
812                                                  &f);
813         if (r)
814                 goto error_free;
815
816         amdgpu_bo_fence(vm->page_directory, f, true);
817         if (fence) {
818                 fence_put(*fence);
819                 *fence = fence_get(f);
820         }
821         fence_put(f);
822         if (!amdgpu_enable_scheduler) {
823                 amdgpu_ib_free(adev, ib);
824                 kfree(ib);
825         }
826         return 0;
827
828 error_free:
829         amdgpu_ib_free(adev, ib);
830         kfree(ib);
831         return r;
832 }
833
834 /**
835  * amdgpu_vm_bo_update - update all BO mappings in the vm page table
836  *
837  * @adev: amdgpu_device pointer
838  * @bo_va: requested BO and VM object
839  * @mem: ttm mem
840  *
841  * Fill in the page table entries for @bo_va.
842  * Returns 0 for success, -EINVAL for failure.
843  *
844  * Object have to be reserved and mutex must be locked!
845  */
846 int amdgpu_vm_bo_update(struct amdgpu_device *adev,
847                         struct amdgpu_bo_va *bo_va,
848                         struct ttm_mem_reg *mem)
849 {
850         struct amdgpu_vm *vm = bo_va->vm;
851         struct amdgpu_bo_va_mapping *mapping;
852         uint32_t flags;
853         uint64_t addr;
854         int r;
855
856         if (mem) {
857                 addr = (u64)mem->start << PAGE_SHIFT;
858                 if (mem->mem_type != TTM_PL_TT)
859                         addr += adev->vm_manager.vram_base_offset;
860         } else {
861                 addr = 0;
862         }
863
864         flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem);
865
866         spin_lock(&vm->status_lock);
867         if (!list_empty(&bo_va->vm_status))
868                 list_splice_init(&bo_va->valids, &bo_va->invalids);
869         spin_unlock(&vm->status_lock);
870
871         list_for_each_entry(mapping, &bo_va->invalids, list) {
872                 r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, addr,
873                                                 flags, &bo_va->last_pt_update);
874                 if (r)
875                         return r;
876         }
877
878         if (trace_amdgpu_vm_bo_mapping_enabled()) {
879                 list_for_each_entry(mapping, &bo_va->valids, list)
880                         trace_amdgpu_vm_bo_mapping(mapping);
881
882                 list_for_each_entry(mapping, &bo_va->invalids, list)
883                         trace_amdgpu_vm_bo_mapping(mapping);
884         }
885
886         spin_lock(&vm->status_lock);
887         list_splice_init(&bo_va->invalids, &bo_va->valids);
888         list_del_init(&bo_va->vm_status);
889         if (!mem)
890                 list_add(&bo_va->vm_status, &vm->cleared);
891         spin_unlock(&vm->status_lock);
892
893         return 0;
894 }
895
896 /**
897  * amdgpu_vm_clear_freed - clear freed BOs in the PT
898  *
899  * @adev: amdgpu_device pointer
900  * @vm: requested vm
901  *
902  * Make sure all freed BOs are cleared in the PT.
903  * Returns 0 for success.
904  *
905  * PTs have to be reserved and mutex must be locked!
906  */
907 int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
908                           struct amdgpu_vm *vm)
909 {
910         struct amdgpu_bo_va_mapping *mapping;
911         int r;
912
913         spin_lock(&vm->freed_lock);
914         while (!list_empty(&vm->freed)) {
915                 mapping = list_first_entry(&vm->freed,
916                         struct amdgpu_bo_va_mapping, list);
917                 list_del(&mapping->list);
918                 spin_unlock(&vm->freed_lock);
919                 r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL);
920                 kfree(mapping);
921                 if (r)
922                         return r;
923
924                 spin_lock(&vm->freed_lock);
925         }
926         spin_unlock(&vm->freed_lock);
927
928         return 0;
929
930 }
931
932 /**
933  * amdgpu_vm_clear_invalids - clear invalidated BOs in the PT
934  *
935  * @adev: amdgpu_device pointer
936  * @vm: requested vm
937  *
938  * Make sure all invalidated BOs are cleared in the PT.
939  * Returns 0 for success.
940  *
941  * PTs have to be reserved and mutex must be locked!
942  */
943 int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
944                              struct amdgpu_vm *vm, struct amdgpu_sync *sync)
945 {
946         struct amdgpu_bo_va *bo_va = NULL;
947         int r = 0;
948
949         spin_lock(&vm->status_lock);
950         while (!list_empty(&vm->invalidated)) {
951                 bo_va = list_first_entry(&vm->invalidated,
952                         struct amdgpu_bo_va, vm_status);
953                 spin_unlock(&vm->status_lock);
954                 mutex_lock(&bo_va->mutex);
955                 r = amdgpu_vm_bo_update(adev, bo_va, NULL);
956                 mutex_unlock(&bo_va->mutex);
957                 if (r)
958                         return r;
959
960                 spin_lock(&vm->status_lock);
961         }
962         spin_unlock(&vm->status_lock);
963
964         if (bo_va)
965                 r = amdgpu_sync_fence(adev, sync, bo_va->last_pt_update);
966
967         return r;
968 }
969
970 /**
971  * amdgpu_vm_bo_add - add a bo to a specific vm
972  *
973  * @adev: amdgpu_device pointer
974  * @vm: requested vm
975  * @bo: amdgpu buffer object
976  *
977  * Add @bo into the requested vm (cayman+).
978  * Add @bo to the list of bos associated with the vm
979  * Returns newly added bo_va or NULL for failure
980  *
981  * Object has to be reserved!
982  */
983 struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
984                                       struct amdgpu_vm *vm,
985                                       struct amdgpu_bo *bo)
986 {
987         struct amdgpu_bo_va *bo_va;
988
989         bo_va = kzalloc(sizeof(struct amdgpu_bo_va), GFP_KERNEL);
990         if (bo_va == NULL) {
991                 return NULL;
992         }
993         bo_va->vm = vm;
994         bo_va->bo = bo;
995         bo_va->ref_count = 1;
996         INIT_LIST_HEAD(&bo_va->bo_list);
997         INIT_LIST_HEAD(&bo_va->valids);
998         INIT_LIST_HEAD(&bo_va->invalids);
999         INIT_LIST_HEAD(&bo_va->vm_status);
1000         mutex_init(&bo_va->mutex);
1001         list_add_tail(&bo_va->bo_list, &bo->va);
1002
1003         return bo_va;
1004 }
1005
1006 /**
1007  * amdgpu_vm_bo_map - map bo inside a vm
1008  *
1009  * @adev: amdgpu_device pointer
1010  * @bo_va: bo_va to store the address
1011  * @saddr: where to map the BO
1012  * @offset: requested offset in the BO
1013  * @flags: attributes of pages (read/write/valid/etc.)
1014  *
1015  * Add a mapping of the BO at the specefied addr into the VM.
1016  * Returns 0 for success, error for failure.
1017  *
1018  * Object has to be reserved and unreserved outside!
1019  */
1020 int amdgpu_vm_bo_map(struct amdgpu_device *adev,
1021                      struct amdgpu_bo_va *bo_va,
1022                      uint64_t saddr, uint64_t offset,
1023                      uint64_t size, uint32_t flags)
1024 {
1025         struct amdgpu_bo_va_mapping *mapping;
1026         struct amdgpu_vm *vm = bo_va->vm;
1027         struct interval_tree_node *it;
1028         unsigned last_pfn, pt_idx;
1029         uint64_t eaddr;
1030         int r;
1031
1032         /* validate the parameters */
1033         if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK ||
1034             size == 0 || size & AMDGPU_GPU_PAGE_MASK)
1035                 return -EINVAL;
1036
1037         /* make sure object fit at this offset */
1038         eaddr = saddr + size - 1;
1039         if ((saddr >= eaddr) || (offset + size > amdgpu_bo_size(bo_va->bo)))
1040                 return -EINVAL;
1041
1042         last_pfn = eaddr / AMDGPU_GPU_PAGE_SIZE;
1043         if (last_pfn >= adev->vm_manager.max_pfn) {
1044                 dev_err(adev->dev, "va above limit (0x%08X >= 0x%08X)\n",
1045                         last_pfn, adev->vm_manager.max_pfn);
1046                 return -EINVAL;
1047         }
1048
1049         saddr /= AMDGPU_GPU_PAGE_SIZE;
1050         eaddr /= AMDGPU_GPU_PAGE_SIZE;
1051
1052         spin_lock(&vm->it_lock);
1053         it = interval_tree_iter_first(&vm->va, saddr, eaddr);
1054         spin_unlock(&vm->it_lock);
1055         if (it) {
1056                 struct amdgpu_bo_va_mapping *tmp;
1057                 tmp = container_of(it, struct amdgpu_bo_va_mapping, it);
1058                 /* bo and tmp overlap, invalid addr */
1059                 dev_err(adev->dev, "bo %p va 0x%010Lx-0x%010Lx conflict with "
1060                         "0x%010lx-0x%010lx\n", bo_va->bo, saddr, eaddr,
1061                         tmp->it.start, tmp->it.last + 1);
1062                 r = -EINVAL;
1063                 goto error;
1064         }
1065
1066         mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
1067         if (!mapping) {
1068                 r = -ENOMEM;
1069                 goto error;
1070         }
1071
1072         INIT_LIST_HEAD(&mapping->list);
1073         mapping->it.start = saddr;
1074         mapping->it.last = eaddr;
1075         mapping->offset = offset;
1076         mapping->flags = flags;
1077
1078         mutex_lock(&bo_va->mutex);
1079         list_add(&mapping->list, &bo_va->invalids);
1080         mutex_unlock(&bo_va->mutex);
1081         spin_lock(&vm->it_lock);
1082         interval_tree_insert(&mapping->it, &vm->va);
1083         spin_unlock(&vm->it_lock);
1084         trace_amdgpu_vm_bo_map(bo_va, mapping);
1085
1086         /* Make sure the page tables are allocated */
1087         saddr >>= amdgpu_vm_block_size;
1088         eaddr >>= amdgpu_vm_block_size;
1089
1090         BUG_ON(eaddr >= amdgpu_vm_num_pdes(adev));
1091
1092         if (eaddr > vm->max_pde_used)
1093                 vm->max_pde_used = eaddr;
1094
1095         /* walk over the address space and allocate the page tables */
1096         for (pt_idx = saddr; pt_idx <= eaddr; ++pt_idx) {
1097                 struct reservation_object *resv = vm->page_directory->tbo.resv;
1098                 struct amdgpu_bo_list_entry *entry;
1099                 struct amdgpu_bo *pt;
1100
1101                 entry = &vm->page_tables[pt_idx].entry;
1102                 if (entry->robj)
1103                         continue;
1104
1105                 r = amdgpu_bo_create(adev, AMDGPU_VM_PTE_COUNT * 8,
1106                                      AMDGPU_GPU_PAGE_SIZE, true,
1107                                      AMDGPU_GEM_DOMAIN_VRAM,
1108                                      AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
1109                                      NULL, resv, &pt);
1110                 if (r)
1111                         goto error_free;
1112
1113                 /* Keep a reference to the page table to avoid freeing
1114                  * them up in the wrong order.
1115                  */
1116                 pt->parent = amdgpu_bo_ref(vm->page_directory);
1117
1118                 r = amdgpu_vm_clear_bo(adev, pt);
1119                 if (r) {
1120                         amdgpu_bo_unref(&pt);
1121                         goto error_free;
1122                 }
1123
1124                 entry->robj = pt;
1125                 entry->priority = 0;
1126                 entry->tv.bo = &entry->robj->tbo;
1127                 entry->tv.shared = true;
1128                 vm->page_tables[pt_idx].addr = 0;
1129         }
1130
1131         return 0;
1132
1133 error_free:
1134         list_del(&mapping->list);
1135         spin_lock(&vm->it_lock);
1136         interval_tree_remove(&mapping->it, &vm->va);
1137         spin_unlock(&vm->it_lock);
1138         trace_amdgpu_vm_bo_unmap(bo_va, mapping);
1139         kfree(mapping);
1140
1141 error:
1142         return r;
1143 }
1144
1145 /**
1146  * amdgpu_vm_bo_unmap - remove bo mapping from vm
1147  *
1148  * @adev: amdgpu_device pointer
1149  * @bo_va: bo_va to remove the address from
1150  * @saddr: where to the BO is mapped
1151  *
1152  * Remove a mapping of the BO at the specefied addr from the VM.
1153  * Returns 0 for success, error for failure.
1154  *
1155  * Object has to be reserved and unreserved outside!
1156  */
1157 int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
1158                        struct amdgpu_bo_va *bo_va,
1159                        uint64_t saddr)
1160 {
1161         struct amdgpu_bo_va_mapping *mapping;
1162         struct amdgpu_vm *vm = bo_va->vm;
1163         bool valid = true;
1164
1165         saddr /= AMDGPU_GPU_PAGE_SIZE;
1166         mutex_lock(&bo_va->mutex);
1167         list_for_each_entry(mapping, &bo_va->valids, list) {
1168                 if (mapping->it.start == saddr)
1169                         break;
1170         }
1171
1172         if (&mapping->list == &bo_va->valids) {
1173                 valid = false;
1174
1175                 list_for_each_entry(mapping, &bo_va->invalids, list) {
1176                         if (mapping->it.start == saddr)
1177                                 break;
1178                 }
1179
1180                 if (&mapping->list == &bo_va->invalids) {
1181                         mutex_unlock(&bo_va->mutex);
1182                         return -ENOENT;
1183                 }
1184         }
1185         mutex_unlock(&bo_va->mutex);
1186         list_del(&mapping->list);
1187         spin_lock(&vm->it_lock);
1188         interval_tree_remove(&mapping->it, &vm->va);
1189         spin_unlock(&vm->it_lock);
1190         trace_amdgpu_vm_bo_unmap(bo_va, mapping);
1191
1192         if (valid) {
1193                 spin_lock(&vm->freed_lock);
1194                 list_add(&mapping->list, &vm->freed);
1195                 spin_unlock(&vm->freed_lock);
1196         } else {
1197                 kfree(mapping);
1198         }
1199
1200         return 0;
1201 }
1202
1203 /**
1204  * amdgpu_vm_bo_rmv - remove a bo to a specific vm
1205  *
1206  * @adev: amdgpu_device pointer
1207  * @bo_va: requested bo_va
1208  *
1209  * Remove @bo_va->bo from the requested vm (cayman+).
1210  *
1211  * Object have to be reserved!
1212  */
1213 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
1214                       struct amdgpu_bo_va *bo_va)
1215 {
1216         struct amdgpu_bo_va_mapping *mapping, *next;
1217         struct amdgpu_vm *vm = bo_va->vm;
1218
1219         list_del(&bo_va->bo_list);
1220
1221         spin_lock(&vm->status_lock);
1222         list_del(&bo_va->vm_status);
1223         spin_unlock(&vm->status_lock);
1224
1225         list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
1226                 list_del(&mapping->list);
1227                 spin_lock(&vm->it_lock);
1228                 interval_tree_remove(&mapping->it, &vm->va);
1229                 spin_unlock(&vm->it_lock);
1230                 trace_amdgpu_vm_bo_unmap(bo_va, mapping);
1231                 spin_lock(&vm->freed_lock);
1232                 list_add(&mapping->list, &vm->freed);
1233                 spin_unlock(&vm->freed_lock);
1234         }
1235         list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) {
1236                 list_del(&mapping->list);
1237                 spin_lock(&vm->it_lock);
1238                 interval_tree_remove(&mapping->it, &vm->va);
1239                 spin_unlock(&vm->it_lock);
1240                 kfree(mapping);
1241         }
1242         fence_put(bo_va->last_pt_update);
1243         mutex_destroy(&bo_va->mutex);
1244         kfree(bo_va);
1245 }
1246
1247 /**
1248  * amdgpu_vm_bo_invalidate - mark the bo as invalid
1249  *
1250  * @adev: amdgpu_device pointer
1251  * @vm: requested vm
1252  * @bo: amdgpu buffer object
1253  *
1254  * Mark @bo as invalid (cayman+).
1255  */
1256 void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
1257                              struct amdgpu_bo *bo)
1258 {
1259         struct amdgpu_bo_va *bo_va;
1260
1261         list_for_each_entry(bo_va, &bo->va, bo_list) {
1262                 spin_lock(&bo_va->vm->status_lock);
1263                 if (list_empty(&bo_va->vm_status))
1264                         list_add(&bo_va->vm_status, &bo_va->vm->invalidated);
1265                 spin_unlock(&bo_va->vm->status_lock);
1266         }
1267 }
1268
1269 /**
1270  * amdgpu_vm_init - initialize a vm instance
1271  *
1272  * @adev: amdgpu_device pointer
1273  * @vm: requested vm
1274  *
1275  * Init @vm fields (cayman+).
1276  */
1277 int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
1278 {
1279         const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE,
1280                 AMDGPU_VM_PTE_COUNT * 8);
1281         unsigned pd_size, pd_entries;
1282         int i, r;
1283
1284         for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1285                 vm->ids[i].id = 0;
1286                 vm->ids[i].flushed_updates = NULL;
1287         }
1288         vm->va = RB_ROOT;
1289         spin_lock_init(&vm->status_lock);
1290         INIT_LIST_HEAD(&vm->invalidated);
1291         INIT_LIST_HEAD(&vm->cleared);
1292         INIT_LIST_HEAD(&vm->freed);
1293         spin_lock_init(&vm->it_lock);
1294         spin_lock_init(&vm->freed_lock);
1295         pd_size = amdgpu_vm_directory_size(adev);
1296         pd_entries = amdgpu_vm_num_pdes(adev);
1297
1298         /* allocate page table array */
1299         vm->page_tables = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt));
1300         if (vm->page_tables == NULL) {
1301                 DRM_ERROR("Cannot allocate memory for page table array\n");
1302                 return -ENOMEM;
1303         }
1304
1305         vm->page_directory_fence = NULL;
1306
1307         r = amdgpu_bo_create(adev, pd_size, align, true,
1308                              AMDGPU_GEM_DOMAIN_VRAM,
1309                              AMDGPU_GEM_CREATE_NO_CPU_ACCESS,
1310                              NULL, NULL, &vm->page_directory);
1311         if (r)
1312                 return r;
1313         r = amdgpu_bo_reserve(vm->page_directory, false);
1314         if (r) {
1315                 amdgpu_bo_unref(&vm->page_directory);
1316                 vm->page_directory = NULL;
1317                 return r;
1318         }
1319         r = amdgpu_vm_clear_bo(adev, vm->page_directory);
1320         amdgpu_bo_unreserve(vm->page_directory);
1321         if (r) {
1322                 amdgpu_bo_unref(&vm->page_directory);
1323                 vm->page_directory = NULL;
1324                 return r;
1325         }
1326
1327         return 0;
1328 }
1329
1330 /**
1331  * amdgpu_vm_fini - tear down a vm instance
1332  *
1333  * @adev: amdgpu_device pointer
1334  * @vm: requested vm
1335  *
1336  * Tear down @vm (cayman+).
1337  * Unbind the VM and remove all bos from the vm bo list
1338  */
1339 void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
1340 {
1341         struct amdgpu_bo_va_mapping *mapping, *tmp;
1342         int i;
1343
1344         if (!RB_EMPTY_ROOT(&vm->va)) {
1345                 dev_err(adev->dev, "still active bo inside vm\n");
1346         }
1347         rbtree_postorder_for_each_entry_safe(mapping, tmp, &vm->va, it.rb) {
1348                 list_del(&mapping->list);
1349                 interval_tree_remove(&mapping->it, &vm->va);
1350                 kfree(mapping);
1351         }
1352         list_for_each_entry_safe(mapping, tmp, &vm->freed, list) {
1353                 list_del(&mapping->list);
1354                 kfree(mapping);
1355         }
1356
1357         for (i = 0; i < amdgpu_vm_num_pdes(adev); i++)
1358                 amdgpu_bo_unref(&vm->page_tables[i].entry.robj);
1359         drm_free_large(vm->page_tables);
1360
1361         amdgpu_bo_unref(&vm->page_directory);
1362         fence_put(vm->page_directory_fence);
1363         for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
1364                 unsigned id = vm->ids[i].id;
1365
1366                 atomic_long_cmpxchg(&adev->vm_manager.ids[id].owner,
1367                                     (long)vm, 0);
1368                 fence_put(vm->ids[i].flushed_updates);
1369         }
1370
1371 }
1372
1373 /**
1374  * amdgpu_vm_manager_fini - cleanup VM manager
1375  *
1376  * @adev: amdgpu_device pointer
1377  *
1378  * Cleanup the VM manager and free resources.
1379  */
1380 void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
1381 {
1382         unsigned i;
1383
1384         for (i = 0; i < AMDGPU_NUM_VM; ++i)
1385                 fence_put(adev->vm_manager.ids[i].active);
1386 }
This page took 0.124652 seconds and 4 git commands to generate.