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;
|
continue;
|
||||||
}
|
}
|
||||||
job = to_amdgpu_job(s_job);
|
job = to_amdgpu_job(s_job);
|
||||||
if (preempted && (&job->hw_fence) == fence)
|
if (preempted && (&job->hw_fence.base) == fence)
|
||||||
/* mark the job as preempted */
|
/* mark the job as preempted */
|
||||||
job->preemption_status |= AMDGPU_IB_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
|
* 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;
|
job_signaled = true;
|
||||||
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
|
||||||
goto skip_hw_reset;
|
goto skip_hw_reset;
|
||||||
|
@@ -41,22 +41,6 @@
|
|||||||
#include "amdgpu_trace.h"
|
#include "amdgpu_trace.h"
|
||||||
#include "amdgpu_reset.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;
|
static struct kmem_cache *amdgpu_fence_slab;
|
||||||
|
|
||||||
int amdgpu_fence_slab_init(void)
|
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);
|
am_fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_ATOMIC);
|
||||||
if (am_fence == NULL)
|
if (am_fence == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
fence = &am_fence->base;
|
|
||||||
am_fence->ring = ring;
|
|
||||||
} else {
|
} else {
|
||||||
/* take use of job-embedded fence */
|
/* 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;
|
seq = ++ring->fence_drv.sync_seq;
|
||||||
if (job && job->job_run_counter) {
|
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
|
* it right here or we won't be able to track them in fence_drv
|
||||||
* and they will remain unsignaled during sa_bo free.
|
* 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))
|
if (!job->base.s_fence && !dma_fence_is_signaled(old))
|
||||||
dma_fence_signal(old);
|
dma_fence_signal(old);
|
||||||
RCU_INIT_POINTER(*ptr, NULL);
|
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)
|
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;
|
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)
|
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))
|
if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer))
|
||||||
amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched));
|
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);
|
struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
|
||||||
|
|
||||||
/* free job if fence has a parent job */
|
/* 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 */
|
/* Check if any fences where initialized */
|
||||||
if (job->base.s_fence && job->base.s_fence->finished.ops)
|
if (job->base.s_fence && job->base.s_fence->finished.ops)
|
||||||
f = &job->base.s_fence->finished;
|
f = &job->base.s_fence->finished;
|
||||||
else if (job->hw_fence.ops)
|
else if (job->hw_fence.base.ops)
|
||||||
f = &job->hw_fence;
|
f = &job->hw_fence.base;
|
||||||
else
|
else
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
|
||||||
@@ -183,10 +183,10 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
|
|||||||
amdgpu_sync_free(&job->explicit_sync);
|
amdgpu_sync_free(&job->explicit_sync);
|
||||||
|
|
||||||
/* only put the hw fence if has embedded fence */
|
/* only put the hw fence if has embedded fence */
|
||||||
if (!job->hw_fence.ops)
|
if (!job->hw_fence.base.ops)
|
||||||
kfree(job);
|
kfree(job);
|
||||||
else
|
else
|
||||||
dma_fence_put(&job->hw_fence);
|
dma_fence_put(&job->hw_fence.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amdgpu_job_set_gang_leader(struct amdgpu_job *job,
|
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)
|
if (job->gang_submit != &job->base.s_fence->scheduled)
|
||||||
dma_fence_put(job->gang_submit);
|
dma_fence_put(job->gang_submit);
|
||||||
|
|
||||||
if (!job->hw_fence.ops)
|
if (!job->hw_fence.base.ops)
|
||||||
kfree(job);
|
kfree(job);
|
||||||
else
|
else
|
||||||
dma_fence_put(&job->hw_fence);
|
dma_fence_put(&job->hw_fence.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
|
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job)
|
||||||
|
@@ -48,7 +48,7 @@ struct amdgpu_job {
|
|||||||
struct drm_sched_job base;
|
struct drm_sched_job base;
|
||||||
struct amdgpu_vm *vm;
|
struct amdgpu_vm *vm;
|
||||||
struct amdgpu_sync explicit_sync;
|
struct amdgpu_sync explicit_sync;
|
||||||
struct dma_fence hw_fence;
|
struct amdgpu_fence hw_fence;
|
||||||
struct dma_fence *gang_submit;
|
struct dma_fence *gang_submit;
|
||||||
uint32_t preamble_status;
|
uint32_t preamble_status;
|
||||||
uint32_t preemption_status;
|
uint32_t preemption_status;
|
||||||
|
@@ -123,6 +123,22 @@ struct amdgpu_fence_driver {
|
|||||||
struct dma_fence **fences;
|
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;
|
extern const struct drm_sched_backend_ops amdgpu_sched_ops;
|
||||||
|
|
||||||
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
|
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
|
||||||
|
Reference in New Issue
Block a user