Skip to content

Commit

Permalink
drm/etnaviv: take current primitive into account when checking for hu…
Browse files Browse the repository at this point in the history
…ng GPU

Large draws can make the GPU appear to be stuck to the current hangcheck
logic as the FE address will not move until the draw is finished. However,
the FE has a debug register, which records the current primitive ID within
a draw. Using this debug register we can extend the timeout as long as the
draw progresses.

Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
  • Loading branch information
Lucas Stach committed Oct 28, 2024
1 parent 46864a6 commit e1f3220
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ struct etnaviv_gpu {

/* hang detection */
u32 hangcheck_dma_addr;
u32 hangcheck_primid;
u32 hangcheck_fence;

void __iomem *mmio;
Expand Down
17 changes: 15 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "etnaviv_gpu.h"
#include "etnaviv_sched.h"
#include "state.xml.h"
#include "state_hi.xml.h"

static int etnaviv_job_hang_limit = 0;
module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444);
Expand All @@ -35,7 +36,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
{
struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
struct etnaviv_gpu *gpu = submit->gpu;
u32 dma_addr;
u32 dma_addr, primid = 0;
int change;

/*
Expand All @@ -52,10 +53,22 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
*/
dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
change = dma_addr - gpu->hangcheck_dma_addr;
if (submit->exec_state == ETNA_PIPE_3D) {
/* guard against concurrent usage from perfmon_sample */
mutex_lock(&gpu->lock);
gpu_write(gpu, VIVS_MC_PROFILE_CONFIG0,
VIVS_MC_PROFILE_CONFIG0_FE_CURRENT_PRIM <<
VIVS_MC_PROFILE_CONFIG0_FE__SHIFT);
primid = gpu_read(gpu, VIVS_MC_PROFILE_FE_READ);
mutex_unlock(&gpu->lock);
}
if (gpu->state == ETNA_GPU_STATE_RUNNING &&
(gpu->completed_fence != gpu->hangcheck_fence ||
change < 0 || change > 16)) {
change < 0 || change > 16 ||
(submit->exec_state == ETNA_PIPE_3D &&
gpu->hangcheck_primid != primid))) {
gpu->hangcheck_dma_addr = dma_addr;
gpu->hangcheck_primid = primid;
gpu->hangcheck_fence = gpu->completed_fence;
goto out_no_timeout;
}
Expand Down

0 comments on commit e1f3220

Please sign in to comment.