]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/xe/multi_queue: Store primary LRC and position info in LRC
authorUmesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Thu, 7 May 2026 16:20:22 +0000 (09:20 -0700)
committerUmesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Fri, 8 May 2026 20:48:42 +0000 (13:48 -0700)
For an LRC belonging to the secondary queue, in order to check if its
context group is active, we need to check the LRC of the primary queue.
In addition to that we want to compare the secondary queue position to
CSMQDEBUG register to check if the queue itself is active.

To do so, store primary LRC and position information in the LRC.

A note on references involved:

- In general the Queue takes a ref on its LRC.
- In addition, for multi-queue,
a. Primary Queue takes a ref for each Secondary LRC.
b. Each Secondary Queue takes a ref to the Primary Queue

In the current patch, each LRC in the queue group is storing a pointer
to primary LRC. Both primary and secondary LRCs are freed only when
primary queue is destroyed. At this time, all secondary queues are
already destroyed, so there is no one using secondary LRCs. We should be
good without taking any additional references.

Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Reviewed-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Link: https://patch.msgid.link/20260507162016.3888309-18-umesh.nerlige.ramappa@intel.com
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_lrc.h
drivers/gpu/drm/xe/xe_lrc_types.h

index 62a75c8fe72fde3d12713cfd5b5607911efc6d9b..1b5ca3ce578a4a846dffa1ae5fdd3d890779656d 100644 (file)
@@ -275,8 +275,12 @@ static void xe_exec_queue_set_lrc(struct xe_exec_queue *q, struct xe_lrc *lrc, u
 {
        xe_assert(gt_to_xe(q->gt), idx < q->width);
 
-       scoped_guard(spinlock, &q->lrc_lookup_lock)
+       scoped_guard(spinlock, &q->lrc_lookup_lock) {
                q->lrc[idx] = lrc;
+               if (xe_exec_queue_is_multi_queue(q))
+                       q->lrc[idx]->multi_queue.primary_lrc =
+                               q->multi_queue.group->primary->lrc[0];
+       }
 }
 
 /**
@@ -907,6 +911,7 @@ static int xe_exec_queue_group_add(struct xe_device *xe, struct xe_exec_queue *q
        }
 
        q->multi_queue.pos = pos;
+       q->lrc[0]->multi_queue.pos = pos;
 
        return 0;
 }
index d280e657239839e7ba8414aa80b45df61f9b4c5f..557dce004d48918239e14428b3934fb01ae91989 100644 (file)
@@ -91,6 +91,11 @@ static inline size_t xe_lrc_ring_size(void)
        return SZ_16K;
 }
 
+static inline bool xe_lrc_is_multi_queue(struct xe_lrc *lrc)
+{
+       return lrc->multi_queue.primary_lrc;
+}
+
 size_t xe_gt_lrc_hang_replay_size(struct xe_gt *gt, enum xe_engine_class class);
 size_t xe_gt_lrc_size(struct xe_gt *gt, enum xe_engine_class class);
 u32 xe_lrc_pphwsp_offset(struct xe_lrc *lrc);
index 5a718f759ed69ae5bd4f4fe11377cb72fe3a0523..0a5c13ec2ad7a9b22b37ac62c86de3085e20cc9c 100644 (file)
@@ -63,6 +63,14 @@ struct xe_lrc {
 
        /** @ctx_timestamp: readout value of CTX_TIMESTAMP on last update */
        u64 ctx_timestamp;
+
+       /** @multi_queue: Multi queue LRC related information */
+       struct {
+               /** @multi_queue.primary_lrc: Primary lrc of this multi-queue group*/
+               struct xe_lrc *primary_lrc;
+               /** @multi_queue.pos: Position of LRC within the multi-queue group */
+               u8 pos;
+       } multi_queue;
 };
 
 struct xe_lrc_snapshot;