diff options
author | Dave Airlie <airlied@redhat.com> | 2017-03-30 21:47:18 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-03-30 21:47:18 -0400 |
commit | 8cd3ac52963f2e99f4c21d1c9ce89531ce66c2d6 (patch) | |
tree | 94f7d4526fe19a32643308d6e00d0fc5442af277 /drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |
parent | 8bcad07a45637fb88e799466e4eee83859e8ffd3 (diff) | |
parent | 60508d3df2d2052881190ac82802a12cabcef53c (diff) |
Merge branch 'drm-next-4.12' of git://people.freedesktop.org/~agd5f/linux into drm-next
New stuff for 4.12:
- Preliminary vega10 support
- Support for multi-level page tables
- GPU sensor stuff for mesa
- job tracing improvements
- PRT support for sparse buffers
- Additional SR-IOV improvements
- ttm improvements
- misc bug fixes and code cleanups
* 'drm-next-4.12' of git://people.freedesktop.org/~agd5f/linux: (315 commits)
drm/amdgpu: Fix 32bit x86 compilation warning
drm/amdgpu: just disallow reading untouched registers
drm/amdgpu: remove duplicate allowed reg CP_CPF_BUSY_STAT
drm/amdgpu/soc15: enable psp block for SRIOV
drm/amdgpu/soc15: bypass pp block for vf
drm/amdgpu/psp: add check sOS sign
drm/amd/amdgpu: Correct ring wptr address in debugfs (v2)
drm/amdgpu: Fix multi-level page table bugs for large BOs v3
drm/amdgpu: Fix Vega10 VM initialization
drm/amdgpu: Make max_pfn 64-bit
drm/amdgpu: drop GB_GPU_ID from the golden settings
drm/amdgpu: fix vm pte pde flags to 64-bit for sdma (v3)
drm/amd/amdgpu: fix Tonga S3 resume hang on rhel6.8
drm/ttm: decrease ttm bo priority number
drm/amd/amdgpu: fix performance drop when VRAM pressure
drm/amdgpu: Couple small warning fixes
drm/amdgpu: Clean up GFX 9 VM fault messages
drm/amdgpu: Register UTCL2 as a source of VM faults
drm/amdgpu/soc15: drop support for reading some registers
drm/amdgpu/soc15: return cached values for some registers (v2)
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 122 |
1 files changed, 86 insertions, 36 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 106cf83c2e6b..f85520d4e711 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
@@ -152,6 +152,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
152 | struct ttm_validate_buffer tv; | 152 | struct ttm_validate_buffer tv; |
153 | struct ww_acquire_ctx ticket; | 153 | struct ww_acquire_ctx ticket; |
154 | struct amdgpu_bo_va *bo_va; | 154 | struct amdgpu_bo_va *bo_va; |
155 | struct dma_fence *fence = NULL; | ||
155 | int r; | 156 | int r; |
156 | 157 | ||
157 | INIT_LIST_HEAD(&list); | 158 | INIT_LIST_HEAD(&list); |
@@ -173,6 +174,17 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
173 | if (bo_va) { | 174 | if (bo_va) { |
174 | if (--bo_va->ref_count == 0) { | 175 | if (--bo_va->ref_count == 0) { |
175 | amdgpu_vm_bo_rmv(adev, bo_va); | 176 | amdgpu_vm_bo_rmv(adev, bo_va); |
177 | |||
178 | r = amdgpu_vm_clear_freed(adev, vm, &fence); | ||
179 | if (unlikely(r)) { | ||
180 | dev_err(adev->dev, "failed to clear page " | ||
181 | "tables on GEM object close (%d)\n", r); | ||
182 | } | ||
183 | |||
184 | if (fence) { | ||
185 | amdgpu_bo_fence(bo, fence, true); | ||
186 | dma_fence_put(fence); | ||
187 | } | ||
176 | } | 188 | } |
177 | } | 189 | } |
178 | ttm_eu_backoff_reservation(&ticket, &list); | 190 | ttm_eu_backoff_reservation(&ticket, &list); |
@@ -507,14 +519,16 @@ static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo) | |||
507 | * amdgpu_gem_va_update_vm -update the bo_va in its VM | 519 | * amdgpu_gem_va_update_vm -update the bo_va in its VM |
508 | * | 520 | * |
509 | * @adev: amdgpu_device pointer | 521 | * @adev: amdgpu_device pointer |
522 | * @vm: vm to update | ||
510 | * @bo_va: bo_va to update | 523 | * @bo_va: bo_va to update |
511 | * @list: validation list | 524 | * @list: validation list |
512 | * @operation: map or unmap | 525 | * @operation: map, unmap or clear |
513 | * | 526 | * |
514 | * Update the bo_va directly after setting its address. Errors are not | 527 | * Update the bo_va directly after setting its address. Errors are not |
515 | * vital here, so they are not reported back to userspace. | 528 | * vital here, so they are not reported back to userspace. |
516 | */ | 529 | */ |
517 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | 530 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, |
531 | struct amdgpu_vm *vm, | ||
518 | struct amdgpu_bo_va *bo_va, | 532 | struct amdgpu_bo_va *bo_va, |
519 | struct list_head *list, | 533 | struct list_head *list, |
520 | uint32_t operation) | 534 | uint32_t operation) |
@@ -529,20 +543,21 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
529 | goto error; | 543 | goto error; |
530 | } | 544 | } |
531 | 545 | ||
532 | r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check, | 546 | r = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_va_check, |
533 | NULL); | 547 | NULL); |
534 | if (r) | 548 | if (r) |
535 | goto error; | 549 | goto error; |
536 | 550 | ||
537 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); | 551 | r = amdgpu_vm_update_directories(adev, vm); |
538 | if (r) | 552 | if (r) |
539 | goto error; | 553 | goto error; |
540 | 554 | ||
541 | r = amdgpu_vm_clear_freed(adev, bo_va->vm); | 555 | r = amdgpu_vm_clear_freed(adev, vm, NULL); |
542 | if (r) | 556 | if (r) |
543 | goto error; | 557 | goto error; |
544 | 558 | ||
545 | if (operation == AMDGPU_VA_OP_MAP) | 559 | if (operation == AMDGPU_VA_OP_MAP || |
560 | operation == AMDGPU_VA_OP_REPLACE) | ||
546 | r = amdgpu_vm_bo_update(adev, bo_va, false); | 561 | r = amdgpu_vm_bo_update(adev, bo_va, false); |
547 | 562 | ||
548 | error: | 563 | error: |
@@ -553,6 +568,12 @@ error: | |||
553 | int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | 568 | int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, |
554 | struct drm_file *filp) | 569 | struct drm_file *filp) |
555 | { | 570 | { |
571 | const uint32_t valid_flags = AMDGPU_VM_DELAY_UPDATE | | ||
572 | AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | | ||
573 | AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_MASK; | ||
574 | const uint32_t prt_flags = AMDGPU_VM_DELAY_UPDATE | | ||
575 | AMDGPU_VM_PAGE_PRT; | ||
576 | |||
556 | struct drm_amdgpu_gem_va *args = data; | 577 | struct drm_amdgpu_gem_va *args = data; |
557 | struct drm_gem_object *gobj; | 578 | struct drm_gem_object *gobj; |
558 | struct amdgpu_device *adev = dev->dev_private; | 579 | struct amdgpu_device *adev = dev->dev_private; |
@@ -563,7 +584,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
563 | struct ttm_validate_buffer tv; | 584 | struct ttm_validate_buffer tv; |
564 | struct ww_acquire_ctx ticket; | 585 | struct ww_acquire_ctx ticket; |
565 | struct list_head list; | 586 | struct list_head list; |
566 | uint32_t invalid_flags, va_flags = 0; | 587 | uint64_t va_flags; |
567 | int r = 0; | 588 | int r = 0; |
568 | 589 | ||
569 | if (!adev->vm_manager.enabled) | 590 | if (!adev->vm_manager.enabled) |
@@ -577,17 +598,17 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
577 | return -EINVAL; | 598 | return -EINVAL; |
578 | } | 599 | } |
579 | 600 | ||
580 | invalid_flags = ~(AMDGPU_VM_DELAY_UPDATE | AMDGPU_VM_PAGE_READABLE | | 601 | if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) { |
581 | AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); | 602 | dev_err(&dev->pdev->dev, "invalid flags combination 0x%08X\n", |
582 | if ((args->flags & invalid_flags)) { | 603 | args->flags); |
583 | dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n", | ||
584 | args->flags, invalid_flags); | ||
585 | return -EINVAL; | 604 | return -EINVAL; |
586 | } | 605 | } |
587 | 606 | ||
588 | switch (args->operation) { | 607 | switch (args->operation) { |
589 | case AMDGPU_VA_OP_MAP: | 608 | case AMDGPU_VA_OP_MAP: |
590 | case AMDGPU_VA_OP_UNMAP: | 609 | case AMDGPU_VA_OP_UNMAP: |
610 | case AMDGPU_VA_OP_CLEAR: | ||
611 | case AMDGPU_VA_OP_REPLACE: | ||
591 | break; | 612 | break; |
592 | default: | 613 | default: |
593 | dev_err(&dev->pdev->dev, "unsupported operation %d\n", | 614 | dev_err(&dev->pdev->dev, "unsupported operation %d\n", |
@@ -595,38 +616,47 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
595 | return -EINVAL; | 616 | return -EINVAL; |
596 | } | 617 | } |
597 | 618 | ||
598 | gobj = drm_gem_object_lookup(filp, args->handle); | ||
599 | if (gobj == NULL) | ||
600 | return -ENOENT; | ||
601 | abo = gem_to_amdgpu_bo(gobj); | ||
602 | INIT_LIST_HEAD(&list); | 619 | INIT_LIST_HEAD(&list); |
603 | tv.bo = &abo->tbo; | 620 | if ((args->operation != AMDGPU_VA_OP_CLEAR) && |
604 | tv.shared = false; | 621 | !(args->flags & AMDGPU_VM_PAGE_PRT)) { |
605 | list_add(&tv.head, &list); | 622 | gobj = drm_gem_object_lookup(filp, args->handle); |
623 | if (gobj == NULL) | ||
624 | return -ENOENT; | ||
625 | abo = gem_to_amdgpu_bo(gobj); | ||
626 | tv.bo = &abo->tbo; | ||
627 | tv.shared = false; | ||
628 | list_add(&tv.head, &list); | ||
629 | } else { | ||
630 | gobj = NULL; | ||
631 | abo = NULL; | ||
632 | } | ||
606 | 633 | ||
607 | amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); | 634 | amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); |
608 | 635 | ||
609 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); | 636 | r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); |
610 | if (r) { | 637 | if (r) |
611 | drm_gem_object_unreference_unlocked(gobj); | 638 | goto error_unref; |
612 | return r; | ||
613 | } | ||
614 | 639 | ||
615 | bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo); | 640 | if (abo) { |
616 | if (!bo_va) { | 641 | bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo); |
617 | ttm_eu_backoff_reservation(&ticket, &list); | 642 | if (!bo_va) { |
618 | drm_gem_object_unreference_unlocked(gobj); | 643 | r = -ENOENT; |
619 | return -ENOENT; | 644 | goto error_backoff; |
645 | } | ||
646 | } else if (args->operation != AMDGPU_VA_OP_CLEAR) { | ||
647 | bo_va = fpriv->prt_va; | ||
648 | } else { | ||
649 | bo_va = NULL; | ||
620 | } | 650 | } |
621 | 651 | ||
622 | switch (args->operation) { | 652 | switch (args->operation) { |
623 | case AMDGPU_VA_OP_MAP: | 653 | case AMDGPU_VA_OP_MAP: |
624 | if (args->flags & AMDGPU_VM_PAGE_READABLE) | 654 | r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address, |
625 | va_flags |= AMDGPU_PTE_READABLE; | 655 | args->map_size); |
626 | if (args->flags & AMDGPU_VM_PAGE_WRITEABLE) | 656 | if (r) |
627 | va_flags |= AMDGPU_PTE_WRITEABLE; | 657 | goto error_backoff; |
628 | if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) | 658 | |
629 | va_flags |= AMDGPU_PTE_EXECUTABLE; | 659 | va_flags = amdgpu_vm_get_pte_flags(adev, args->flags); |
630 | r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, | 660 | r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, |
631 | args->offset_in_bo, args->map_size, | 661 | args->offset_in_bo, args->map_size, |
632 | va_flags); | 662 | va_flags); |
@@ -634,14 +664,34 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
634 | case AMDGPU_VA_OP_UNMAP: | 664 | case AMDGPU_VA_OP_UNMAP: |
635 | r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); | 665 | r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); |
636 | break; | 666 | break; |
667 | |||
668 | case AMDGPU_VA_OP_CLEAR: | ||
669 | r = amdgpu_vm_bo_clear_mappings(adev, &fpriv->vm, | ||
670 | args->va_address, | ||
671 | args->map_size); | ||
672 | break; | ||
673 | case AMDGPU_VA_OP_REPLACE: | ||
674 | r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address, | ||
675 | args->map_size); | ||
676 | if (r) | ||
677 | goto error_backoff; | ||
678 | |||
679 | va_flags = amdgpu_vm_get_pte_flags(adev, args->flags); | ||
680 | r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address, | ||
681 | args->offset_in_bo, args->map_size, | ||
682 | va_flags); | ||
683 | break; | ||
637 | default: | 684 | default: |
638 | break; | 685 | break; |
639 | } | 686 | } |
640 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && | 687 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !amdgpu_vm_debug) |
641 | !amdgpu_vm_debug) | 688 | amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, &list, |
642 | amdgpu_gem_va_update_vm(adev, bo_va, &list, args->operation); | 689 | args->operation); |
690 | |||
691 | error_backoff: | ||
643 | ttm_eu_backoff_reservation(&ticket, &list); | 692 | ttm_eu_backoff_reservation(&ticket, &list); |
644 | 693 | ||
694 | error_unref: | ||
645 | drm_gem_object_unreference_unlocked(gobj); | 695 | drm_gem_object_unreference_unlocked(gobj); |
646 | return r; | 696 | return r; |
647 | } | 697 | } |