[PATCH 3/3] drm/amdkfd: disable debug before retiring MES process context on teardown
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: Alex Sierra <[email protected]> On process teardown, kfd_process_notifier_release_internal() called kfd_process_dequeue_from_all_devices() (which issues the MES SET_SHADER_DEBUGGER process_ctx_flush=1 that retires the process context) before kfd_dbg_trap_disable(). For a process under a debugger, the debug teardown path (kfd_dbg_trap_disable -> kfd_dbg_trap_deactivate) then issues several SET_SHADER_DEBUGGER process_ctx_flush=0 packets (reset wave launch mode, clear debug flags, reset MES debug mode). Because those packets carry the process_context_addr, MES re-adds the process to its scheduler list after the flush had retired it. Teardown then frees proc_ctx_bo, and a later MES scheduling pass dereferences the freed process context, producing a GPUVM page fault (vmid 0, GC_UTCL2) on the freed page. This is intermittent because it depends on an MES pass landing on the process before its GART page is reused. It is specific to the debugger path, where queues are added with skip_process_ctx_clear=1 so the last REMOVE_QUEUE does not clear the context and delisting relies on the flush. Reorder teardown so debug is disabled first, and the process context is flushed/retired last, so nothing re-adds the process after it is retired. kfd_dbg_trap_disable() now runs while queues still exist, which matches the normal live debug-disable ordering. Signed-off-by: Alex Sierra <[email protected]> Reviewed-by: Felix Kuehling <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 44 +++++++++++++++--------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 0a7c1900da959..dd938788bdd9a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -1408,23 +1408,16 @@ void kfd_process_notifier_release_internal(struct kfd_process *p) kfd_unref_process(p); /* - * Dequeue and destroy user queues, it is not safe for GPU to access - * system memory after mmu release notifier callback returns because - * exit_mmap free process memory afterwards. + * Disable debug BEFORE dequeuing/flushing the MES process context. + * + * kfd_dbg_trap_disable() -> kfd_dbg_trap_deactivate() issues + * SET_SHADER_DEBUGGER (process_ctx_flush=0) packets that re-add the + * process to the MES scheduler list. kfd_process_dequeue_from_all_devices() + * sends the process_ctx_flush=1 that retires the context. If debug + * teardown ran after the dequeue, those packets would put the process + * back on the MES list and, once proc_ctx_bo is freed, MES would fault + * on the freed process context. Retiring the context last avoids this. */ - kfd_process_dequeue_from_all_devices(p); - pqm_uninit(&p->pqm); - - for (i = 0; i < p->n_pdds; i++) { - struct kfd_process_device *pdd = p->pdds[i]; - - /* re-enable GFX OFF since runtime enable with ttmp setup disabled it. */ - if (!kfd_dbg_is_rlc_restore_supported(pdd->dev) && p->runtime_info.ttmp_setup) - amdgpu_gfx_off_ctrl(pdd->dev->adev, true); - } - - /* Indicate to other users that MM is no longer valid */ - p->mm = NULL; kfd_dbg_trap_disable(p); if (atomic_read(&p->debugged_process_count) > 0) { @@ -1445,6 +1438,25 @@ void kfd_process_notifier_release_internal(struct kfd_process *p) srcu_read_unlock(&kfd_processes_srcu, idx); } + /* + * Dequeue and destroy user queues, it is not safe for GPU to access + * system memory after mmu release notifier callback returns because + * exit_mmap free process memory afterwards. + */ + kfd_process_dequeue_from_all_devices(p); + pqm_uninit(&p->pqm); + + for (i = 0; i < p->n_pdds; i++) { + struct kfd_process_device *pdd = p->pdds[i]; + + /* re-enable GFX OFF since runtime enable with ttmp setup disabled it. */ + if (!kfd_dbg_is_rlc_restore_supported(pdd->dev) && p->runtime_info.ttmp_setup) + amdgpu_gfx_off_ctrl(pdd->dev->adev, true); + } + + /* Indicate to other users that MM is no longer valid */ + p->mm = NULL; + if (p->context_id == KFD_CONTEXT_ID_PRIMARY) mmu_notifier_put(&p->mmu_notifier); } -- 2.55.0