aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/xe/xe_pt.c65
-rw-r--r--drivers/gpu/drm/xe/xe_pt.h3
-rw-r--r--drivers/gpu/drm/xe/xe_vm.c66
-rw-r--r--drivers/gpu/drm/xe/xe_vm.h11
-rw-r--r--drivers/gpu/drm/xe/xe_vm_types.h1
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];
/**