]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/sched: Increment job count before swapping tail spsc queue
authorMatthew Brost <matthew.brost@intel.com>
Fri, 13 Jun 2025 21:20:13 +0000 (14:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jul 2025 16:30:49 +0000 (18:30 +0200)
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>
include/drm/spsc_queue.h

index 125f096c88cb96a6da1567d25a238a9cf1640f41..ee9df8cc67b730db81d5a25174d9a5430cf976a7 100644 (file)
@@ -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