[PATCH 6/8] drm/amdgpu: move reusing VMIDs into separate function
Chunming Zhou
zhoucm1 at amd.com
Thu Feb 1 06:23:19 UTC 2018
Reviewed-by: Chunming Zhou <david1.zhou at amd.com>
On 2018年01月31日 23:47, Christian König wrote:
> Let's try this once more.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 130 ++++++++++++++++++++------------
> 1 file changed, 81 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> index 86d012b21554..a139c4e2dc53 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
> @@ -321,58 +321,51 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
> }
>
> /**
> - * amdgpu_vm_grab_id - allocate the next free VMID
> + * amdgpu_vm_grab_used - try to reuse a VMID
> *
> * @vm: vm to allocate id for
> * @ring: ring we want to submit job to
> * @sync: sync object where we add dependencies
> * @fence: fence protecting ID from reuse
> * @job: job who wants to use the VMID
> + * @id: resulting VMID
> *
> - * Allocate an id for the vm, adding fences to the sync obj as necessary.
> + * Try to reuse a VMID for this submission.
> */
> -int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> - struct amdgpu_sync *sync, struct dma_fence *fence,
> - struct amdgpu_job *job)
> +static int amdgpu_vmid_grab_used(struct amdgpu_vm *vm,
> + struct amdgpu_ring *ring,
> + struct amdgpu_sync *sync,
> + struct dma_fence *fence,
> + struct amdgpu_job *job,
> + struct amdgpu_vmid **id)
> {
> struct amdgpu_device *adev = ring->adev;
> unsigned vmhub = ring->funcs->vmhub;
> struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
> uint64_t fence_context = adev->fence_context + ring->idx;
> struct dma_fence *updates = sync->last_vm_update;
> - struct amdgpu_vmid *id, *idle;
> - int r = 0;
> -
> - mutex_lock(&id_mgr->lock);
> - r = amdgpu_vmid_grab_idle(vm, ring, sync, &idle);
> - if (r || !idle)
> - goto error;
> -
> - if (vm->reserved_vmid[vmhub]) {
> - r = amdgpu_vmid_grab_reserved(vm, ring, sync, fence, job);
> - mutex_unlock(&id_mgr->lock);
> - return r;
> - }
> + int r;
>
> job->vm_needs_flush = vm->use_cpu_for_update;
> +
> /* Check if we can use a VMID already assigned to this VM */
> - list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) {
> - struct dma_fence *flushed;
> + list_for_each_entry_reverse((*id), &id_mgr->ids_lru, list) {
> bool needs_flush = vm->use_cpu_for_update;
> + struct dma_fence *flushed;
>
> /* Check all the prerequisites to using this VMID */
> - if (id->owner != vm->entity.fence_context)
> + if ((*id)->owner != vm->entity.fence_context)
> continue;
>
> - if (job->vm_pd_addr != id->pd_gpu_addr)
> + if ((*id)->pd_gpu_addr != job->vm_pd_addr)
> continue;
>
> - if (!id->last_flush ||
> - (id->last_flush->context != fence_context &&
> - !dma_fence_is_signaled(id->last_flush)))
> + if (!(*id)->last_flush ||
> + ((*id)->last_flush->context != fence_context &&
> + !dma_fence_is_signaled((*id)->last_flush)))
> needs_flush = true;
>
> - flushed = id->flushed_updates;
> + flushed = (*id)->flushed_updates;
> if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
> needs_flush = true;
>
> @@ -380,44 +373,83 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> if (adev->asic_type < CHIP_VEGA10 && needs_flush)
> continue;
>
> - /* Good we can use this VMID. Remember this submission as
> + /* Good, we can use this VMID. Remember this submission as
> * user of the VMID.
> */
> - r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
> + r = amdgpu_sync_fence(ring->adev, &(*id)->active, fence, false);
> if (r)
> - goto error;
> + return r;
>
> if (updates && (!flushed || dma_fence_is_later(updates, flushed))) {
> - dma_fence_put(id->flushed_updates);
> - id->flushed_updates = dma_fence_get(updates);
> + dma_fence_put((*id)->flushed_updates);
> + (*id)->flushed_updates = dma_fence_get(updates);
> }
>
> - if (needs_flush)
> - goto needs_flush;
> - else
> - goto no_flush_needed;
> -
> + job->vm_needs_flush |= needs_flush;
> + return 0;
> }
>
> - /* Still no ID to use? Then use the idle one found earlier */
> - id = idle;
> + *id = NULL;
> + return 0;
> +}
>
> - /* Remember this submission as user of the VMID */
> - r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
> +/**
> + * amdgpu_vm_grab_id - allocate the next free VMID
> + *
> + * @vm: vm to allocate id for
> + * @ring: ring we want to submit job to
> + * @sync: sync object where we add dependencies
> + * @fence: fence protecting ID from reuse
> + * @job: job who wants to use the VMID
> + *
> + * Allocate an id for the vm, adding fences to the sync obj as necessary.
> + */
> +int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> + struct amdgpu_sync *sync, struct dma_fence *fence,
> + struct amdgpu_job *job)
> +{
> + struct amdgpu_device *adev = ring->adev;
> + unsigned vmhub = ring->funcs->vmhub;
> + struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
> + struct dma_fence *updates = sync->last_vm_update;
> + struct amdgpu_vmid *id, *idle;
> + int r = 0;
> +
> + mutex_lock(&id_mgr->lock);
> + r = amdgpu_vmid_grab_idle(vm, ring, sync, &idle);
> + if (r || !idle)
> + goto error;
> +
> + if (vm->reserved_vmid[vmhub]) {
> + r = amdgpu_vmid_grab_reserved(vm, ring, sync, fence, job);
> + mutex_unlock(&id_mgr->lock);
> + return r;
> + }
> +
> + r = amdgpu_vmid_grab_used(vm, ring, sync, fence, job, &id);
> if (r)
> goto error;
>
> - id->pd_gpu_addr = job->vm_pd_addr;
> - dma_fence_put(id->flushed_updates);
> - id->flushed_updates = dma_fence_get(updates);
> - id->owner = vm->entity.fence_context;
> + if (!id) {
> + /* Still no ID to use? Then use the idle one found earlier */
> + id = idle;
>
> -needs_flush:
> - job->vm_needs_flush = true;
> - dma_fence_put(id->last_flush);
> - id->last_flush = NULL;
> + /* Remember this submission as user of the VMID */
> + r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
> + if (r)
> + goto error;
>
> -no_flush_needed:
> + id->pd_gpu_addr = job->vm_pd_addr;
> + dma_fence_put(id->flushed_updates);
> + id->flushed_updates = dma_fence_get(updates);
> + id->owner = vm->entity.fence_context;
> + job->vm_needs_flush = true;
> + }
> +
> + if (job->vm_needs_flush) {
> + dma_fence_put(id->last_flush);
> + id->last_flush = NULL;
> + }
> list_move_tail(&id->list, &id_mgr->ids_lru);
>
> job->vmid = id - id_mgr->ids;
More information about the amd-gfx
mailing list