diff options
-rw-r--r-- | drivers/gpu/drm/xe/xe_pt.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_pt.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_vm.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_vm.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_vm_types.h | 1 |
5 files changed, 74 insertions, 72 deletions
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c index 46ef9df34a2e..de1030a47588 100644 --- a/drivers/gpu/drm/xe/xe_pt.c +++ b/drivers/gpu/drm/xe/xe_pt.c @@ -50,17 +50,19 @@ static struct xe_pt *xe_pt_entry(struct xe_pt_dir *pt_dir, unsigned int index) static u64 __xe_pt_empty_pte(struct xe_tile *tile, struct xe_vm *vm, unsigned int level) { - u16 pat_index = tile_to_xe(tile)->pat.idx[XE_CACHE_WB]; + struct xe_device *xe = tile_to_xe(tile); + u16 pat_index = xe->pat.idx[XE_CACHE_WB]; u8 id = tile->id; - if (!vm->scratch_bo[id]) + if (!xe_vm_has_scratch(vm)) return 0; - if (level > 0) + if (level > MAX_HUGEPTE_LEVEL) return vm->pt_ops->pde_encode_bo(vm->scratch_pt[id][level - 1]->bo, 0, pat_index); - return vm->pt_ops->pte_encode_bo(vm->scratch_bo[id], 0, pat_index, 0); + return vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level, IS_DGFX(xe), 0) | + XE_PTE_NULL; } /** @@ -135,7 +137,7 @@ void xe_pt_populate_empty(struct xe_tile *tile, struct xe_vm *vm, u64 empty; int i; - if (!vm->scratch_bo[tile->id]) { + if (!xe_vm_has_scratch(vm)) { /* * FIXME: Some memory is allocated already allocated to zero? * Find out which memory that is and avoid this memset... @@ -195,57 +197,6 @@ void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred) } /** - * xe_pt_create_scratch() - Setup a scratch memory pagetable tree for the - * given tile and vm. - * @xe: xe device. - * @tile: tile to set up for. - * @vm: vm to set up for. - * - * Sets up a pagetable tree with one page-table per level and a single - * leaf bo. All pagetable entries point to the single page-table or, - * for L0, the single bo one level below. - * - * Return: 0 on success, negative error code on error. - */ -int xe_pt_create_scratch(struct xe_device *xe, struct xe_tile *tile, - struct xe_vm *vm) -{ - u8 id = tile->id; - unsigned int flags; - int i; - - /* - * So we don't need to worry about 64K TLB hints when dealing with - * scratch entires, rather keep the scratch page in system memory on - * platforms where 64K pages are needed for VRAM. - */ - flags = XE_BO_CREATE_PINNED_BIT; - if (vm->flags & XE_VM_FLAG_64K) - flags |= XE_BO_CREATE_SYSTEM_BIT; - else - flags |= XE_BO_CREATE_VRAM_IF_DGFX(tile); - - vm->scratch_bo[id] = xe_bo_create_pin_map(xe, tile, vm, SZ_4K, - ttm_bo_type_kernel, - flags); - if (IS_ERR(vm->scratch_bo[id])) - return PTR_ERR(vm->scratch_bo[id]); - - xe_map_memset(vm->xe, &vm->scratch_bo[id]->vmap, 0, 0, - vm->scratch_bo[id]->size); - - for (i = 0; i < vm->pt_root[id]->level; i++) { - vm->scratch_pt[id][i] = xe_pt_create(vm, tile, i); - if (IS_ERR(vm->scratch_pt[id][i])) - return PTR_ERR(vm->scratch_pt[id][i]); - - xe_pt_populate_empty(tile, vm, vm->scratch_pt[id][i]); - } - - return 0; -} - -/** * DOC: Pagetable building * * Below we use the term "page-table" for both page-directories, containing @@ -1289,7 +1240,7 @@ __xe_pt_bind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_exec_queue * it needs to be done here. */ if ((rebind && !xe_vm_in_lr_mode(vm) && !vm->batch_invalidate_tlb) || - (!rebind && vm->scratch_bo[tile->id] && xe_vm_in_preempt_fence_mode(vm))) { + (!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) { ifence = kzalloc(sizeof(*ifence), GFP_KERNEL); if (!ifence) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_pt.h b/drivers/gpu/drm/xe/xe_pt.h index ba2f3325c84d..71a4fbfcff43 100644 --- a/drivers/gpu/drm/xe/xe_pt.h +++ b/drivers/gpu/drm/xe/xe_pt.h @@ -29,9 +29,6 @@ unsigned int xe_pt_shift(unsigned int level); struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile, unsigned int level); -int xe_pt_create_scratch(struct xe_device *xe, struct xe_tile *tile, - struct xe_vm *vm); - void xe_pt_populate_empty(struct xe_tile *tile, struct xe_vm *vm, struct xe_pt *pt); diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index d589beb99fe6..e190469ec03a 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1348,6 +1348,57 @@ static const struct xe_pt_ops xelp_pt_ops = { static void vm_destroy_work_func(struct work_struct *w); +/** + * xe_vm_create_scratch() - Setup a scratch memory pagetable tree for the + * given tile and vm. + * @xe: xe device. + * @tile: tile to set up for. + * @vm: vm to set up for. + * + * Sets up a pagetable tree with one page-table per level and a single + * leaf PTE. All pagetable entries point to the single page-table or, + * for MAX_HUGEPTE_LEVEL, a NULL huge PTE returning 0 on read and + * writes become NOPs. + * + * Return: 0 on success, negative error code on error. + */ +static int xe_vm_create_scratch(struct xe_device *xe, struct xe_tile *tile, + struct xe_vm *vm) +{ + u8 id = tile->id; + int i; + + for (i = MAX_HUGEPTE_LEVEL; i < vm->pt_root[id]->level; i++) { + vm->scratch_pt[id][i] = xe_pt_create(vm, tile, i); + if (IS_ERR(vm->scratch_pt[id][i])) + return PTR_ERR(vm->scratch_pt[id][i]); + + xe_pt_populate_empty(tile, vm, vm->scratch_pt[id][i]); + } + + return 0; +} + +static void xe_vm_free_scratch(struct xe_vm *vm) +{ + struct xe_tile *tile; + u8 id; + + if (!xe_vm_has_scratch(vm)) + return; + + for_each_tile(tile, vm->xe, id) { + u32 i; + + if (!vm->pt_root[id]) + continue; + + for (i = MAX_HUGEPTE_LEVEL; i < vm->pt_root[id]->level; ++i) + if (vm->scratch_pt[id][i]) + xe_pt_destroy(vm->scratch_pt[id][i], vm->flags, NULL); + } +} + struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) { struct drm_gem_object *vm_resv_obj; @@ -1424,12 +1475,12 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) } } - if (flags & XE_VM_FLAG_SCRATCH_PAGE) { + if (xe_vm_has_scratch(vm)) { for_each_tile(tile, xe, id) { if (!vm->pt_root[id]) continue; - err = xe_pt_create_scratch(xe, tile, vm); + err = xe_vm_create_scratch(xe, tile, vm); if (err) goto err_unlock_close; } @@ -1575,16 +1626,9 @@ void xe_vm_close_and_put(struct xe_vm *vm) * install a fence to resv. Hence it's safe to * destroy the pagetables immediately. */ - for_each_tile(tile, xe, id) { - if (vm->scratch_bo[id]) { - u32 i; + xe_vm_free_scratch(vm); - xe_bo_unpin(vm->scratch_bo[id]); - xe_bo_put(vm->scratch_bo[id]); - for (i = 0; i < vm->pt_root[id]->level; i++) - xe_pt_destroy(vm->scratch_pt[id][i], vm->flags, - NULL); - } + for_each_tile(tile, xe, id) { if (vm->pt_root[id]) { xe_pt_destroy(vm->pt_root[id], vm->flags, NULL); vm->pt_root[id] = NULL; diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h index 12bb5d79487f..a1907544cc4f 100644 --- a/drivers/gpu/drm/xe/xe_vm.h +++ b/drivers/gpu/drm/xe/xe_vm.h @@ -63,6 +63,17 @@ static inline bool xe_vm_is_closed_or_banned(struct xe_vm *vm) struct xe_vma * xe_vm_find_overlapping_vma(struct xe_vm *vm, u64 start, u64 range); +/** + * xe_vm_has_scratch() - Whether the vm is configured for scratch PTEs + * @vm: The vm + * + * Return: whether the vm populates unmapped areas with scratch PTEs + */ +static inline bool xe_vm_has_scratch(const struct xe_vm *vm) +{ + return vm->flags & XE_VM_FLAG_SCRATCH_PAGE; +} + static inline struct xe_vm *gpuva_to_vm(struct drm_gpuva *gpuva) { return container_of(gpuva->vm, struct xe_vm, gpuvm); diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h index e70ec6b2fabe..15471025a44f 100644 --- a/drivers/gpu/drm/xe/xe_vm_types.h +++ b/drivers/gpu/drm/xe/xe_vm_types.h @@ -151,7 +151,6 @@ struct xe_vm { u64 size; struct xe_pt *pt_root[XE_MAX_TILES_PER_DEVICE]; - struct xe_bo *scratch_bo[XE_MAX_TILES_PER_DEVICE]; struct xe_pt *scratch_pt[XE_MAX_TILES_PER_DEVICE][XE_VM_MAX_LEVEL]; /** |