drm/amdgpu: switch job hw_fence to amdgpu_fence
commit ebe43542702c3d15d1a1d95e8e13b1b54076f05a upstream.
Use the amdgpu fence container so we can store additional
data in the fence. This also fixes the start_time handling
for MCBP since we were casting the fence to an amdgpu_fence
and it wasn't.
Fixes: 3f4c175d62
("drm/amdgpu: MCBP based on DRM scheduler (v9)")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit bf1cd14f9e2e1fdf981eed273ddd595863f5288c)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a5d7cc1647
commit
8302adf60a
@@ -1890,7 +1890,7 @@ no_preempt:
|
||||
continue;
|
||||
}
|
||||
job = to_amdgpu_job(s_job);
|
||||
if (preempted && (&job->hw_fence) == fence)
|
||||
if (preempted && (&job->hw_fence.base) == fence)
|
||||
/* mark the job as preempted */
|
||||
job->preemption_status |= AMDGPU_IB_PREEMPTED;
|
||||
}
|
||||
|
@@ -5367,7 +5367,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
|
||||
*
|
||||
* job->base holds a reference to parent fence
|
||||
*/
|
||||
if (job && dma_fence_is_signaled(&job->hw_fence)) {
|
||||
if (job && dma_fence_is_signaled(&job->hw_fence.base)) {
|
||||
job_signaled = true;
|
||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||
goto skip_hw_reset;
|
||||
|
@@ -41,22 +41,6 @@
|
||||
#include "amdgpu_trace.h"
|
||||
#include "amdgpu_reset.h"
|
||||
|
||||
/*
|
||||
* Fences mark an event in the GPUs pipeline and are used
|
||||
* for GPU/CPU synchronization. When the fence is written,
|
||||
* it is expected that all buffers associated with that fence
|
||||
* are no longer in use by the associated ring on the GPU and
|
||||
* that the relevant GPU caches have been flushed.
|
||||
*/
|
||||
|
||||
struct amdgpu_fence {
|
||||
struct dma_fence base;
|
||||
|
||||
/* RB, DMA, etc. */
|
||||
struct amdgpu_ring *ring;
|
||||
ktime_t start_timestamp;
|
||||
};
|
||||
|
||||
static struct kmem_cache *amdgpu_fence_slab;
|
||||
|
||||
int amdgpu_fence_slab_init(void)
|
||||
@@ -153,12 +137,12 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd
|
||||
am_fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_ATOMIC);
|
||||
if (am_fence == NULL)
|
||||
return -ENOMEM;
|
||||
fence = &am_fence->base;
|
||||
am_fence->ring = ring;
|
||||
} else {
|
||||
/* take use of job-embedded fence */
|
||||
fence = &job->hw_fence;
|
||||
am_fence = &job->hw_fence;
|
||||
}
|
||||
fence = &am_fence->base;
|
||||
am_fence->ring = ring;
|
||||
|
||||
seq = ++ring->fence_drv.sync_seq;
|
||||
if (job && job->job_run_counter) {
|
||||
@@ -719,7 +703,7 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)
|
||||
* it right here or we won't be able to track them in fence_drv
|
||||
* and they will remain unsignaled during sa_bo free.
|
||||
*/
|
||||
job = container_of(old, struct amdgpu_job, hw_fence);
|
||||
job = container_of(old, struct amdgpu_job, hw_fence.base);
|
||||
if (!job->base.s_fence && !dma_fence_is_signaled(old))
|
||||
dma_fence_signal(old);
|
||||
RCU_INIT_POINTER(*ptr, NULL);
|
||||
@@ -781,7 +765,7 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f)
|
||||
|
||||
static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f)
|
||||
{
|
||||
struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence);
|
||||
struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
|
||||
|
||||
return (const char *)to_amdgpu_ring(job->base.sched)->name;
|
||||
}
|
||||
@@ -811,7 +795,7 @@ static bool amdgpu_fence_enable_signaling(struct dma_fence *f)
|
||||
*/
|
||||
static bool amdgpu_job_fence_enable_signaling(struct dma_fence *f)
|
||||
{
|
||||
struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence);
|
||||
struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
|
||||
|
||||
if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer))
|
||||
amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched));
|
||||
@@ -846,7 +830,7 @@ static void amdgpu_job_fence_free(struct rcu_head *rcu)
|
||||
struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
|
||||
|
||||
/* free job if fence has a parent job */
|
||||
kfree(container_of(f, struct amdgpu_job, hw_fence));
|
||||
kfree(container_of(f, struct amdgpu_job, hw_fence.base));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -165,8 +165,8 @@ void amdgpu_job_free_resources(struct amdgpu_job *job)
|
||||
/* Check if any fences where initialized */
|
||||
if (job->base.s_fence && job->base.s_fence->finished.ops)
|
||||
f = &job->base.s_fence->finished;
|
||||
else if (job->hw_fence.ops)
|
||||
f = &job->hw_fence;
|
||||
else if (job->hw_fence.base.ops)
|
||||
f = &job->hw_fence.base;
|
||||
else
|
||||
f = NULL;
|
||||
|
||||
@@ -183,10 +183,10 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
||||
amdgpu_sync_free(&job->explicit_sync);
|
||||
|
||||
/* only put the hw fence if has embedded fence */
|
||||
if (!job->hw_fence.ops)
|
||||
if (!job->hw_fence.base.ops)
|
||||
kfree(job);
|
||||
else
|
||||
dma_fence_put(&job->hw_fence);
|
||||
dma_fence_put(&job->hw_fence.base);
|
||||
}
|
||||
|
||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
||||
@@ -215,10 +215,10 @@ void amdgpu_job_free(struct amdgpu_job *job)
|
||||
if (job->gang_submit != &job->base.s_fence->scheduled)
|
||||
dma_fence_put(job->gang_submit);
|
||||
|
||||
if (!job->hw_fence.ops)
|
||||
if (!job->hw_fence.base.ops)
|
||||
kfree(job);
|
||||
else
|
||||
dma_fence_put(&job->hw_fence);
|
||||
dma_fence_put(&job->hw_fence.base);
|
||||
}
|
||||
|
||||
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
|
||||
|
@@ -48,7 +48,7 @@ struct amdgpu_job {
|
||||
struct drm_sched_job base;
|
||||
struct amdgpu_vm *vm;
|
||||
struct amdgpu_sync explicit_sync;
|
||||
struct dma_fence hw_fence;
|
||||
struct amdgpu_fence hw_fence;
|
||||
struct dma_fence *gang_submit;
|
||||
uint32_t preamble_status;
|
||||
uint32_t preemption_status;
|
||||
|
@@ -123,6 +123,22 @@ struct amdgpu_fence_driver {
|
||||
struct dma_fence **fences;
|
||||
};
|
||||
|
||||
/*
|
||||
* Fences mark an event in the GPUs pipeline and are used
|
||||
* for GPU/CPU synchronization. When the fence is written,
|
||||
* it is expected that all buffers associated with that fence
|
||||
* are no longer in use by the associated ring on the GPU and
|
||||
* that the relevant GPU caches have been flushed.
|
||||
*/
|
||||
|
||||
struct amdgpu_fence {
|
||||
struct dma_fence base;
|
||||
|
||||
/* RB, DMA, etc. */
|
||||
struct amdgpu_ring *ring;
|
||||
ktime_t start_timestamp;
|
||||
};
|
||||
|
||||
extern const struct drm_sched_backend_ops amdgpu_sched_ops;
|
||||
|
||||
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
|
||||
|
Reference in New Issue
Block a user