summaryrefslogtreecommitdiff
path: root/include/drm
diff options
context:
space:
mode:
authorMatthew Brost <matthew.brost@intel.com>2025-06-13 14:20:13 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-07-17 18:27:57 +0200
commite62f51d0ec8a9baf324caf9a564f8e318d36a551 (patch)
treec086a05d27e54a37e8e3463b7ab836aef4434e93 /include/drm
parent3f8fc02c2582c1dfad1785e9c7bc8b4e1521af0a (diff)
downloadlinux-e62f51d0ec8a9baf324caf9a564f8e318d36a551.tar.gz
linux-e62f51d0ec8a9baf324caf9a564f8e318d36a551.tar.bz2
linux-e62f51d0ec8a9baf324caf9a564f8e318d36a551.zip
drm/sched: Increment job count before swapping tail spsc queue
commit 8af39ec5cf2be522c8eb43a3d8005ed59e4daaee upstream. A small race exists between spsc_queue_push and the run-job worker, in which spsc_queue_push may return not-first while the run-job worker has already idled due to the job count being zero. If this race occurs, job scheduling stops, leading to hangs while waiting on the job’s DMA fences. Seal this race by incrementing the job count before appending to the SPSC queue. This race was observed on a drm-tip 6.16-rc1 build with the Xe driver in an SVM test case. Fixes: 1b1f42d8fde4 ("drm: move amd_gpu_scheduler into common location") Fixes: 27105db6c63a ("drm/amdgpu: Add SPSC queue to scheduler.") Cc: stable@vger.kernel.org Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com> Link: https://lore.kernel.org/r/20250613212013.719312-1-matthew.brost@intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/spsc_queue.h4
1 files changed, 3 insertions, 1 deletions
diff --git a/include/drm/spsc_queue.h b/include/drm/spsc_queue.h
index 125f096c88cb..ee9df8cc67b7 100644
--- a/include/drm/spsc_queue.h
+++ b/include/drm/spsc_queue.h
@@ -70,9 +70,11 @@ static inline bool spsc_queue_push(struct spsc_queue *queue, struct spsc_node *n
preempt_disable();
+ atomic_inc(&queue->job_count);
+ smp_mb__after_atomic();
+
tail = (struct spsc_node **)atomic_long_xchg(&queue->tail, (long)&node->next);
WRITE_ONCE(*tail, node);
- atomic_inc(&queue->job_count);
/*
* In case of first element verify new node will be visible to the consumer