Skip to content

Commit e1f3220

Browse files
committed
drm/etnaviv: take current primitive into account when checking for hung 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>
1 parent 46864a6 commit e1f3220

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ struct etnaviv_gpu {
144144

145145
/* hang detection */
146146
u32 hangcheck_dma_addr;
147+
u32 hangcheck_primid;
147148
u32 hangcheck_fence;
148149

149150
void __iomem *mmio;

drivers/gpu/drm/etnaviv/etnaviv_sched.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "etnaviv_gpu.h"
1212
#include "etnaviv_sched.h"
1313
#include "state.xml.h"
14+
#include "state_hi.xml.h"
1415

1516
static int etnaviv_job_hang_limit = 0;
1617
module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444);
@@ -35,7 +36,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
3536
{
3637
struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
3738
struct etnaviv_gpu *gpu = submit->gpu;
38-
u32 dma_addr;
39+
u32 dma_addr, primid = 0;
3940
int change;
4041

4142
/*
@@ -52,10 +53,22 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
5253
*/
5354
dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
5455
change = dma_addr - gpu->hangcheck_dma_addr;
56+
if (submit->exec_state == ETNA_PIPE_3D) {
57+
/* guard against concurrent usage from perfmon_sample */
58+
mutex_lock(&gpu->lock);
59+
gpu_write(gpu, VIVS_MC_PROFILE_CONFIG0,
60+
VIVS_MC_PROFILE_CONFIG0_FE_CURRENT_PRIM <<
61+
VIVS_MC_PROFILE_CONFIG0_FE__SHIFT);
62+
primid = gpu_read(gpu, VIVS_MC_PROFILE_FE_READ);
63+
mutex_unlock(&gpu->lock);
64+
}
5565
if (gpu->state == ETNA_GPU_STATE_RUNNING &&
5666
(gpu->completed_fence != gpu->hangcheck_fence ||
57-
change < 0 || change > 16)) {
67+
change < 0 || change > 16 ||
68+
(submit->exec_state == ETNA_PIPE_3D &&
69+
gpu->hangcheck_primid != primid))) {
5870
gpu->hangcheck_dma_addr = dma_addr;
71+
gpu->hangcheck_primid = primid;
5972
gpu->hangcheck_fence = gpu->completed_fence;
6073
goto out_no_timeout;
6174
}

0 commit comments

Comments
 (0)