From: Matthew Brost <matthew.br...@intel.com>

Introduce a fences argument to xe_vm_range_tilemask_tlb_invalidation,
allowing callers to provide fences and defer waiting to a later point.

Signed-off-by: Matthew Brost <matthew.br...@intel.com>
---
 drivers/gpu/drm/xe/xe_svm.c |  3 ++-
 drivers/gpu/drm/xe/xe_vm.c  | 26 +++++++++++++++++---------
 drivers/gpu/drm/xe/xe_vm.h  |  6 ++++--
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 23c5b363261c..82a598c8d56e 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -226,7 +226,8 @@ static void xe_svm_invalidate_twopass(struct drm_gpusvm 
*gpusvm,
 
        xe_device_wmb(xe);
 
-       err = xe_vm_range_tilemask_tlb_invalidation(vm, adj_start, adj_end, 
tile_mask);
+       err = xe_vm_range_tilemask_tlb_invalidation(vm, NULL, adj_start,
+                                                   adj_end, tile_mask);
        WARN_ON_ONCE(err);
 
 range_notifier_event_end:
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 148a2425006f..52242fac6969 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -3846,6 +3846,7 @@ void xe_vm_unlock(struct xe_vm *vm)
  * xe_vm_range_tilemask_tlb_invalidation - Issue a TLB invalidation on this 
tilemask for an
  * address range
  * @vm: The VM
+ * @fences: Caller provided fences, caller owns waiting if non-NULL
  * @start: start address
  * @end: end address
  * @tile_mask: mask for which gt's issue tlb invalidation
@@ -3854,10 +3855,12 @@ void xe_vm_unlock(struct xe_vm *vm)
  *
  * Returns 0 for success, negative error code otherwise.
  */
-int xe_vm_range_tilemask_tlb_invalidation(struct xe_vm *vm, u64 start,
-                                         u64 end, u8 tile_mask)
+int xe_vm_range_tilemask_tlb_invalidation(struct xe_vm *vm,
+                                         struct xe_gt_tlb_invalidation_fence 
*fences,
+                                         u64 start, u64 end, u8 tile_mask)
 {
        struct xe_gt_tlb_invalidation_fence fence[XE_MAX_TILES_PER_DEVICE * 
XE_MAX_GT_PER_TILE];
+       struct xe_gt_tlb_invalidation_fence *__fence = fences ?: fence;
        struct xe_tile *tile;
        u32 fence_id = 0;
        u8 id;
@@ -3869,37 +3872,41 @@ int xe_vm_range_tilemask_tlb_invalidation(struct xe_vm 
*vm, u64 start,
        for_each_tile(tile, vm->xe, id) {
                if (tile_mask & BIT(id)) {
                        xe_gt_tlb_invalidation_fence_init(tile->primary_gt,
-                                                         &fence[fence_id], 
true);
+                                                        __fence, true);
 
                        err = xe_gt_tlb_invalidation_range(tile->primary_gt,
-                                                          &fence[fence_id],
+                                                          __fence,
                                                           start,
                                                           end,
                                                           vm->usm.asid);
                        if (err)
                                goto wait;
                        ++fence_id;
+                       ++__fence;
 
                        if (!tile->media_gt)
                                continue;
 
                        xe_gt_tlb_invalidation_fence_init(tile->media_gt,
-                                                         &fence[fence_id], 
true);
+                                                         __fence, true);
 
                        err = xe_gt_tlb_invalidation_range(tile->media_gt,
-                                                          &fence[fence_id],
+                                                          __fence,
                                                           start,
                                                           end,
                                                           vm->usm.asid);
                        if (err)
                                goto wait;
                        ++fence_id;
+                       ++__fence;
                }
        }
 
 wait:
-       for (id = 0; id < fence_id; ++id)
-               xe_gt_tlb_invalidation_fence_wait(&fence[id]);
+       if (!fences) {
+               for (id = 0; id < fence_id; ++id)
+                       xe_gt_tlb_invalidation_fence_wait(&fence[id]);
+       }
 
        return err;
 }
@@ -3958,7 +3965,8 @@ int xe_vm_invalidate_vma(struct xe_vma *vma)
 
        xe_device_wmb(xe);
 
-       ret = xe_vm_range_tilemask_tlb_invalidation(xe_vma_vm(vma), 
xe_vma_start(vma),
+       ret = xe_vm_range_tilemask_tlb_invalidation(xe_vma_vm(vma), NULL,
+                                                   xe_vma_start(vma),
                                                    xe_vma_end(vma), tile_mask);
 
        /* WRITE_ONCE pairs with READ_ONCE in xe_vm_has_valid_gpu_mapping() */
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 3475a118f666..d1c3c9aa8d03 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -22,6 +22,7 @@ struct dma_fence;
 
 struct xe_exec_queue;
 struct xe_file;
+struct xe_gt_tlb_invalidation_fence;
 struct xe_sync_entry;
 struct xe_svm_range;
 struct drm_exec;
@@ -228,8 +229,9 @@ struct dma_fence *xe_vm_range_rebind(struct xe_vm *vm,
 struct dma_fence *xe_vm_range_unbind(struct xe_vm *vm,
                                     struct xe_svm_range *range);
 
-int xe_vm_range_tilemask_tlb_invalidation(struct xe_vm *vm, u64 start,
-                                         u64 end, u8 tile_mask);
+int xe_vm_range_tilemask_tlb_invalidation(struct xe_vm *vm,
+                                         struct xe_gt_tlb_invalidation_fence 
*fences,
+                                         u64 start, u64 end, u8 tile_mask);
 
 int xe_vm_invalidate_vma(struct xe_vma *vma);
 
-- 
2.50.1

Reply via email to