mirror of
https://github.com/torvalds/linux.git
synced 2026-10-30 14:06:03 +01:00
drm/amdgpu: require a job to schedule an IB
Remove the old direct submit path. This simplifies the code. v2: remove more local variables Reviewed-by: Jesse Zhang <jesse.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
451bfc778a
commit
c06d09d09c
|
|
@ -727,7 +727,7 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
|
|||
job->vmid = vmid;
|
||||
job->num_ibs = 1;
|
||||
|
||||
ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
|
||||
ret = amdgpu_ib_schedule(ring, job, &f);
|
||||
|
||||
if (ret) {
|
||||
drm_err(adev_to_drm(adev), "failed to schedule IB.\n");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
* Christian König
|
||||
*/
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <drm/amdgpu_drm.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
|
|
@ -102,11 +100,9 @@ void amdgpu_ib_free(struct amdgpu_ib *ib, struct dma_fence *f)
|
|||
/**
|
||||
* amdgpu_ib_schedule - schedule an IB (Indirect Buffer) on the ring
|
||||
*
|
||||
* @ring: ring index the IB is associated with
|
||||
* @num_ibs: number of IBs to schedule
|
||||
* @ibs: IB objects to schedule
|
||||
* @ring: ring structure the IB is associated with
|
||||
* @job: job to schedule
|
||||
* @f: fence created during this submission
|
||||
* @f: fence referenced during this submission
|
||||
*
|
||||
* Schedule an IB on the associated ring (all asics).
|
||||
* Returns 0 on success, error on failure.
|
||||
|
|
@ -121,92 +117,71 @@ void amdgpu_ib_free(struct amdgpu_ib *ib, struct dma_fence *f)
|
|||
* 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_ring *ring, unsigned int num_ibs,
|
||||
struct amdgpu_ib *ibs, struct amdgpu_job *job,
|
||||
int amdgpu_ib_schedule(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
||||
struct dma_fence **f)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_ib *ib = &ibs[0];
|
||||
struct amdgpu_ib *ib;
|
||||
struct dma_fence *tmp = NULL;
|
||||
struct amdgpu_fence *af;
|
||||
struct amdgpu_fence *vm_af;
|
||||
bool need_ctx_switch;
|
||||
bool emit_spm_needed = false;
|
||||
bool emit_gds_needed = false;
|
||||
struct amdgpu_vm *vm;
|
||||
uint64_t fence_ctx;
|
||||
uint32_t status = 0, alloc_size;
|
||||
unsigned int fence_flags = 0;
|
||||
bool secure, init_shadow;
|
||||
u64 shadow_va, csa_va, gds_va;
|
||||
int vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
bool secure;
|
||||
unsigned int vmid;
|
||||
bool need_pipe_sync = false;
|
||||
unsigned int cond_exec;
|
||||
unsigned int i;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
if (num_ibs == 0)
|
||||
if (!job || !job->num_ibs)
|
||||
return -EINVAL;
|
||||
|
||||
/* ring tests don't use a job */
|
||||
if (job) {
|
||||
vm = job->vm;
|
||||
fence_ctx = job->base.s_fence ?
|
||||
job->base.s_fence->finished.context : 0;
|
||||
shadow_va = job->shadow_va;
|
||||
csa_va = job->csa_va;
|
||||
gds_va = job->gds_va;
|
||||
init_shadow = job->init_shadow;
|
||||
af = job->hw_fence;
|
||||
/* Save the context of the job for reset handling.
|
||||
* The driver needs this so it can skip the ring
|
||||
* contents for guilty contexts.
|
||||
*/
|
||||
af->context = fence_ctx;
|
||||
/* the vm fence is also part of the job's context */
|
||||
job->hw_vm_fence->context = fence_ctx;
|
||||
} else {
|
||||
vm = NULL;
|
||||
fence_ctx = 0;
|
||||
shadow_va = 0;
|
||||
csa_va = 0;
|
||||
gds_va = 0;
|
||||
init_shadow = false;
|
||||
af = kzalloc_obj(*af, GFP_ATOMIC);
|
||||
if (!af)
|
||||
return -ENOMEM;
|
||||
}
|
||||
vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
ib = &job->ibs[0];
|
||||
fence_ctx = job->base.s_fence ?
|
||||
job->base.s_fence->finished.context : 0;
|
||||
af = job->hw_fence;
|
||||
vm_af = job->hw_vm_fence;
|
||||
/* Save the context of the job for reset handling.
|
||||
* The driver needs this so it can skip the ring
|
||||
* contents for guilty contexts.
|
||||
*/
|
||||
af->context = fence_ctx;
|
||||
/* the vm fence is also part of the job's context */
|
||||
vm_af->context = fence_ctx;
|
||||
|
||||
if (!ring->sched.ready) {
|
||||
dev_err(adev->dev, "couldn't schedule ib on ring <%s>\n", ring->name);
|
||||
r = -EINVAL;
|
||||
goto free_fence;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vm && !job->vmid) {
|
||||
if (job->vm && !job->vmid) {
|
||||
dev_err(adev->dev, "VM IB without ID\n");
|
||||
r = -EINVAL;
|
||||
goto free_fence;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ib->flags & AMDGPU_IB_FLAGS_SECURE) &&
|
||||
(!ring->funcs->secure_submission_supported)) {
|
||||
dev_err(adev->dev, "secure submissions not supported on ring <%s>\n", ring->name);
|
||||
r = -EINVAL;
|
||||
goto free_fence;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
alloc_size = ring->funcs->emit_frame_size + num_ibs *
|
||||
alloc_size = ring->funcs->emit_frame_size + job->num_ibs *
|
||||
ring->funcs->emit_ib_size;
|
||||
|
||||
r = amdgpu_ring_alloc(ring, alloc_size);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "scheduling IB failed (%d).\n", r);
|
||||
goto free_fence;
|
||||
return r;
|
||||
}
|
||||
|
||||
need_ctx_switch = ring->current_ctx != fence_ctx;
|
||||
if (ring->funcs->emit_pipeline_sync && job &&
|
||||
if (ring->funcs->emit_pipeline_sync &&
|
||||
((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) ||
|
||||
need_ctx_switch || amdgpu_vm_need_pipeline_sync(ring, job))) {
|
||||
|
||||
|
|
@ -218,15 +193,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
dma_fence_put(tmp);
|
||||
}
|
||||
|
||||
if (job) {
|
||||
vm_af = job->hw_vm_fence;
|
||||
/* VM sequence */
|
||||
vm_af->ib_wptr = ring->wptr;
|
||||
amdgpu_vm_flush(ring, job, &need_pipe_sync, &emit_spm_needed,
|
||||
&emit_gds_needed);
|
||||
vm_af->ib_dw_size =
|
||||
amdgpu_ring_get_dw_distance(ring, vm_af->ib_wptr, ring->wptr);
|
||||
}
|
||||
/* VM sequence */
|
||||
vm_af->ib_wptr = ring->wptr;
|
||||
amdgpu_vm_flush(ring, job, &need_pipe_sync, &emit_spm_needed,
|
||||
&emit_gds_needed);
|
||||
vm_af->ib_dw_size =
|
||||
amdgpu_ring_get_dw_distance(ring, vm_af->ib_wptr, ring->wptr);
|
||||
|
||||
/* IB sequence */
|
||||
af->ib_wptr = ring->wptr;
|
||||
|
|
@ -256,8 +228,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
ring->funcs->emit_wave_limit(ring, true);
|
||||
|
||||
if (ring->funcs->emit_gfx_shadow && adev->gfx.cp_gfx_shadow)
|
||||
amdgpu_ring_emit_gfx_shadow(ring, shadow_va, csa_va, gds_va,
|
||||
init_shadow, vmid);
|
||||
amdgpu_ring_emit_gfx_shadow(ring, job->shadow_va, job->csa_va, job->gds_va,
|
||||
job->init_shadow, vmid);
|
||||
|
||||
if (ring->funcs->init_cond_exec)
|
||||
cond_exec = amdgpu_ring_init_cond_exec(ring,
|
||||
|
|
@ -271,7 +243,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
if (need_ctx_switch)
|
||||
status |= AMDGPU_HAVE_CTX_SWITCH;
|
||||
|
||||
if (job && ring->funcs->emit_cntxcntl) {
|
||||
if (ring->funcs->emit_cntxcntl) {
|
||||
status |= job->preamble_status;
|
||||
status |= job->preemption_status;
|
||||
amdgpu_ring_emit_cntxcntl(ring, status);
|
||||
|
|
@ -280,15 +252,15 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
/* Setup initial TMZiness and send it off.
|
||||
*/
|
||||
secure = false;
|
||||
if (job && ring->funcs->emit_frame_cntl) {
|
||||
if (ring->funcs->emit_frame_cntl) {
|
||||
secure = ib->flags & AMDGPU_IB_FLAGS_SECURE;
|
||||
amdgpu_ring_emit_frame_cntl(ring, true, secure);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_ibs; ++i) {
|
||||
ib = &ibs[i];
|
||||
for (i = 0; i < job->num_ibs; ++i) {
|
||||
ib = &job->ibs[i];
|
||||
|
||||
if (job && ring->funcs->emit_frame_cntl) {
|
||||
if (ring->funcs->emit_frame_cntl) {
|
||||
if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) {
|
||||
amdgpu_ring_emit_frame_cntl(ring, false, secure);
|
||||
secure = !secure;
|
||||
|
|
@ -300,7 +272,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
status &= ~AMDGPU_HAVE_CTX_SWITCH;
|
||||
}
|
||||
|
||||
if (job && ring->funcs->emit_frame_cntl)
|
||||
if (ring->funcs->emit_frame_cntl)
|
||||
amdgpu_ring_emit_frame_cntl(ring, false, secure);
|
||||
|
||||
amdgpu_device_invalidate_hdp(adev, ring);
|
||||
|
|
@ -312,7 +284,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;
|
||||
|
||||
/* wrap the last IB with fence */
|
||||
if (job && job->uf_addr) {
|
||||
if (job->uf_addr) {
|
||||
amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
|
||||
fence_flags | AMDGPU_FENCE_FLAG_64BIT);
|
||||
}
|
||||
|
|
@ -326,8 +298,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
amdgpu_fence_emit(ring, af, fence_flags);
|
||||
*f = &af->base;
|
||||
/* get a ref for the job */
|
||||
if (job)
|
||||
dma_fence_get(*f);
|
||||
dma_fence_get(*f);
|
||||
|
||||
if (ring->funcs->insert_end)
|
||||
ring->funcs->insert_end(ring);
|
||||
|
|
@ -335,7 +306,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
amdgpu_ring_patch_cond_exec(ring, cond_exec);
|
||||
|
||||
ring->current_ctx = fence_ctx;
|
||||
if (job && ring->funcs->emit_switch_buffer)
|
||||
if (ring->funcs->emit_switch_buffer)
|
||||
amdgpu_ring_emit_switch_buffer(ring);
|
||||
|
||||
if (ring->funcs->emit_wave_limit &&
|
||||
|
|
@ -349,11 +320,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
|
|||
amdgpu_ring_commit(ring);
|
||||
|
||||
return 0;
|
||||
|
||||
free_fence:
|
||||
if (!job)
|
||||
kfree(af);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ int amdgpu_job_submit_direct(struct amdgpu_job *job, struct amdgpu_ring *ring,
|
|||
int r;
|
||||
|
||||
job->base.sched = &ring->sched;
|
||||
r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job, fence);
|
||||
r = amdgpu_ib_schedule(ring, job, fence);
|
||||
|
||||
if (r)
|
||||
return r;
|
||||
|
|
@ -457,8 +457,7 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
|||
dev_dbg(adev->dev, "Skip scheduling IBs in ring(%s)",
|
||||
ring->name);
|
||||
} else {
|
||||
r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job,
|
||||
&fence);
|
||||
r = amdgpu_ib_schedule(ring, job, &fence);
|
||||
if (r)
|
||||
dev_err(adev->dev,
|
||||
"Error scheduling IBs (%d) in ring(%s)", r,
|
||||
|
|
|
|||
|
|
@ -578,8 +578,7 @@ int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
enum amdgpu_ib_pool_type pool,
|
||||
struct amdgpu_ib *ib);
|
||||
void amdgpu_ib_free(struct amdgpu_ib *ib, struct dma_fence *f);
|
||||
int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
||||
struct amdgpu_ib *ibs, struct amdgpu_job *job,
|
||||
int amdgpu_ib_schedule(struct amdgpu_ring *ring, struct amdgpu_job *job,
|
||||
struct dma_fence **f);
|
||||
int amdgpu_ib_pool_init(struct amdgpu_device *adev);
|
||||
void amdgpu_ib_pool_fini(struct amdgpu_device *adev);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user