drm/amdkfd: gfx12.1 add no-op prefetch on trap entry

VMEM instructions may hang after trap exit. Issue a no-op
prefetch to reset wave VMEM state.

v2: squash in preserve SCC on trap entry

Signed-off-by: Jay Cornwall <jay.cornwall@amd.com>
Cc: Joseph Greathouse <joseph.greathouse@amd.com>
Cc: Michael Chen <michael.chen@amd.com>
Cc: Lancelot Six <lancelot.six@amd.com>
Cc: Vladimir Indic <vladimir.indic@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Jay Cornwall 2026-06-08 09:53:57 -05:00 committed by Alex Deucher
parent 42cc336311
commit 0e1e0f87af
2 changed files with 674 additions and 631 deletions

File diff suppressed because it is too large Load Diff

View File

@ -44,11 +44,16 @@
#define HAVE_HT_TRAP_ID_WA (ASIC_FAMILY >= CHIP_GFX12)
#define WAVE32_ONLY (ASIC_FAMILY == CHIP_GC_12_0_3)
#define SAVE_TTMPS_IN_SGPR_BLOCK (ASIC_FAMILY >= CHIP_GC_12_0_3)
#define VMEM_ON_TRAP_ENTRY_WA (ASIC_FAMILY == CHIP_GC_12_0_3)
#if HAVE_XNACK && !WAVE32_ONLY
# error
#endif
#if VMEM_ON_TRAP_ENTRY_WA && RELAXED_SCHEDULING_IN_TRAP
# error
#endif
#define ADDRESS_HI32_NUM_BITS ((HAVE_57BIT_ADDRESS ? 57 : 48) - 32)
#define ADDRESS_HI32_MASK ((1 << ADDRESS_HI32_NUM_BITS) - 1)
@ -238,6 +243,34 @@ L_JUMP_TO_RESTORE:
s_branch L_RESTORE
L_SKIP_RESTORE:
s_getreg_b32 s_save_state_priv, hwreg(HW_REG_WAVE_STATE_PRIV) //save STATUS since we will change SCC
#if VMEM_ON_TRAP_ENTRY_WA
s_getreg_b32 ttmp14, hwreg(HW_REG_WAVE_EXCP_FLAG_PRIV)
s_bitcmp1_b32 ttmp14, SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT
s_cbranch_scc0 L_NOT_WAVE_START
s_setreg_imm32_b32 hwreg(HW_REG_WAVE_EXCP_FLAG_PRIV, SQ_WAVE_EXCP_FLAG_PRIV_WAVE_START_SHIFT, 1), 0
s_mov_b64 [ttmp2, ttmp3], 0
v_mov_b32 v1, 0
global_prefetch_b8 v1, [ttmp2, ttmp3] scope:SCOPE_SE th:TH_LOAD_RT
s_rfe_b64 [ttmp0, ttmp1]
L_NOT_WAVE_START:
s_mov_b32 ttmp14, exec_lo
s_mov_b32 exec_lo, 1
v_readlane_b32 ttmp15, v1, 0
s_mov_b64 [ttmp2, ttmp3], 0
v_mov_b32 v1, 0
global_prefetch_b8 v1, [ttmp2, ttmp3] scope:SCOPE_SE th:TH_LOAD_RT
v_writelane_b32 v1, ttmp15, 0
s_mov_b32 exec_lo, ttmp14
#endif
#if RELAXED_SCHEDULING_IN_TRAP
// Assume most relaxed scheduling mode is set. Save and revert to normal mode.
s_getreg_b32 ttmp2, hwreg(HW_REG_WAVE_SCHED_MODE)
@ -246,8 +279,6 @@ L_SKIP_RESTORE:
SQ_WAVE_SCHED_MODE_DEP_MODE_SHIFT, SQ_WAVE_SCHED_MODE_DEP_MODE_SIZE), 0
#endif
s_getreg_b32 s_save_state_priv, hwreg(HW_REG_WAVE_STATE_PRIV) //save STATUS since we will change SCC
#if RELAXED_SCHEDULING_IN_TRAP
// Save SCHED_MODE[1:0] into ttmp11[27:26].
s_andn2_b32 ttmp11, ttmp11, TTMP11_SCHED_MODE_MASK