summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Zhang <Jesse.Zhang@amd.com>2026-10-12 12:19:15 +0800
committerAlex Deucher <alexander.deucher@amd.com>2026-10-27 17:04:49 -0400
commit8f3ecda0ab42fb5ba7310fe848013d3eff31b416 (patch)
treebc7038f7094130f0f8c6681caf2d5ae0be95c83f
parentc1584e10a7deb655438f21867b2b7a356a9aaf9f (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.c15
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;
}