Add a per-priority-band count (LOW/NORMAL/HIGH) of exec queues attached to a user VM in xe_vm_add_exec_queue()/xe_vm_remove_exec_queue(), protected by vm->exec_queues.lock in write mode. KERNEL priority is not counted since it is not possible for user exec queues.
This count is needed so a VM's private buffer objects can later be prioritized for eviction based on the priority userspace has assigned to the exec queues using that VM (i.e. work submitted at a higher priority band implies its buffers are more important to keep resident), rather than treating every VM the same. Also move the has_ctx_tlb_inval check inside the lock in xe_vm_add_exec_queue() so the list add/count update is properly gated under the same critical section, and make xe_vm_remove_exec_queue() bail out early if q->xef is not set, rather than relying on callers to check this. Cc: Carlos Santa <[email protected]> Cc: Ryan Neph <[email protected]> Assisted-by: GitHub_Copilot:claude-sonnet-5 Signed-off-by: Matthew Brost <[email protected]> --- drivers/gpu/drm/xe/xe_vm.c | 31 ++++++++++++++++++++----------- drivers/gpu/drm/xe/xe_vm_types.h | 7 +++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index e915e33ebece..984e76248942 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -4933,8 +4933,9 @@ int xe_vm_alloc_cpu_addr_mirror_vma(struct xe_vm *vm, uint64_t start, uint64_t r * @vm: The VM. * @q: The exec_queue * - * Add exec queue to VM, skipped if the device does not have context based TLB - * invalidations. + * Track exec queue's priority band count for the VM. Also links the exec + * queue onto the per-GT list, skipped if the device does not have context + * based TLB invalidations. */ void xe_vm_add_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q) { @@ -4948,12 +4949,14 @@ void xe_vm_add_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q) xe_assert(xe, vm->xef); xe_assert(xe, vm == q->vm); - if (!xe->info.has_ctx_tlb_inval) - return; - down_write(&vm->exec_queues.lock); - list_add(&q->vm_exec_queue_link, &vm->exec_queues.list[q->gt->info.id]); - ++vm->exec_queues.count[q->gt->info.id]; + if (xe->info.has_ctx_tlb_inval) { + list_add(&q->vm_exec_queue_link, &vm->exec_queues.list[q->gt->info.id]); + ++vm->exec_queues.count[q->gt->info.id]; + } + if (q->sched_props.priority >= XE_EXEC_QUEUE_PRIORITY_LOW && + q->sched_props.priority <= XE_EXEC_QUEUE_PRIORITY_HIGH) + ++vm->exec_queues.priority_count[q->sched_props.priority]; up_write(&vm->exec_queues.lock); } @@ -4962,18 +4965,24 @@ void xe_vm_add_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q) * @vm: The VM. * @q: The exec_queue * - * Remove exec queue from VM, skipped if the device does not have context based - * TLB invalidations. + * Untrack exec queue's priority band count for the VM. Also unlinks the + * exec queue from the per-GT list, skipped if the device does not have + * context based TLB invalidations. No-op if @q is not a user exec queue, + * or is a VM exec queue (VM exec queues are never tracked by + * xe_vm_add_exec_queue()). */ void xe_vm_remove_exec_queue(struct xe_vm *vm, struct xe_exec_queue *q) { - if (!vm->xe->info.has_ctx_tlb_inval) + if (!q->xef || (q->flags & EXEC_QUEUE_FLAG_VM)) return; down_write(&vm->exec_queues.lock); - if (!list_empty(&q->vm_exec_queue_link)) { + if (vm->xe->info.has_ctx_tlb_inval && !list_empty(&q->vm_exec_queue_link)) { list_del(&q->vm_exec_queue_link); --vm->exec_queues.count[q->gt->info.id]; } + if (q->sched_props.priority >= XE_EXEC_QUEUE_PRIORITY_LOW && + q->sched_props.priority <= XE_EXEC_QUEUE_PRIORITY_HIGH) + --vm->exec_queues.priority_count[q->sched_props.priority]; up_write(&vm->exec_queues.lock); } diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h index 635ed29b9a69..d75546c4eb66 100644 --- a/drivers/gpu/drm/xe/xe_vm_types.h +++ b/drivers/gpu/drm/xe/xe_vm_types.h @@ -16,6 +16,7 @@ #include <linux/scatterlist.h> #include "xe_device_types.h" +#include "xe_exec_queue_types.h" #include "xe_pt_types.h" #include "xe_range_fence.h" #include "xe_tlb_inval_types.h" @@ -342,6 +343,12 @@ struct xe_vm { * per GT */ int count[XE_MAX_TILES_PER_DEVICE * XE_MAX_GT_PER_TILE]; + /** + * @exec_queues.priority_count: count of exec queues attached + * to this VM, per priority band (LOW / NORMAL / HIGH only, + * KERNEL priority is not possible for user exec queues) + */ + int priority_count[XE_EXEC_QUEUE_PRIORITY_HIGH + 1]; /** @exec_queues.lock: lock to protect exec_queues list */ struct rw_semaphore lock; } exec_queues; -- 2.34.1
