[PATCH 2/5] drm/amdgpu: separate VMID flush tracking per hub
Alex Deucher
alexdeucher at gmail.com
Wed Apr 5 18:47:53 UTC 2017
On Wed, Apr 5, 2017 at 12:21 PM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> Rather inefficient, but this way we only need to flush the current hub.
>
> I wonder if we shouldn't make nails with heads and separate the VMID ranges completely.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 36 ++++++++++++++++++++--------------
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 6 +++---
> 2 files changed, 24 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 8785420..6fd1952 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -406,6 +406,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> struct amdgpu_job *job)
> {
> struct amdgpu_device *adev = ring->adev;
> + unsigned vmhub = ring->funcs->vmhub;
> uint64_t fence_context = adev->fence_context + ring->idx;
> struct fence *updates = sync->last_vm_update;
> struct amdgpu_vm_id *id, *idle;
> @@ -480,17 +481,17 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> if (atomic64_read(&id->owner) != vm->client_id)
> continue;
>
> - if (job->vm_pd_addr != id->pd_gpu_addr)
> + if (job->vm_pd_addr != id->pd_gpu_addr[vmhub])
> continue;
>
> - if (!id->last_flush)
> + if (!id->last_flush[vmhub])
> continue;
>
> - if (id->last_flush->context != fence_context &&
> - !fence_is_signaled(id->last_flush))
> + if (id->last_flush[vmhub]->context != fence_context &&
> + !fence_is_signaled(id->last_flush[vmhub]))
> continue;
>
> - flushed = id->flushed_updates;
> + flushed = id->flushed_updates[vmhub];
> if (updates &&
> (!flushed || fence_is_later(updates, flushed)))
> continue;
> @@ -522,13 +523,15 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
> if (r)
> goto error;
>
> - fence_put(id->last_flush);
> - id->last_flush = NULL;
> + for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
Would it be worth storing the number of vm_hubs per chip and using
that as the limit? That way we wouldn't loop multiple times for older
asics with only one hub.
Alex
> + fence_put(id->last_flush[i]);
> + id->last_flush[i] = NULL;
> + }
>
> - fence_put(id->flushed_updates);
> - id->flushed_updates = fence_get(updates);
> + fence_put(id->flushed_updates[vmhub]);
> + id->flushed_updates[vmhub] = fence_get(updates);
>
> - id->pd_gpu_addr = job->vm_pd_addr;
> + id->pd_gpu_addr[vmhub] = job->vm_pd_addr;
> id->current_gpu_reset_count = atomic_read(&adev->gpu_reset_counter);
> list_move_tail(&id->list, &adev->vm_manager.ids_lru);
> atomic64_set(&id->owner, vm->client_id);
> @@ -591,6 +594,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
> {
> struct amdgpu_device *adev = ring->adev;
> struct amdgpu_vm_id *id = &adev->vm_manager.ids[job->vm_id];
> + unsigned vmhub = ring->funcs->vmhub;
> bool gds_switch_needed = ring->funcs->emit_gds_switch && (
> id->gds_base != job->gds_base ||
> id->gds_size != job->gds_size ||
> @@ -629,8 +633,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job)
> return r;
>
> mutex_lock(&adev->vm_manager.lock);
> - fence_put(id->last_flush);
> - id->last_flush = fence;
> + fence_put(id->last_flush[vmhub]);
> + id->last_flush[vmhub] = fence;
> mutex_unlock(&adev->vm_manager.lock);
> }
>
> @@ -2234,13 +2238,15 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
> */
> void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
> {
> - unsigned i;
> + unsigned i, j;
>
> for (i = 0; i < AMDGPU_NUM_VM; ++i) {
> struct amdgpu_vm_id *id = &adev->vm_manager.ids[i];
>
> amdgpu_sync_free(&adev->vm_manager.ids[i].active);
> - fence_put(id->flushed_updates);
> - fence_put(id->last_flush);
> + for (j = 0; j < AMDGPU_MAX_VMHUBS; ++j) {
> + fence_put(id->flushed_updates[j]);
> + fence_put(id->last_flush[j]);
> + }
> }
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 7d01372..d61dd83 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -132,12 +132,12 @@ struct amdgpu_vm {
> struct amdgpu_vm_id {
> struct list_head list;
> struct amdgpu_sync active;
> - struct fence *last_flush;
> + struct fence *last_flush[AMDGPU_MAX_VMHUBS];
> atomic64_t owner;
>
> - uint64_t pd_gpu_addr;
> + uint64_t pd_gpu_addr[AMDGPU_MAX_VMHUBS];
> /* last flushed PD/PT update */
> - struct fence *flushed_updates;
> + struct fence *flushed_updates[AMDGPU_MAX_VMHUBS];
>
> uint32_t current_gpu_reset_count;
>
> --
> 2.5.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
More information about the amd-gfx
mailing list