From: David Yat Sin <David.YatSin@xxxxxxx> We need the SPI_GDBG_PER_VMID_CNTL.TRAP_EN bit to be set during PC Sampling so that the TTMP registers are valid inside the sampling data. runtime_info.ttmp_setup will be cleared when the user application does the AMDKFD_IOC_RUNTIME_ENABLE ioctl without KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK flag on exit. It is also not valid to have the debugger attached to a process while PC sampling is enabled so adding some checks to prevent this. Signed-off-by: David Yat Sin <David.YatSin@xxxxxxx> Signed-off-by: James Zhu <James.Zhu@xxxxxxx> --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 30 ++++++-------------- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 26 +++++++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_debug.h | 3 ++ drivers/gpu/drm/amd/amdkfd/kfd_pc_sampling.c | 13 +++++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 3 ++ 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index d9cac97c54c0..bc37f3ee2c66 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -2804,26 +2804,9 @@ static int runtime_enable(struct kfd_process *p, uint64_t r_debug, p->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED; p->runtime_info.r_debug = r_debug; - p->runtime_info.ttmp_setup = enable_ttmp_setup; - if (p->runtime_info.ttmp_setup) { - for (i = 0; i < p->n_pdds; i++) { - struct kfd_process_device *pdd = p->pdds[i]; - - if (!kfd_dbg_is_rlc_restore_supported(pdd->dev)) { - amdgpu_gfx_off_ctrl(pdd->dev->adev, false); - pdd->dev->kfd2kgd->enable_debug_trap( - pdd->dev->adev, - true, - pdd->dev->vm_info.last_vmid_kfd); - } else if (kfd_dbg_is_per_vmid_supported(pdd->dev)) { - pdd->spi_dbg_override = pdd->dev->kfd2kgd->enable_debug_trap( - pdd->dev->adev, - false, - 0); - } - } - } + if (enable_ttmp_setup) + kfd_dbg_enable_ttmp_setup(p); retry: if (p->debug_trap_enabled) { @@ -2972,10 +2955,10 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v goto out; } - /* Check if target is still PTRACED. */ rcu_read_lock(); + /* Check if target is still PTRACED. */ if (target != p && args->op != KFD_IOC_DBG_TRAP_DISABLE - && ptrace_parent(target->lead_thread) != current) { + && ptrace_parent(target->lead_thread) != current) { pr_err("PID %i is not PTRACED and cannot be debugged\n", args->pid); r = -EPERM; } @@ -2985,6 +2968,11 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v goto out; mutex_lock(&target->mutex); + if (!!target->pc_sampling_ref) { + pr_debug("Cannot enable debug trap on PID:%d because PC Sampling active\n", args->pid); + r = -EBUSY; + goto unlock_out; + } if (args->op != KFD_IOC_DBG_TRAP_ENABLE && !target->debug_trap_enabled) { pr_err("PID %i not debug enabled for op %i\n", args->pid, args->op); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index d889e3545120..8d836c65c636 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -1120,3 +1120,29 @@ void kfd_dbg_set_enabled_debug_exception_mask(struct kfd_process *target, mutex_unlock(&target->event_mutex); } + +void kfd_dbg_enable_ttmp_setup(struct kfd_process *p) +{ + int i; + + if (p->runtime_info.ttmp_setup) + return; + + p->runtime_info.ttmp_setup = true; + for (i = 0; i < p->n_pdds; i++) { + struct kfd_process_device *pdd = p->pdds[i]; + + if (!kfd_dbg_is_rlc_restore_supported(pdd->dev)) { + amdgpu_gfx_off_ctrl(pdd->dev->adev, false); + pdd->dev->kfd2kgd->enable_debug_trap( + pdd->dev->adev, + true, + pdd->dev->vm_info.last_vmid_kfd); + } else if (kfd_dbg_is_per_vmid_supported(pdd->dev)) { + pdd->spi_dbg_override = pdd->dev->kfd2kgd->enable_debug_trap( + pdd->dev->adev, + false, + 0); + } + } +} diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.h b/drivers/gpu/drm/amd/amdkfd/kfd_debug.h index fd0ff64d4184..d7ce0b119dd0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.h @@ -90,6 +90,9 @@ int kfd_dbg_trap_device_snapshot(struct kfd_process *target, void kfd_dbg_set_enabled_debug_exception_mask(struct kfd_process *target, uint64_t exception_set_mask); + +void kfd_dbg_enable_ttmp_setup(struct kfd_process *p); + /* * If GFX off is enabled, chips that do not support RLC restore for the debug * registers will disable GFX off temporarily for the entire debug session. diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pc_sampling.c b/drivers/gpu/drm/amd/amdkfd/kfd_pc_sampling.c index 783844ddd82f..4777cfefbb08 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pc_sampling.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pc_sampling.c @@ -24,6 +24,7 @@ #include "kfd_priv.h" #include "amdgpu_amdkfd.h" #include "kfd_pc_sampling.h" +#include "kfd_debug.h" #include "kfd_device_queue_manager.h" struct supported_pc_sample_info { @@ -312,6 +313,14 @@ static int kfd_pc_sample_create(struct kfd_process_device *pdd, pcs_entry->pdd = pdd; user_args->trace_id = (uint32_t)i; + /* + * Set SPI_GDBG_PER_VMID_CNTL.TRAP_EN so that TTMP registers are valid in the sampling data + * p->runtime_info.ttmp_setup will be cleared when user application calls runtime_disable + * on exit. + */ + kfd_dbg_enable_ttmp_setup(pdd->process); + pdd->process->pc_sampling_ref++; + pr_debug("alloc pcs_entry = %p, trace_id = 0x%x on gpu 0x%x", pcs_entry, i, pdd->dev->id); return 0; @@ -323,6 +332,7 @@ static int kfd_pc_sample_destroy(struct kfd_process_device *pdd, uint32_t trace_ pr_debug("free pcs_entry = %p, trace_id = 0x%x on gpu 0x%x", pcs_entry, trace_id, pdd->dev->id); + pdd->process->pc_sampling_ref--; mutex_lock(&pdd->dev->pcs_data.mutex); pdd->dev->pcs_data.hosttrap_entry.base.use_count--; idr_remove(&pdd->dev->pcs_data.hosttrap_entry.base.pc_sampling_idr, trace_id); @@ -381,6 +391,9 @@ int kfd_pc_sample(struct kfd_process_device *pdd, if (!pcs_entry || pcs_entry->pdd != pdd) return -EINVAL; + } else if (pdd->process->debug_trap_enabled) { + pr_debug("Cannot have PC Sampling and debug trap simultaneously"); + return -EBUSY; } switch (args->op) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 372727b5d945..cce99478118b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -1021,6 +1021,9 @@ struct kfd_process { struct semaphore runtime_enable_sema; bool is_runtime_retry; struct kfd_runtime_info runtime_info; + + /* Indicates process' PC Sampling ref cnt*/ + uint32_t pc_sampling_ref; }; #define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */ -- 2.25.1