]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/xe: Add dependency scheduler for GT TLB invalidations to bind queues
authorMatthew Brost <matthew.brost@intel.com>
Thu, 24 Jul 2025 19:12:13 +0000 (12:12 -0700)
committerMatthew Brost <matthew.brost@intel.com>
Fri, 25 Jul 2025 01:25:59 +0000 (18:25 -0700)
Add a generic dependency scheduler for GT TLB invalidations, used to
schedule jobs that issue GT TLB invalidations to bind queues.

v2:
 - Use shared GT TLB invalidation queue for dep scheduler
 - Break allocation of dep scheduler into its own function
 - Add define for max number tlb invalidations
 - Skip media if not present

Suggested-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Stuart Summers <stuart.summers@intel.com>
Link: https://lore.kernel.org/r/20250724191216.4076566-5-matthew.brost@intel.com
drivers/gpu/drm/xe/xe_exec_queue.c
drivers/gpu/drm/xe/xe_exec_queue_types.h

index 8991b4aed440710590e0de4feee7784049c31388..d5958518ef0003137d63f8d85aef588676b8f3ac 100644 (file)
@@ -12,6 +12,7 @@
 #include <drm/drm_file.h>
 #include <uapi/drm/xe_drm.h>
 
+#include "xe_dep_scheduler.h"
 #include "xe_device.h"
 #include "xe_gt.h"
 #include "xe_hw_engine_class_sysfs.h"
@@ -39,6 +40,12 @@ static int exec_queue_user_extensions(struct xe_device *xe, struct xe_exec_queue
 
 static void __xe_exec_queue_free(struct xe_exec_queue *q)
 {
+       int i;
+
+       for (i = 0; i < XE_EXEC_QUEUE_TLB_INVAL_COUNT; ++i)
+               if (q->tlb_inval[i].dep_scheduler)
+                       xe_dep_scheduler_fini(q->tlb_inval[i].dep_scheduler);
+
        if (xe_exec_queue_uses_pxp(q))
                xe_pxp_exec_queue_remove(gt_to_xe(q->gt)->pxp, q);
        if (q->vm)
@@ -50,6 +57,39 @@ static void __xe_exec_queue_free(struct xe_exec_queue *q)
        kfree(q);
 }
 
+static int alloc_dep_schedulers(struct xe_device *xe, struct xe_exec_queue *q)
+{
+       struct xe_tile *tile = gt_to_tile(q->gt);
+       int i;
+
+       for (i = 0; i < XE_EXEC_QUEUE_TLB_INVAL_COUNT; ++i) {
+               struct xe_dep_scheduler *dep_scheduler;
+               struct xe_gt *gt;
+               struct workqueue_struct *wq;
+
+               if (i == XE_EXEC_QUEUE_TLB_INVAL_PRIMARY_GT)
+                       gt = tile->primary_gt;
+               else
+                       gt = tile->media_gt;
+
+               if (!gt)
+                       continue;
+
+               wq = gt->tlb_invalidation.job_wq;
+
+#define MAX_TLB_INVAL_JOBS     16      /* Picking a reasonable value */
+               dep_scheduler = xe_dep_scheduler_create(xe, wq, q->name,
+                                                       MAX_TLB_INVAL_JOBS);
+               if (IS_ERR(dep_scheduler))
+                       return PTR_ERR(dep_scheduler);
+
+               q->tlb_inval[i].dep_scheduler = dep_scheduler;
+       }
+#undef MAX_TLB_INVAL_JOBS
+
+       return 0;
+}
+
 static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
                                                   struct xe_vm *vm,
                                                   u32 logical_mask,
@@ -94,6 +134,14 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe,
        else
                q->sched_props.priority = XE_EXEC_QUEUE_PRIORITY_NORMAL;
 
+       if (q->flags & (EXEC_QUEUE_FLAG_MIGRATE | EXEC_QUEUE_FLAG_VM)) {
+               err = alloc_dep_schedulers(xe, q);
+               if (err) {
+                       __xe_exec_queue_free(q);
+                       return ERR_PTR(err);
+               }
+       }
+
        if (vm)
                q->vm = xe_vm_get(vm);
 
index abdf4a57e6e26c7a4d6dd5196352e3fc7078ef68..ba443a497b389ea58a9f5dd9bfb47b5000540a0f 100644 (file)
@@ -134,6 +134,19 @@ struct xe_exec_queue {
                struct list_head link;
        } lr;
 
+#define XE_EXEC_QUEUE_TLB_INVAL_PRIMARY_GT     0
+#define XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT       1
+#define XE_EXEC_QUEUE_TLB_INVAL_COUNT          (XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT  + 1)
+
+       /** @tlb_inval: TLB invalidations exec queue state */
+       struct {
+               /**
+                * @tlb_inval.dep_scheduler: The TLB invalidation
+                * dependency scheduler
+                */
+               struct xe_dep_scheduler *dep_scheduler;
+       } tlb_inval[XE_EXEC_QUEUE_TLB_INVAL_COUNT];
+
        /** @pxp: PXP info tracking */
        struct {
                /** @pxp.type: PXP session type used by this queue */