diff options
| author | Jesse Zhang <Jesse.Zhang@amd.com> | 2026-10-12 12:19:15 +0800 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2026-10-27 17:04:49 -0400 |
| commit | 8f3ecda0ab42fb5ba7310fe848013d3eff31b416 (patch) | |
| tree | bc7038f7094130f0f8c6681caf2d5ae0be95c83f | |
| parent | c1584e10a7deb655438f21867b2b7a356a9aaf9f (diff) | |
drm/amdkfd: evict the queues only once for CRIU PROCESS_INFO
criu_process_info() evicts the queues of the process on every call, and
each kfd_process_evict_queues() increments qpd->evicted, but CRIU UNPAUSE
restores them only once. After PROCESS_INFO twice and UNPAUSE the queues
stay evicted for good. On navi31, a barrier-AND packet on an HSA queue
completes after PROCESS_INFO + UNPAUSE, but times out after
PROCESS_INFO, PROCESS_INFO, UNPAUSE.
The error path has a related problem: when kfd_process_evict_queues()
itself fails, it has already rolled back its partial eviction, and the
kfd_process_restore_queues() in the error path restores once more.
Evict only when the queues are not paused yet, and on errors only undo
an eviction done by this call. The barrier now completes after any
number of PROCESS_INFO calls followed by UNPAUSE.
Fixes: cd9f79103003 ("drm/amdkfd: CRIU Implement KFD unpause operation")
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4d79c9e3c32c677fcadf5ca10ab81ee0a4b81f99)
Cc: stable@vger.kernel.org
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index cad60ccdb216..d65ae53c81a5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -2876,6 +2876,7 @@ static int criu_process_info(struct file *filep, struct kfd_process *p, struct kfd_ioctl_criu_args *args) { + bool paused_here = false; int ret = 0; mutex_lock(&p->mutex); @@ -2886,11 +2887,15 @@ static int criu_process_info(struct file *filep, goto err_unlock; } - ret = kfd_process_evict_queues(p, KFD_QUEUE_EVICTION_CRIU_CHECKPOINT); - if (ret) - goto err_unlock; + /* UNPAUSE restores the queues once, so evict them only once */ + if (!p->queues_paused) { + ret = kfd_process_evict_queues(p, KFD_QUEUE_EVICTION_CRIU_CHECKPOINT); + if (ret) + goto err_unlock; - p->queues_paused = true; + p->queues_paused = true; + paused_here = true; + } args->pid = task_pid_nr_ns(p->lead_thread, task_active_pid_ns(p->lead_thread)); @@ -2905,7 +2910,7 @@ static int criu_process_info(struct file *filep, args->priv_data_size); err_unlock: - if (ret) { + if (ret && paused_here) { kfd_process_restore_queues(p); p->queues_paused = false; } |
