From cadf97b196a1e5b2db2606d53f77714e3e9cf4bb Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Fri, 15 Jan 2016 11:25:00 +0800 Subject: drm/amdgpu: clean up non-scheduler code path (v2) Non-scheduler code is longer supported. v2: agd: rebased on upstream Signed-off-by: Chunming Zhou Reviewed-by: Ken Wang Reviewed-by: Monk Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 44 +++++++++++++------------------ 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 438c05254695..dd9fac302e55 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -76,33 +76,25 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, void *owner, struct fence **f) { - int r = 0; - if (amdgpu_enable_scheduler) { - struct amdgpu_job *job = - kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); - if (!job) - return -ENOMEM; - job->base.sched = &ring->sched; - job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; - job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); - if (!job->base.s_fence) { - kfree(job); - return -ENOMEM; - } - *f = fence_get(&job->base.s_fence->base); - - job->adev = adev; - job->ibs = ibs; - job->num_ibs = num_ibs; - job->owner = owner; - job->free_job = free_job; - amd_sched_entity_push_job(&job->base); - } else { - r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); - if (r) - return r; - *f = fence_get(&ibs[num_ibs - 1].fence->base); + struct amdgpu_job *job = + kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); + if (!job) + return -ENOMEM; + job->base.sched = &ring->sched; + job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; + job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); + if (!job->base.s_fence) { + kfree(job); + return -ENOMEM; } + *f = fence_get(&job->base.s_fence->base); + + job->adev = adev; + job->ibs = ibs; + job->num_ibs = num_ibs; + job->owner = owner; + job->free_job = free_job; + amd_sched_entity_push_job(&job->base); return 0; } -- cgit v1.2.3 From 8d0a7cea824a2784150ef7f25a1e88f18a2a8f69 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 3 Nov 2015 20:58:50 +0100 Subject: drm/amdgpu: grab VMID before submitting job v5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the scheduler to handle the dependencies on ID contention as well. v2: grab id only once v3: use a separate lock for the VMIDs v4: cleanup after semaphore removal v5: minor coding style change Signed-off-by: Christian König Reviewed-by: Chunming Zhou Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 17 +++++------------ drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 26 +++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 719bce615a2b..edfaae439b76 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -777,6 +777,7 @@ struct amdgpu_ib { struct amdgpu_ring *ring; struct amdgpu_fence *fence; struct amdgpu_user_fence *user; + bool grabbed_vmid; struct amdgpu_vm *vm; struct amdgpu_ctx *ctx; struct amdgpu_sync sync; @@ -925,6 +926,9 @@ struct amdgpu_vm { }; struct amdgpu_vm_manager { + /* protecting IDs */ + struct mutex lock; + struct { struct fence *active; atomic_long_t owner; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 80ce22ddbc0c..bbe8023bf58f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1456,6 +1456,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* mutex initialization are all done here so we * can recall function without having locking issues */ mutex_init(&adev->ring_lock); + mutex_init(&adev->vm_manager.lock); atomic_set(&adev->irq.ih.lock, 0); mutex_init(&adev->gem.mutex); mutex_init(&adev->pm.mutex); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 54cede30a69c..56ae9a58dbc5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -142,21 +142,17 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, return -EINVAL; } + if (vm && !ibs->grabbed_vmid) { + dev_err(adev->dev, "VM IB without ID\n"); + return -EINVAL; + } + r = amdgpu_ring_lock(ring, (256 + AMDGPU_NUM_SYNCS * 8) * num_ibs); if (r) { dev_err(adev->dev, "scheduling IB failed (%d).\n", r); return r; } - if (vm) { - /* grab a vm id if necessary */ - r = amdgpu_vm_grab_id(ibs->vm, ibs->ring, &ibs->sync); - if (r) { - amdgpu_ring_unlock_undo(ring); - return r; - } - } - r = amdgpu_sync_wait(&ibs->sync); if (r) { amdgpu_ring_unlock_undo(ring); @@ -207,9 +203,6 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, AMDGPU_FENCE_FLAG_64BIT); } - if (ib->vm) - amdgpu_vm_fence(adev, ib->vm, &ib->fence->base); - amdgpu_ring_unlock_commit(ring); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index dd9fac302e55..b22a95f0571c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -31,7 +31,31 @@ static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) { struct amdgpu_job *job = to_amdgpu_job(sched_job); - return amdgpu_sync_get_fence(&job->ibs->sync); + struct amdgpu_sync *sync = &job->ibs->sync; + struct amdgpu_vm *vm = job->ibs->vm; + + struct fence *fence = amdgpu_sync_get_fence(sync); + + if (fence == NULL && vm && !job->ibs->grabbed_vmid) { + struct amdgpu_ring *ring = job->ibs->ring; + struct amdgpu_device *adev = ring->adev; + int r; + + mutex_lock(&adev->vm_manager.lock); + r = amdgpu_vm_grab_id(vm, ring, sync); + if (r) { + DRM_ERROR("Error getting VM ID (%d)\n", r); + } else { + fence = &job->base.s_fence->base; + amdgpu_vm_fence(ring->adev, vm, fence); + job->ibs->grabbed_vmid = true; + } + mutex_unlock(&adev->vm_manager.lock); + + fence = amdgpu_sync_get_fence(sync); + } + + return fence; } static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) -- cgit v1.2.3 From 94dd0a4ae0b1af997b1f45793e5fd5b47f4ffc18 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 18 Jan 2016 17:01:42 +0100 Subject: drm/amdgpu: merge vm_grab_id and vm_fence v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for an extra function any more. v2: comment cleanups Signed-off-by: Christian König Reviewed-by: Chunming Zhou Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 13 +++---- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 57 ++++++++++++++----------------- 3 files changed, 30 insertions(+), 45 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index edfaae439b76..43b48eb6cf6e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -956,13 +956,10 @@ void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates); void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, struct amdgpu_vm *vm); int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, - struct amdgpu_sync *sync); + struct amdgpu_sync *sync, struct fence *fence); void amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_vm *vm, struct fence *updates); -void amdgpu_vm_fence(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct fence *fence); uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, struct amdgpu_vm *vm); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index b22a95f0571c..76a1f823d983 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -38,19 +38,14 @@ static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) if (fence == NULL && vm && !job->ibs->grabbed_vmid) { struct amdgpu_ring *ring = job->ibs->ring; - struct amdgpu_device *adev = ring->adev; int r; - mutex_lock(&adev->vm_manager.lock); - r = amdgpu_vm_grab_id(vm, ring, sync); - if (r) { + r = amdgpu_vm_grab_id(vm, ring, sync, + &job->base.s_fence->base); + if (r) DRM_ERROR("Error getting VM ID (%d)\n", r); - } else { - fence = &job->base.s_fence->base; - amdgpu_vm_fence(ring->adev, vm, fence); + else job->ibs->grabbed_vmid = true; - } - mutex_unlock(&adev->vm_manager.lock); fence = amdgpu_sync_get_fence(sync); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index edbb3ff4e731..d4718e1cd050 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -152,13 +152,14 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, * @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 * * Allocate an id for the vm, adding fences to the sync obj as necessary. * * Global mutex must be locked! */ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, - struct amdgpu_sync *sync) + struct amdgpu_sync *sync, struct fence *fence) { struct fence *best[AMDGPU_MAX_RINGS] = {}; struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; @@ -167,6 +168,8 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, unsigned choices[2] = {}; unsigned i; + mutex_lock(&adev->vm_manager.lock); + /* check if the id is still valid */ if (vm_id->id) { unsigned id = vm_id->id; @@ -175,6 +178,9 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, owner = atomic_long_read(&adev->vm_manager.ids[id].owner); if (owner == (long)vm) { trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx); + fence_put(adev->vm_manager.ids[id].active); + adev->vm_manager.ids[id].active = fence_get(fence); + mutex_unlock(&adev->vm_manager.lock); return 0; } } @@ -191,6 +197,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, /* found a free one */ vm_id->id = i; trace_amdgpu_vm_grab_id(vm, i, ring->idx); + mutex_unlock(&adev->vm_manager.lock); return 0; } @@ -203,19 +210,29 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, } for (i = 0; i < 2; ++i) { - if (choices[i]) { - struct fence *fence; + struct fence *active; + int r; - fence = adev->vm_manager.ids[choices[i]].active; - vm_id->id = choices[i]; + if (!choices[i]) + continue; - trace_amdgpu_vm_grab_id(vm, choices[i], ring->idx); - return amdgpu_sync_fence(ring->adev, sync, fence); - } + vm_id->id = choices[i]; + active = adev->vm_manager.ids[vm_id->id].active; + r = amdgpu_sync_fence(ring->adev, sync, active); + + trace_amdgpu_vm_grab_id(vm, choices[i], ring->idx); + atomic_long_set(&adev->vm_manager.ids[vm_id->id].owner, (long)vm); + + fence_put(adev->vm_manager.ids[vm_id->id].active); + adev->vm_manager.ids[vm_id->id].active = fence_get(fence); + + mutex_unlock(&adev->vm_manager.lock); + return r; } /* should never happen */ BUG(); + mutex_unlock(&adev->vm_manager.lock); return -EINVAL; } @@ -257,30 +274,6 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, } } -/** - * amdgpu_vm_fence - remember fence for vm - * - * @adev: amdgpu_device pointer - * @vm: vm we want to fence - * @fence: fence to remember - * - * Fence the vm (cayman+). - * Set the fence used to protect page table and id. - * - * Global and local mutex must be locked! - */ -void amdgpu_vm_fence(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct fence *fence) -{ - struct amdgpu_ring *ring = amdgpu_ring_from_fence(fence); - unsigned vm_id = vm->ids[ring->idx].id; - - fence_put(adev->vm_manager.ids[vm_id].active); - adev->vm_manager.ids[vm_id].active = fence_get(fence); - atomic_long_set(&adev->vm_manager.ids[vm_id].owner, (long)vm); -} - /** * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo * -- cgit v1.2.3 From 50838c8cc413de8da39c4c216ae05410845d5a44 Mon Sep 17 00:00:00 2001 From: Christian König Date: Wed, 3 Feb 2016 13:44:52 +0100 Subject: drm/amdgpu: add proper job alloc/free functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And use them in the CS instead of allocating IBs and jobs separately. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 12 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 65 +++++++++++-------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 33 ++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 6 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 6 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 2 +- 6 files changed, 69 insertions(+), 55 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 935b9aa08474..5c55445f0260 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -796,6 +796,9 @@ enum amdgpu_ring_type { extern struct amd_sched_backend_ops amdgpu_sched_ops; +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job); +void amdgpu_job_free(struct amdgpu_job *job); int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, struct amdgpu_ring *ring, struct amdgpu_ib *ibs, @@ -1216,9 +1219,8 @@ struct amdgpu_cs_parser { unsigned nchunks; struct amdgpu_cs_chunk *chunks; - /* indirect buffers */ - uint32_t num_ibs; - struct amdgpu_ib *ibs; + /* scheduler job object */ + struct amdgpu_job *job; /* buffer objects */ struct ww_acquire_ctx ticket; @@ -1249,14 +1251,14 @@ struct amdgpu_job { static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx) { - return p->ibs[ib_idx].ptr[idx]; + return p->job->ibs[ib_idx].ptr[idx]; } static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx, uint32_t value) { - p->ibs[ib_idx].ptr[idx] = value; + p->job->ibs[ib_idx].ptr[idx] = value; } /* diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 55179efccfcf..e9d88771783b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -121,7 +121,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) uint64_t *chunk_array_user; uint64_t *chunk_array; struct amdgpu_fpriv *fpriv = p->filp->driver_priv; - unsigned size; + unsigned size, num_ibs = 0; int i; int ret; @@ -186,7 +186,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) switch (p->chunks[i].chunk_id) { case AMDGPU_CHUNK_ID_IB: - p->num_ibs++; + ++num_ibs; break; case AMDGPU_CHUNK_ID_FENCE: @@ -211,16 +211,9 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } } - if (p->num_ibs == 0) { - ret = -EINVAL; + ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job); + if (ret) goto free_all_kdata; - } - - p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!p->ibs) { - ret = -ENOMEM; - goto free_all_kdata; - } kfree(chunk_array); return 0; @@ -414,7 +407,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) list_for_each_entry(e, &p->validated, tv.head) { struct reservation_object *resv = e->robj->tbo.resv; - r = amdgpu_sync_resv(p->adev, &p->ibs[0].sync, resv, p->filp); + r = amdgpu_sync_resv(p->adev, &p->job->ibs[0].sync, resv, p->filp); if (r) return r; @@ -477,10 +470,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); - if (parser->ibs) - for (i = 0; i < parser->num_ibs; i++) - amdgpu_ib_free(parser->adev, &parser->ibs[i]); - kfree(parser->ibs); + if (parser->job) + amdgpu_job_free(parser->job); amdgpu_bo_unref(&parser->uf.bo); amdgpu_bo_unref(&parser->uf_entry.robj); } @@ -497,7 +488,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (r) return r; - r = amdgpu_sync_fence(adev, &p->ibs[0].sync, vm->page_directory_fence); + r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, vm->page_directory_fence); if (r) return r; @@ -523,14 +514,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, return r; f = bo_va->last_pt_update; - r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); + r = amdgpu_sync_fence(adev, &p->job->ibs[0].sync, f); if (r) return r; } } - r = amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync); + r = amdgpu_vm_clear_invalids(adev, vm, &p->job->ibs[0].sync); if (amdgpu_vm_debug && p->bo_list) { /* Invalidate all BOs to test for userspace bugs */ @@ -556,8 +547,8 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, int i, r; /* Only for UVD/VCE VM emulation */ - for (i = 0; i < parser->num_ibs; i++) { - ring = parser->ibs[i].ring; + for (i = 0; i < parser->job->num_ibs; i++) { + ring = parser->job->ibs[i].ring; if (ring->funcs->parse_cs) { r = amdgpu_ring_parse_cs(ring, parser, i); if (r) @@ -590,14 +581,14 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, int i, j; int r; - for (i = 0, j = 0; i < parser->nchunks && j < parser->num_ibs; i++) { + for (i = 0, j = 0; i < parser->nchunks && j < parser->job->num_ibs; i++) { struct amdgpu_cs_chunk *chunk; struct amdgpu_ib *ib; struct drm_amdgpu_cs_chunk_ib *chunk_ib; struct amdgpu_ring *ring; chunk = &parser->chunks[i]; - ib = &parser->ibs[j]; + ib = &parser->job->ibs[j]; chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) @@ -666,7 +657,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, struct amdgpu_bo *gds = parser->bo_list->gds_obj; struct amdgpu_bo *gws = parser->bo_list->gws_obj; struct amdgpu_bo *oa = parser->bo_list->oa_obj; - struct amdgpu_ib *ib = &parser->ibs[0]; + struct amdgpu_ib *ib = &parser->job->ibs[0]; if (gds) { ib->gds_base = amdgpu_bo_gpu_offset(gds); @@ -683,7 +674,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, } /* wrap the last IB with user fence */ if (parser->uf.bo) { - struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1]; + struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; /* UVD & VCE fw doesn't support user fences */ if (ib->ring->type == AMDGPU_RING_TYPE_UVD || @@ -704,7 +695,7 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, int i, j, r; /* Add dependencies to first IB */ - ib = &p->ibs[0]; + ib = &p->job->ibs[0]; for (i = 0; i < p->nchunks; ++i) { struct drm_amdgpu_cs_chunk_dep *deps; struct amdgpu_cs_chunk *chunk; @@ -756,26 +747,19 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, static int amdgpu_cs_free_job(struct amdgpu_job *job) { - int i; - if (job->ibs) - for (i = 0; i < job->num_ibs; i++) - amdgpu_ib_free(job->adev, &job->ibs[i]); - kfree(job->ibs); - if (job->uf.bo) - amdgpu_bo_unref(&job->uf.bo); + amdgpu_job_free(job); return 0; } static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { - struct amdgpu_ring * ring = p->ibs->ring; + struct amdgpu_ring * ring = p->job->ibs->ring; struct amd_sched_fence *fence; struct amdgpu_job *job; - job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); - if (!job) - return -ENOMEM; + job = p->job; + p->job = NULL; job->base.sched = &ring->sched; job->base.s_entity = &p->ctx->rings[ring->idx].entity; @@ -783,11 +767,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, job->owner = p->filp; job->free_job = amdgpu_cs_free_job; - job->ibs = p->ibs; - job->num_ibs = p->num_ibs; - p->ibs = NULL; - p->num_ibs = 0; - if (job->ibs[job->num_ibs - 1].user) { job->uf = p->uf; job->ibs[job->num_ibs - 1].user = &job->uf; @@ -854,7 +833,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) goto out; - for (i = 0; i < parser.num_ibs; i++) + for (i = 0; i < parser.job->num_ibs; i++) trace_amdgpu_cs(&parser, i); r = amdgpu_cs_ib_vm_chunk(adev, &parser); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 76a1f823d983..10d098e33707 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -28,6 +28,39 @@ #include "amdgpu.h" #include "amdgpu_trace.h" +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job) +{ + size_t size = sizeof(struct amdgpu_job); + + if (num_ibs == 0) + return -EINVAL; + + size += sizeof(struct amdgpu_ib) * num_ibs; + + *job = kzalloc(size, GFP_KERNEL); + if (!*job) + return -ENOMEM; + + (*job)->adev = adev; + (*job)->ibs = (void *)&(*job)[1]; + (*job)->num_ibs = num_ibs; + (*job)->free_job = NULL; + + return 0; +} + +void amdgpu_job_free(struct amdgpu_job *job) +{ + unsigned i; + + for (i = 0; i < job->num_ibs; ++i) + amdgpu_ib_free(job->adev, &job->ibs[i]); + + amdgpu_bo_unref(&job->uf.bo); + /* TODO: Free the job structure here as well */ +} + static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) { struct amdgpu_job *job = to_amdgpu_job(sched_job); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index e7d2676839e1..f808b5a6e52b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -38,10 +38,10 @@ TRACE_EVENT(amdgpu_cs, TP_fast_assign( __entry->bo_list = p->bo_list; - __entry->ring = p->ibs[i].ring->idx; - __entry->dw = p->ibs[i].length_dw; + __entry->ring = p->job->ibs[i].ring->idx; + __entry->dw = p->job->ibs[i].length_dw; __entry->fences = amdgpu_fence_count_emitted( - p->ibs[i].ring); + p->job->ibs[i].ring); ), TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", __entry->bo_list, __entry->ring, __entry->dw, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 676ef699b6ad..f2bd2334bbe6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -702,7 +702,7 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) { - struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; + struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; int i, r; ctx->idx++; @@ -748,7 +748,7 @@ static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, static int amdgpu_uvd_cs_packets(struct amdgpu_uvd_cs_ctx *ctx, int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) { - struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; + struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; int r; for (ctx->idx = 0 ; ctx->idx < ib->length_dw; ) { @@ -790,7 +790,7 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) [0x00000003] = 2048, [0x00000004] = 0xFFFFFFFF, }; - struct amdgpu_ib *ib = &parser->ibs[ib_idx]; + struct amdgpu_ib *ib = &parser->job->ibs[ib_idx]; int r; if (ib->length_dw % 16) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 43aad45969a7..66b7bfafca24 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -603,7 +603,7 @@ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, */ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) { - struct amdgpu_ib *ib = &p->ibs[ib_idx]; + struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; unsigned fb_idx = 0, bs_idx = 0; int session_idx = -1; bool destroyed = false; -- cgit v1.2.3 From b07c60c0652c497af0c42c1278941f7c5a187fe9 Mon Sep 17 00:00:00 2001 From: Christian König Date: Sun, 31 Jan 2016 12:29:04 +0100 Subject: drm/amdgpu: move ring from IBs into job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't submit to multiple rings at the same time anyway. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 33 +++++++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 11 ++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 8 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 2 +- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 2 +- 14 files changed, 45 insertions(+), 44 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c23eea308991..dd6dd23fb3c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -771,7 +771,6 @@ struct amdgpu_ib { uint32_t length_dw; uint64_t gpu_addr; uint32_t *ptr; - struct amdgpu_ring *ring; struct amdgpu_fence *fence; struct amdgpu_user_fence *user; bool grabbed_vmid; @@ -1178,10 +1177,10 @@ struct amdgpu_gfx { unsigned ce_ram_size; }; -int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, +int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned size, struct amdgpu_ib *ib); void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib); -int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, +int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, struct amdgpu_ib *ib, void *owner); int amdgpu_ib_pool_init(struct amdgpu_device *adev); void amdgpu_ib_pool_fini(struct amdgpu_device *adev); @@ -1239,6 +1238,7 @@ struct amdgpu_cs_parser { struct amdgpu_job { struct amd_sched_job base; struct amdgpu_device *adev; + struct amdgpu_ring *ring; struct amdgpu_ib *ibs; uint32_t num_ibs; void *owner; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 8f3b72f5c91c..d928165bfc33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -542,26 +542,25 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, } static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, - struct amdgpu_cs_parser *parser) + struct amdgpu_cs_parser *p) { - struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; + struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; - struct amdgpu_ring *ring; + struct amdgpu_ring *ring = p->job->ring; int i, r; /* Only for UVD/VCE VM emulation */ - for (i = 0; i < parser->job->num_ibs; i++) { - ring = parser->job->ibs[i].ring; - if (ring->funcs->parse_cs) { - r = amdgpu_ring_parse_cs(ring, parser, i); + if (ring->funcs->parse_cs) { + for (i = 0; i < p->job->num_ibs; i++) { + r = amdgpu_ring_parse_cs(ring, p, i); if (r) return r; } } - r = amdgpu_bo_vm_update_pte(parser, vm); + r = amdgpu_bo_vm_update_pte(p, vm); if (!r) - amdgpu_cs_sync_rings(parser); + amdgpu_cs_sync_rings(p); return r; } @@ -603,6 +602,11 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, if (r) return r; + if (parser->job->ring && parser->job->ring != ring) + return -EINVAL; + + parser->job->ring = ring; + if (ring->funcs->parse_cs) { struct amdgpu_bo_va_mapping *m; struct amdgpu_bo *aobj = NULL; @@ -631,7 +635,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE; kptr += chunk_ib->va_start - offset; - r = amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib); + r = amdgpu_ib_get(adev, NULL, chunk_ib->ib_bytes, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); return r; @@ -640,7 +644,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); amdgpu_bo_kunmap(aobj); } else { - r = amdgpu_ib_get(ring, vm, 0, ib); + r = amdgpu_ib_get(adev, vm, 0, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); return r; @@ -680,8 +684,8 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; /* UVD & VCE fw doesn't support user fences */ - if (ib->ring->type == AMDGPU_RING_TYPE_UVD || - ib->ring->type == AMDGPU_RING_TYPE_VCE) + if (parser->job->ring->type == AMDGPU_RING_TYPE_UVD || + parser->job->ring->type == AMDGPU_RING_TYPE_VCE) return -EINVAL; ib->user = &parser->job->uf; @@ -757,7 +761,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job) static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { - struct amdgpu_ring * ring = p->job->ibs->ring; + struct amdgpu_ring *ring = p->job->ring; struct amd_sched_fence *fence; struct amdgpu_job *job; @@ -766,7 +770,6 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, job->base.sched = &ring->sched; job->base.s_entity = &p->ctx->rings[ring->idx].entity; - job->adev = p->adev; job->owner = p->filp; job->free_job = amdgpu_cs_free_job; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index b6737707eda2..47196ec593fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -55,10 +55,9 @@ static int amdgpu_debugfs_sa_init(struct amdgpu_device *adev); * suballocator. * Returns 0 on success, error on failure. */ -int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, +int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned size, struct amdgpu_ib *ib) { - struct amdgpu_device *adev = ring->adev; int r; if (size) { @@ -77,7 +76,6 @@ int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, amdgpu_sync_create(&ib->sync); - ib->ring = ring; ib->vm = vm; return 0; @@ -120,11 +118,11 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) * a CONST_IB), it will be put on the ring prior to the DE IB. Prior * to SI there was just a DE IB. */ -int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, +int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, struct amdgpu_ib *ibs, void *owner) { + struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = &ibs[0]; - struct amdgpu_ring *ring; struct amdgpu_ctx *ctx, *old_ctx; struct amdgpu_vm *vm; unsigned i; @@ -133,7 +131,6 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, if (num_ibs == 0) return -EINVAL; - ring = ibs->ring; ctx = ibs->ctx; vm = ibs->vm; @@ -178,7 +175,7 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, for (i = 0; i < num_ibs; ++i) { ib = &ibs[i]; - if (ib->ring != ring || ib->ctx != ctx || ib->vm != vm) { + if (ib->ctx != ctx || ib->vm != vm) { ring->current_ctx = old_ctx; amdgpu_ring_undo(ring); return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 10d098e33707..84453c1c4b07 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -70,7 +70,7 @@ static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) struct fence *fence = amdgpu_sync_get_fence(sync); if (fence == NULL && vm && !job->ibs->grabbed_vmid) { - struct amdgpu_ring *ring = job->ibs->ring; + struct amdgpu_ring *ring = job->ring; int r; r = amdgpu_vm_grab_id(vm, ring, sync, @@ -98,7 +98,7 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) } job = to_amdgpu_job(sched_job); trace_amdgpu_sched_run_job(job); - r = amdgpu_ib_schedule(job->adev, job->num_ibs, job->ibs, job->owner); + r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job->owner); if (r) { DRM_ERROR("Error scheduling IBs (%d)\n", r); goto err; @@ -142,6 +142,7 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, *f = fence_get(&job->base.s_fence->base); job->adev = adev; + job->ring = ring; job->ibs = ibs; job->num_ibs = num_ibs; job->owner = owner; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index f808b5a6e52b..9ca3735c563c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -38,10 +38,10 @@ TRACE_EVENT(amdgpu_cs, TP_fast_assign( __entry->bo_list = p->bo_list; - __entry->ring = p->job->ibs[i].ring->idx; + __entry->ring = p->job->ring->idx; __entry->dw = p->job->ibs[i].length_dw; __entry->fences = amdgpu_fence_count_emitted( - p->job->ibs[i].ring); + p->job->ring); ), TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", __entry->bo_list, __entry->ring, __entry->dw, @@ -65,7 +65,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, __entry->sched_job = &job->base; __entry->ib = job->ibs; __entry->fence = &job->base.s_fence->base; - __entry->ring_name = job->ibs[0].ring->name; + __entry->ring_name = job->ring->name; __entry->num_ibs = job->num_ibs; ), TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", @@ -90,7 +90,7 @@ TRACE_EVENT(amdgpu_sched_run_job, __entry->sched_job = &job->base; __entry->ib = job->ibs; __entry->fence = &job->base.s_fence->base; - __entry->ring_name = job->ibs[0].ring->name; + __entry->ring_name = job->ring->name; __entry->num_ibs = job->num_ibs; ), TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a7354798f087..6b63dcc3a773 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1030,7 +1030,7 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, if (!ib) return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, num_dw * 4, ib); + r = amdgpu_ib_get(adev, NULL, num_dw * 4, ib); if (r) { kfree(ib); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index f2bd2334bbe6..46f2bdb76d20 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -867,7 +867,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, r = -ENOMEM; goto err; } - r = amdgpu_ib_get(ring, NULL, 64, ib); + r = amdgpu_ib_get(adev, NULL, 64, ib); if (r) goto err1; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 66b7bfafca24..bcbe4167d7b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -377,7 +377,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); if (!ib) return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib); + r = amdgpu_ib_get(adev, NULL, ib_size_dw * 4, ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); kfree(ib); @@ -463,7 +463,7 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, if (!ib) return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib); + r = amdgpu_ib_get(adev, NULL, ib_size_dw * 4, ib); if (r) { kfree(ib); DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index d0acc9c0fd7f..b68642b47b7b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -355,7 +355,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, if (!ib) goto error; - r = amdgpu_ib_get(ring, NULL, 64, ib); + r = amdgpu_ib_get(adev, NULL, 64, ib); if (r) goto error_free; @@ -448,7 +448,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, if (!ib) return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, ndw * 4, ib); + r = amdgpu_ib_get(adev, NULL, ndw * 4, ib); if (r) { kfree(ib); return r; @@ -737,7 +737,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, if (!ib) return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, ndw * 4, ib); + r = amdgpu_ib_get(adev, NULL, ndw * 4, ib); if (r) { kfree(ib); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 1007a98f775b..f352d7559686 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -621,7 +621,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 40159d529e5b..5f57a820dacb 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -2631,7 +2631,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring) } WREG32(scratch, 0xCAFEDEAD); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err1; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 2ca36606c2ef..dbfa895c2ae5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -699,7 +699,7 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring) } WREG32(scratch, 0xCAFEDEAD); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err1; @@ -1171,7 +1171,7 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) /* allocate an indirect buffer to put the commands in */ memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, total_size, &ib); + r = amdgpu_ib_get(adev, NULL, total_size, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 5dfb13c56b90..49ec93cc7166 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -674,7 +674,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 999a169299f0..8fe150f02634 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -825,7 +825,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; -- cgit v1.2.3 From ec72b8006c1e69f633e3def3e3b3c7c6318d271c Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 1 Feb 2016 11:56:35 +0100 Subject: drm/amdgpu: directly return fence from ib_schedule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 10 ++++------ 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index dd6dd23fb3c7..387a26bba65a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1181,7 +1181,8 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned size, struct amdgpu_ib *ib); void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib); int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, - struct amdgpu_ib *ib, void *owner); + struct amdgpu_ib *ib, void *owner, + struct fence **f); int amdgpu_ib_pool_init(struct amdgpu_device *adev); void amdgpu_ib_pool_fini(struct amdgpu_device *adev); int amdgpu_ib_ring_tests(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 47196ec593fc..4b2c176b83f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -104,6 +104,7 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) * @num_ibs: number of IBs to schedule * @ibs: IB objects to schedule * @owner: owner for creating the fences + * @f: fence created during this submission * * Schedule an IB on the associated ring (all asics). * Returns 0 on success, error on failure. @@ -119,7 +120,8 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) * to SI there was just a DE IB. */ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, - struct amdgpu_ib *ibs, void *owner) + struct amdgpu_ib *ibs, void *owner, + struct fence **f) { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = &ibs[0]; @@ -200,6 +202,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, AMDGPU_FENCE_FLAG_64BIT); } + if (f) + *f = fence_get(&ib->fence->base); + amdgpu_ring_commit(ring); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 84453c1c4b07..cabb0fc28610 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -88,7 +88,7 @@ static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) { - struct amdgpu_fence *fence = NULL; + struct fence *fence = NULL; struct amdgpu_job *job; int r; @@ -98,21 +98,19 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) } job = to_amdgpu_job(sched_job); trace_amdgpu_sched_run_job(job); - r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job->owner); + r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, + job->owner, &fence); if (r) { DRM_ERROR("Error scheduling IBs (%d)\n", r); goto err; } - fence = job->ibs[job->num_ibs - 1].fence; - fence_get(&fence->base); - err: if (job->free_job) job->free_job(job); kfree(job); - return fence ? &fence->base : NULL; + return fence; } struct amd_sched_backend_ops amdgpu_sched_ops = { -- cgit v1.2.3 From d71518b5aa7c9c298ffbd12ddd23297e3373a37b Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 1 Feb 2016 12:20:25 +0100 Subject: drm/amdgpu: cleanup in kernel job submission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a job_alloc_with_ib helper and proper job submission. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 13 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 10 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 76 +++++++++++++-------------- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 34 +++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 37 +++++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 58 ++++++--------------- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 87 ++++++++++--------------------- 7 files changed, 111 insertions(+), 204 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 387a26bba65a..6cefde4aab49 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -797,14 +797,11 @@ extern struct amd_sched_backend_ops amdgpu_sched_ops; int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, struct amdgpu_job **job); +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job); void amdgpu_job_free(struct amdgpu_job *job); -int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, - struct amdgpu_ring *ring, - struct amdgpu_ib *ibs, - unsigned num_ibs, - int (*free_job)(struct amdgpu_job *), - void *owner, - struct fence **fence); +int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, + void *owner, struct fence **f); struct amdgpu_ring { struct amdgpu_device *adev; @@ -987,7 +984,6 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, uint64_t addr); void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va); -int amdgpu_vm_free_job(struct amdgpu_job *job); /* * context related structures @@ -1244,7 +1240,6 @@ struct amdgpu_job { uint32_t num_ibs; void *owner; struct amdgpu_user_fence uf; - int (*free_job)(struct amdgpu_job *job); }; #define to_amdgpu_job(sched_job) \ container_of((sched_job), struct amdgpu_job, base) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d928165bfc33..a5311623a489 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -752,12 +752,6 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, return 0; } -static int amdgpu_cs_free_job(struct amdgpu_job *job) -{ - amdgpu_job_free(job); - return 0; -} - static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) { @@ -771,12 +765,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, job->base.sched = &ring->sched; job->base.s_entity = &p->ctx->rings[ring->idx].entity; job->owner = p->filp; - job->free_job = amdgpu_cs_free_job; fence = amd_sched_fence_create(job->base.s_entity, p->filp); if (!fence) { - amdgpu_cs_free_job(job); - kfree(job); + amdgpu_job_free(job); return -ENOMEM; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index cabb0fc28610..bbdda727f89a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -45,11 +45,26 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->adev = adev; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; - (*job)->free_job = NULL; return 0; } +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job) +{ + int r; + + r = amdgpu_job_alloc(adev, 1, job); + if (r) + return r; + + r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]); + if (r) + kfree(*job); + + return r; +} + void amdgpu_job_free(struct amdgpu_job *job) { unsigned i; @@ -58,7 +73,27 @@ void amdgpu_job_free(struct amdgpu_job *job) amdgpu_ib_free(job->adev, &job->ibs[i]); amdgpu_bo_unref(&job->uf.bo); - /* TODO: Free the job structure here as well */ + kfree(job); +} + +int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, + void *owner, struct fence **f) +{ + struct amdgpu_device *adev = job->adev; + + job->ring = ring; + job->base.sched = &ring->sched; + job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; + job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); + if (!job->base.s_fence) + return -ENOMEM; + + *f = fence_get(&job->base.s_fence->base); + + job->owner = owner; + amd_sched_entity_push_job(&job->base); + + return 0; } static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) @@ -106,10 +141,7 @@ static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) } err: - if (job->free_job) - job->free_job(job); - - kfree(job); + amdgpu_job_free(job); return fence; } @@ -117,35 +149,3 @@ struct amd_sched_backend_ops amdgpu_sched_ops = { .dependency = amdgpu_sched_dependency, .run_job = amdgpu_sched_run_job, }; - -int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, - struct amdgpu_ring *ring, - struct amdgpu_ib *ibs, - unsigned num_ibs, - int (*free_job)(struct amdgpu_job *), - void *owner, - struct fence **f) -{ - struct amdgpu_job *job = - kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); - if (!job) - return -ENOMEM; - job->base.sched = &ring->sched; - job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; - job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); - if (!job->base.s_fence) { - kfree(job); - return -ENOMEM; - } - *f = fence_get(&job->base.s_fence->base); - - job->adev = adev; - job->ring = ring; - job->ibs = ibs; - job->num_ibs = num_ibs; - job->owner = owner; - job->free_job = free_job; - amd_sched_entity_push_job(&job->base); - - return 0; -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 6b63dcc3a773..21c1a18c6d48 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1012,9 +1012,10 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, struct fence **fence) { struct amdgpu_device *adev = ring->adev; + struct amdgpu_job *job; + uint32_t max_bytes; unsigned num_loops, num_dw; - struct amdgpu_ib *ib; unsigned i; int r; @@ -1026,20 +1027,12 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, while (num_dw & 0x7) num_dw++; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(adev, NULL, num_dw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); + if (r) return r; - } - - ib->length_dw = 0; if (resv) { - r = amdgpu_sync_resv(adev, &ib->sync, resv, + r = amdgpu_sync_resv(adev, &job->ibs[0].sync, resv, AMDGPU_FENCE_OWNER_UNDEFINED); if (r) { DRM_ERROR("sync failed (%d).\n", r); @@ -1050,27 +1043,24 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, for (i = 0; i < num_loops; i++) { uint32_t cur_size_in_bytes = min(byte_count, max_bytes); - amdgpu_emit_copy_buffer(adev, ib, src_offset, dst_offset, - cur_size_in_bytes); + amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset, + dst_offset, cur_size_in_bytes); src_offset += cur_size_in_bytes; dst_offset += cur_size_in_bytes; byte_count -= cur_size_in_bytes; } - amdgpu_ring_pad_ib(ring, ib); - WARN_ON(ib->length_dw > num_dw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - fence); + amdgpu_ring_pad_ib(ring, &job->ibs[0]); + WARN_ON(job->ibs[0].length_dw > num_dw); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, fence); if (r) goto error_free; return 0; + error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 46f2bdb76d20..4e98be8b29fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -823,14 +823,6 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) return 0; } -static int amdgpu_uvd_free_job( - struct amdgpu_job *job) -{ - amdgpu_ib_free(job->adev, job->ibs); - kfree(job->ibs); - return 0; -} - static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, struct fence **fence) @@ -838,7 +830,8 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct ttm_validate_buffer tv; struct ww_acquire_ctx ticket; struct list_head head; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; struct amdgpu_device *adev = ring->adev; uint64_t addr; @@ -862,15 +855,12 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); if (r) goto err; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) { - r = -ENOMEM; - goto err; - } - r = amdgpu_ib_get(adev, NULL, 64, ib); + + r = amdgpu_job_alloc_with_ib(adev, 64, &job); if (r) - goto err1; + goto err; + ib = &job->ibs[0]; addr = amdgpu_bo_gpu_offset(bo); ib->ptr[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0); ib->ptr[1] = addr; @@ -882,12 +872,9 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, ib->ptr[i] = PACKET2(0); ib->length_dw = 16; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_uvd_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, &f); if (r) - goto err2; + goto err_free; ttm_eu_fence_buffer_objects(&ticket, &head, f); @@ -897,10 +884,10 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, fence_put(f); return 0; -err2: - amdgpu_ib_free(ring->adev, ib); -err1: - kfree(ib); + +err_free: + amdgpu_job_free(job); + err: ttm_eu_backoff_reservation(&ticket, &head); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index bcbe4167d7b1..66e97ea0e6b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -346,14 +346,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) } } -static int amdgpu_vce_free_job( - struct amdgpu_job *job) -{ - amdgpu_ib_free(job->adev, job->ibs); - kfree(job->ibs); - return 0; -} - /** * amdgpu_vce_get_create_msg - generate a VCE create msg * @@ -368,21 +360,17 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct fence **fence) { const unsigned ib_size_dw = 1024; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; - struct amdgpu_device *adev = ring->adev; uint64_t dummy; int i, r; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - r = amdgpu_ib_get(adev, NULL, ib_size_dw * 4, ib); - if (r) { - DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); - kfree(ib); + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) return r; - } + + ib = &job->ibs[0]; dummy = ib->gpu_addr + 1024; @@ -423,19 +411,16 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vce_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, &f); if (r) goto err; if (fence) *fence = fence_get(f); fence_put(f); return 0; + err: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } @@ -453,23 +438,17 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, struct fence **fence) { const unsigned ib_size_dw = 1024; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; - struct amdgpu_device *adev = ring->adev; uint64_t dummy; int i, r; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(adev, NULL, ib_size_dw * 4, ib); - if (r) { - kfree(ib); - DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) return r; - } + ib = &job->ibs[0]; dummy = ib->gpu_addr + 1024; /* stitch together an VCE destroy msg */ @@ -489,19 +468,16 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vce_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_UNDEFINED, &f); if (r) goto err; if (fence) *fence = fence_get(f); fence_put(f); return 0; + err: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b68642b47b7b..fb003089f73c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -313,15 +313,6 @@ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, } } -int amdgpu_vm_free_job(struct amdgpu_job *job) -{ - int i; - for (i = 0; i < job->num_ibs; i++) - amdgpu_ib_free(job->adev, &job->ibs[i]); - kfree(job->ibs); - return 0; -} - /** * amdgpu_vm_clear_bo - initially clear the page dir/table * @@ -335,7 +326,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, { struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; struct fence *fence = NULL; - struct amdgpu_ib *ib; + struct amdgpu_job *job; unsigned entries; uint64_t addr; int r; @@ -351,32 +342,25 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, addr = amdgpu_bo_gpu_offset(bo); entries = amdgpu_bo_size(bo) / 8; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) + r = amdgpu_job_alloc_with_ib(adev, 64, &job); + if (r) goto error; - r = amdgpu_ib_get(adev, NULL, 64, ib); + amdgpu_vm_update_pages(adev, NULL, 0, &job->ibs[0], addr, 0, entries, + 0, 0); + amdgpu_ring_pad_ib(ring, &job->ibs[0]); + + WARN_ON(job->ibs[0].length_dw > 64); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_VM, &fence); if (r) goto error_free; - ib->length_dw = 0; - - amdgpu_vm_update_pages(adev, NULL, 0, ib, addr, 0, entries, 0, 0); - amdgpu_ring_pad_ib(ring, ib); - - WARN_ON(ib->length_dw > 64); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &fence); - if (!r) - amdgpu_bo_fence(bo, fence, true); + amdgpu_bo_fence(bo, fence, true); fence_put(fence); return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); error: return r; @@ -433,6 +417,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; uint64_t last_pde = ~0, last_pt = ~0; unsigned count = 0, pt_idx, ndw; + struct amdgpu_job *job; struct amdgpu_ib *ib; struct fence *fence = NULL; @@ -444,16 +429,11 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, /* assume the worst case */ ndw += vm->max_pde_used * 6; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(adev, NULL, ndw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); + if (r) return r; - } - ib->length_dw = 0; + + ib = &job->ibs[0]; /* walk over the address space and update the page directory */ for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { @@ -495,10 +475,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, amdgpu_ring_pad_ib(ring, ib); amdgpu_sync_resv(adev, &ib->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM); WARN_ON(ib->length_dw > ndw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &fence); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_VM, &fence); if (r) goto error_free; @@ -506,18 +483,15 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, fence_put(vm->page_directory_fence); vm->page_directory_fence = fence_get(fence); fence_put(fence); - } - if (ib->length_dw == 0) { - amdgpu_ib_free(adev, ib); - kfree(ib); + } else { + amdgpu_job_free(job); } return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } @@ -695,6 +669,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; void *owner = AMDGPU_FENCE_OWNER_VM; unsigned nptes, ncmds, ndw; + struct amdgpu_job *job; struct amdgpu_ib *ib; struct fence *f = NULL; int r; @@ -733,15 +708,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ndw += 2 * 10; } - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(adev, NULL, ndw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); + if (r) return r; - } + + ib = &job->ibs[0]; r = amdgpu_sync_resv(adev, &ib->sync, vm->page_directory->tbo.resv, owner); @@ -757,10 +728,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, amdgpu_ring_pad_ib(ring, ib); WARN_ON(ib->length_dw > ndw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &f); + r = amdgpu_job_submit(job, ring, AMDGPU_FENCE_OWNER_VM, &f); if (r) goto error_free; @@ -773,8 +741,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } -- cgit v1.2.3 From 0856cab1a6298d9cbf037dc683ce514cadb28040 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 1 Feb 2016 12:31:01 +0100 Subject: drm/amdgpu: rename amdgpu_sched.c to amdgpu_job.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That's probably a better matching name. Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 151 ++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 151 ------------------------------ 3 files changed, 152 insertions(+), 152 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c delete mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c') diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index dceebbbf94b0..c7fcdcedaadb 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -93,7 +93,7 @@ amdgpu-y += amdgpu_cgs.o amdgpu-y += \ ../scheduler/gpu_scheduler.o \ ../scheduler/sched_fence.o \ - amdgpu_sched.o + amdgpu_job.o # ACP componet ifneq ($(CONFIG_DRM_AMD_ACP),) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c new file mode 100644 index 000000000000..6f3e757e056e --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -0,0 +1,151 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * + */ +#include +#include +#include +#include +#include "amdgpu.h" +#include "amdgpu_trace.h" + +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job) +{ + size_t size = sizeof(struct amdgpu_job); + + if (num_ibs == 0) + return -EINVAL; + + size += sizeof(struct amdgpu_ib) * num_ibs; + + *job = kzalloc(size, GFP_KERNEL); + if (!*job) + return -ENOMEM; + + (*job)->adev = adev; + (*job)->ibs = (void *)&(*job)[1]; + (*job)->num_ibs = num_ibs; + + return 0; +} + +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job) +{ + int r; + + r = amdgpu_job_alloc(adev, 1, job); + if (r) + return r; + + r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]); + if (r) + kfree(*job); + + return r; +} + +void amdgpu_job_free(struct amdgpu_job *job) +{ + unsigned i; + + for (i = 0; i < job->num_ibs; ++i) + amdgpu_ib_free(job->adev, &job->ibs[i]); + + amdgpu_bo_unref(&job->uf.bo); + kfree(job); +} + +int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, + void *owner, struct fence **f) +{ + struct amdgpu_device *adev = job->adev; + + job->ring = ring; + job->base.sched = &ring->sched; + job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; + job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); + if (!job->base.s_fence) + return -ENOMEM; + + *f = fence_get(&job->base.s_fence->base); + + job->owner = owner; + amd_sched_entity_push_job(&job->base); + + return 0; +} + +static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) +{ + struct amdgpu_job *job = to_amdgpu_job(sched_job); + struct amdgpu_sync *sync = &job->ibs->sync; + struct amdgpu_vm *vm = job->ibs->vm; + + struct fence *fence = amdgpu_sync_get_fence(sync); + + if (fence == NULL && vm && !job->ibs->grabbed_vmid) { + struct amdgpu_ring *ring = job->ring; + int r; + + r = amdgpu_vm_grab_id(vm, ring, sync, + &job->base.s_fence->base); + if (r) + DRM_ERROR("Error getting VM ID (%d)\n", r); + else + job->ibs->grabbed_vmid = true; + + fence = amdgpu_sync_get_fence(sync); + } + + return fence; +} + +static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job) +{ + struct fence *fence = NULL; + struct amdgpu_job *job; + int r; + + if (!sched_job) { + DRM_ERROR("job is null\n"); + return NULL; + } + job = to_amdgpu_job(sched_job); + trace_amdgpu_sched_run_job(job); + r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, + job->owner, &fence); + if (r) { + DRM_ERROR("Error scheduling IBs (%d)\n", r); + goto err; + } + +err: + amdgpu_job_free(job); + return fence; +} + +struct amd_sched_backend_ops amdgpu_sched_ops = { + .dependency = amdgpu_job_dependency, + .run_job = amdgpu_job_run, +}; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c deleted file mode 100644 index bbdda727f89a..000000000000 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * - */ -#include -#include -#include -#include -#include "amdgpu.h" -#include "amdgpu_trace.h" - -int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, - struct amdgpu_job **job) -{ - size_t size = sizeof(struct amdgpu_job); - - if (num_ibs == 0) - return -EINVAL; - - size += sizeof(struct amdgpu_ib) * num_ibs; - - *job = kzalloc(size, GFP_KERNEL); - if (!*job) - return -ENOMEM; - - (*job)->adev = adev; - (*job)->ibs = (void *)&(*job)[1]; - (*job)->num_ibs = num_ibs; - - return 0; -} - -int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, - struct amdgpu_job **job) -{ - int r; - - r = amdgpu_job_alloc(adev, 1, job); - if (r) - return r; - - r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]); - if (r) - kfree(*job); - - return r; -} - -void amdgpu_job_free(struct amdgpu_job *job) -{ - unsigned i; - - for (i = 0; i < job->num_ibs; ++i) - amdgpu_ib_free(job->adev, &job->ibs[i]); - - amdgpu_bo_unref(&job->uf.bo); - kfree(job); -} - -int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, - void *owner, struct fence **f) -{ - struct amdgpu_device *adev = job->adev; - - job->ring = ring; - job->base.sched = &ring->sched; - job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; - job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); - if (!job->base.s_fence) - return -ENOMEM; - - *f = fence_get(&job->base.s_fence->base); - - job->owner = owner; - amd_sched_entity_push_job(&job->base); - - return 0; -} - -static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) -{ - struct amdgpu_job *job = to_amdgpu_job(sched_job); - struct amdgpu_sync *sync = &job->ibs->sync; - struct amdgpu_vm *vm = job->ibs->vm; - - struct fence *fence = amdgpu_sync_get_fence(sync); - - if (fence == NULL && vm && !job->ibs->grabbed_vmid) { - struct amdgpu_ring *ring = job->ring; - int r; - - r = amdgpu_vm_grab_id(vm, ring, sync, - &job->base.s_fence->base); - if (r) - DRM_ERROR("Error getting VM ID (%d)\n", r); - else - job->ibs->grabbed_vmid = true; - - fence = amdgpu_sync_get_fence(sync); - } - - return fence; -} - -static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) -{ - struct fence *fence = NULL; - struct amdgpu_job *job; - int r; - - if (!sched_job) { - DRM_ERROR("job is null\n"); - return NULL; - } - job = to_amdgpu_job(sched_job); - trace_amdgpu_sched_run_job(job); - r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, - job->owner, &fence); - if (r) { - DRM_ERROR("Error scheduling IBs (%d)\n", r); - goto err; - } - -err: - amdgpu_job_free(job); - return fence; -} - -struct amd_sched_backend_ops amdgpu_sched_ops = { - .dependency = amdgpu_sched_dependency, - .run_job = amdgpu_sched_run_job, -}; -- cgit v1.2.3