diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-08-25 12:59:50 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-08-25 12:59:50 +1000 |
| commit | e9c3ddee6a08c5b25cdb06b524320a5a98250513 (patch) | |
| tree | 41cc2cc030ef965c1d34b336c994a3ac9c00c13e /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |
| parent | 51d6120792ab5f46d6f5f7f37b65d05cc1afc019 (diff) | |
| parent | 7b4d3e297e8a7d3b82e68231ff077e891c370349 (diff) | |
| download | linux-e9c3ddee6a08c5b25cdb06b524320a5a98250513.tar.gz linux-e9c3ddee6a08c5b25cdb06b524320a5a98250513.tar.bz2 linux-e9c3ddee6a08c5b25cdb06b524320a5a98250513.zip | |
Merge branch 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux into drm-next
First drm-next pull for radeon and amdgpu for 4.9. Highlights:
- powerplay support for iceland asics
- improved GPU reset (both full asic and per block)
- UVD and VCE powergating for CZ and ST
- VCE clockgating for CZ and ST
- Support for pre-initialized (e.g., zeroed) vram buffers
- ttm cleanups
- virtual display support
- core and radeon/amdgpu support for page_flip_target
- lots of bug fixes and clean ups
* 'drm-next-4.9' of git://people.freedesktop.org/~agd5f/linux: (171 commits)
drm/amdgpu: use memcpy_toio for VCE firmware upload
drm/amdgpu: use memcpy_to/fromio for UVD fw upload
drm/amd/powerplay: delete useless code in iceland_hwmgr.c.
drm/radeon: switch UVD code to use UVD_NO_OP for padding
drm/amdgpu: switch UVD code to use UVD_NO_OP for padding
drm/radeon: add support for UVD_NO_OP register
drm/amdgpu: add support for UVD_NO_OP register
drm/amdgpu: fix VCE ib alignment value
drm/amdgpu: fix IB alignment for UVD
drm/amd/amdgpu: Print ring name in amdgpu_ib_schedule()
drm/radeon: remove dead code, si_mc_load_microcode (v2)
drm/radeon/cik: remove dead code (v2)
drm/amd/powerplay: avoid NULL dereference, cz_hwmgr.c
drm/amd/powerplay: avoid NULL pointer dereference
drm/amdgpu/gmc8: remove dead code (v2)
drm/amdgpu/gmc7: remove dead code (v2)
drm/amdgpu: Fix indentation in dce_v8_0_audio_write_sad_regs()
drm/amdgpu: Use correct mask in dce_v8_0_afmt_setmode() and fix comment typos.
drm/amdgpu: cleanup amdgpu_vm_bo_update params
drm/amdgpu: stop adding dummy entry in amdgpu_ttm_placement_init
...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 95 |
1 files changed, 60 insertions, 35 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 0307ff5887c5..d80e5d3a4add 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -287,18 +287,56 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) return max(bytes_moved_threshold, 1024*1024ull); } +static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, + struct amdgpu_bo *bo) +{ + u64 initial_bytes_moved; + uint32_t domain; + int r; + + if (bo->pin_count) + return 0; + + /* Avoid moving this one if we have moved too many buffers + * for this IB already. + * + * Note that this allows moving at least one buffer of + * any size, because it doesn't take the current "bo" + * into account. We don't want to disallow buffer moves + * completely. + */ + if (p->bytes_moved <= p->bytes_moved_threshold) + domain = bo->prefered_domains; + else + domain = bo->allowed_domains; + +retry: + amdgpu_ttm_placement_from_domain(bo, domain); + initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved); + r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); + p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) - + initial_bytes_moved; + + if (unlikely(r)) { + if (r != -ERESTARTSYS && domain != bo->allowed_domains) { + domain = bo->allowed_domains; + goto retry; + } + } + + return r; +} + int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, struct list_head *validated) { struct amdgpu_bo_list_entry *lobj; - u64 initial_bytes_moved; int r; list_for_each_entry(lobj, validated, tv.head) { struct amdgpu_bo *bo = lobj->robj; bool binding_userptr = false; struct mm_struct *usermm; - uint32_t domain; usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); if (usermm && usermm != current->mm) @@ -313,35 +351,13 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, binding_userptr = true; } - if (bo->pin_count) - continue; - - /* Avoid moving this one if we have moved too many buffers - * for this IB already. - * - * Note that this allows moving at least one buffer of - * any size, because it doesn't take the current "bo" - * into account. We don't want to disallow buffer moves - * completely. - */ - if (p->bytes_moved <= p->bytes_moved_threshold) - domain = bo->prefered_domains; - else - domain = bo->allowed_domains; - - retry: - amdgpu_ttm_placement_from_domain(bo, domain); - initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved); - r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); - p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) - - initial_bytes_moved; - - if (unlikely(r)) { - if (r != -ERESTARTSYS && domain != bo->allowed_domains) { - domain = bo->allowed_domains; - goto retry; - } + r = amdgpu_cs_bo_validate(p, bo); + if (r) return r; + if (bo->shadow) { + r = amdgpu_cs_bo_validate(p, bo); + if (r) + return r; } if (binding_userptr) { @@ -386,8 +402,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); - if (unlikely(r != 0)) + if (unlikely(r != 0)) { + DRM_ERROR("ttm_eu_reserve_buffers failed.\n"); goto error_free_pages; + } /* Without a BO list we don't have userptr BOs */ if (!p->bo_list) @@ -427,9 +445,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, /* Unreserve everything again. */ ttm_eu_backoff_reservation(&p->ticket, &p->validated); - /* We tried to often, just abort */ + /* We tried too many times, just abort */ if (!--tries) { r = -EDEADLK; + DRM_ERROR("deadlock in %s\n", __func__); goto error_free_pages; } @@ -441,11 +460,13 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, sizeof(struct page*)); if (!e->user_pages) { r = -ENOMEM; + DRM_ERROR("calloc failure in %s\n", __func__); goto error_free_pages; } r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages); if (r) { + DRM_ERROR("amdgpu_ttm_tt_get_user_pages failed.\n"); drm_free_large(e->user_pages); e->user_pages = NULL; goto error_free_pages; @@ -462,12 +483,16 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, p->bytes_moved = 0; r = amdgpu_cs_list_validate(p, &duplicates); - if (r) + if (r) { + DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n"); goto error_validate; + } r = amdgpu_cs_list_validate(p, &p->validated); - if (r) + if (r) { + DRM_ERROR("amdgpu_cs_list_validate(validated) failed.\n"); goto error_validate; + } fpriv->vm.last_eviction_counter = atomic64_read(&p->adev->num_evictions); @@ -617,7 +642,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (bo_va == NULL) continue; - r = amdgpu_vm_bo_update(adev, bo_va, &bo->tbo.mem); + r = amdgpu_vm_bo_update(adev, bo_va, false); if (r) return r; |
