Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe: split kernel vs permanent engine flags

If an engine is only destroyed on driver unload, we can skip its
clean-up steps with the GuC because the GuC is going to be tuned off as
well, so it doesn't matter if we're in sync with it or not. Currently,
we apply this optimization to all engines marked as kernel, but this
stops us to supporting kernel engines that don't stick around until
unload. To remove this limitation, add a separate flag to indicate if
the engine is expected to only be destryed on driver unload and use that
to trigger the optimzation.

While at it, add a small comment to explain what each engine flag
represents.

v2: s/XE_BUG_ON/XE_WARN_ON, s/ENGINE/EXEC_QUEUE
v3: rebased

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://lore.kernel.org/r/20230822173334.1664332-3-daniele.ceraolospurio@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>

authored by

Daniele Ceraolo Spurio and committed by
Rodrigo Vivi
923e4238 1c66c0f3

+27 -13
+3
drivers/gpu/drm/xe/xe_exec_queue.c
··· 41 41 int err; 42 42 int i; 43 43 44 + /* only kernel queues can be permanent */ 45 + XE_WARN_ON((flags & EXEC_QUEUE_FLAG_PERMANENT) && !(flags & EXEC_QUEUE_FLAG_KERNEL)); 46 + 44 47 q = kzalloc(sizeof(*q) + sizeof(struct xe_lrc) * width, GFP_KERNEL); 45 48 if (!q) 46 49 return ERR_PTR(-ENOMEM);
+16 -8
drivers/gpu/drm/xe/xe_exec_queue_types.h
··· 65 65 /** @fence_irq: fence IRQ used to signal job completion */ 66 66 struct xe_hw_fence_irq *fence_irq; 67 67 68 - #define EXEC_QUEUE_FLAG_BANNED BIT(0) 69 - #define EXEC_QUEUE_FLAG_KERNEL BIT(1) 70 - #define EXEC_QUEUE_FLAG_PERSISTENT BIT(2) 71 - #define EXEC_QUEUE_FLAG_COMPUTE_MODE BIT(3) 72 - /* Caller needs to hold rpm ref when creating engine with EXEC_QUEUE_FLAG_VM */ 73 - #define EXEC_QUEUE_FLAG_VM BIT(4) 74 - #define EXEC_QUEUE_FLAG_BIND_ENGINE_CHILD BIT(5) 75 - #define EXEC_QUEUE_FLAG_WA BIT(6) 68 + /* queue no longer allowed to submit */ 69 + #define EXEC_QUEUE_FLAG_BANNED BIT(0) 70 + /* queue used for kernel submission only */ 71 + #define EXEC_QUEUE_FLAG_KERNEL BIT(1) 72 + /* kernel engine only destroyed at driver unload */ 73 + #define EXEC_QUEUE_FLAG_PERMANENT BIT(2) 74 + /* queue keeps running pending jobs after destroy ioctl */ 75 + #define EXEC_QUEUE_FLAG_PERSISTENT BIT(3) 76 + /* queue for use with compute VMs */ 77 + #define EXEC_QUEUE_FLAG_COMPUTE_MODE BIT(4) 78 + /* for VM jobs. Caller needs to hold rpm ref when creating queue with this flag */ 79 + #define EXEC_QUEUE_FLAG_VM BIT(5) 80 + /* child of VM queue for multi-tile VM jobs */ 81 + #define EXEC_QUEUE_FLAG_BIND_ENGINE_CHILD BIT(6) 82 + /* queue used for WA setup */ 83 + #define EXEC_QUEUE_FLAG_WA BIT(7) 76 84 77 85 /** 78 86 * @flags: flags for this exec queue, should statically setup aside from ban
+3 -3
drivers/gpu/drm/xe/xe_guc_submit.c
··· 965 965 INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async); 966 966 967 967 /* We must block on kernel engines so slabs are empty on driver unload */ 968 - if (q->flags & EXEC_QUEUE_FLAG_KERNEL) 968 + if (q->flags & EXEC_QUEUE_FLAG_PERMANENT) 969 969 __guc_exec_queue_fini_async(&q->guc->fini_async); 970 970 else 971 971 queue_work(system_wq, &q->guc->fini_async); ··· 988 988 struct xe_exec_queue *q = msg->private_data; 989 989 struct xe_guc *guc = exec_queue_to_guc(q); 990 990 991 - XE_WARN_ON(q->flags & EXEC_QUEUE_FLAG_KERNEL); 991 + XE_WARN_ON(q->flags & EXEC_QUEUE_FLAG_PERMANENT); 992 992 trace_xe_exec_queue_cleanup_entity(q); 993 993 994 994 if (exec_queue_registered(q)) ··· 1208 1208 { 1209 1209 struct xe_sched_msg *msg = q->guc->static_msgs + STATIC_MSG_CLEANUP; 1210 1210 1211 - if (!(q->flags & EXEC_QUEUE_FLAG_KERNEL)) 1211 + if (!(q->flags & EXEC_QUEUE_FLAG_PERMANENT)) 1212 1212 guc_exec_queue_add_msg(q, msg, CLEANUP); 1213 1213 else 1214 1214 __guc_exec_queue_fini(exec_queue_to_guc(q), q);
+5 -2
drivers/gpu/drm/xe/xe_migrate.c
··· 343 343 344 344 m->q = xe_exec_queue_create(xe, vm, 345 345 BIT(hwe->logical_instance), 1, 346 - hwe, EXEC_QUEUE_FLAG_KERNEL); 346 + hwe, 347 + EXEC_QUEUE_FLAG_KERNEL | 348 + EXEC_QUEUE_FLAG_PERMANENT); 347 349 } else { 348 350 m->q = xe_exec_queue_create_class(xe, primary_gt, vm, 349 351 XE_ENGINE_CLASS_COPY, 350 - EXEC_QUEUE_FLAG_KERNEL); 352 + EXEC_QUEUE_FLAG_KERNEL | 353 + EXEC_QUEUE_FLAG_PERMANENT); 351 354 } 352 355 if (IS_ERR(m->q)) { 353 356 xe_vm_close_and_put(vm);