Commit 18b1ce0b authored by Simona Vetter's avatar Simona Vetter
Browse files

Merge tag 'drm-xe-fixes-2025-10-23' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes



UAPI Changes:
 - Make madvise autoreset an explicit behavior requested by userspace
   (Thomas Hellström)

Driver Changes:
 - Drop XE_VMA flag conversion and ensure GPUVA flags are passed around
   (homas Hellström)
 - Fix missing wq allocation error checking (Matthew Brost)

Signed-off-by: default avatarSimona Vetter <simona.vetter@ffwll.ch>
From: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/4p2glnvgifc6osjlvzv23xhsyqhw4diqlfxz54lmg7robv44bi@nwd37zpqfa2l
parents adb0971a ce29214a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -292,6 +292,9 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt)
		ggtt->pt_ops = &xelp_pt_ops;

	ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM);
	if (!ggtt->wq)
		return -ENOMEM;

	__xe_ggtt_init_early(ggtt, xe_wopcm_size(xe));

	err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt);
+2 −2
Original line number Diff line number Diff line
@@ -2022,7 +2022,7 @@ static int op_prepare(struct xe_vm *vm,
	case DRM_GPUVA_OP_MAP:
		if ((!op->map.immediate && xe_vm_in_fault_mode(vm) &&
		     !op->map.invalidate_on_bind) ||
		    op->map.is_cpu_addr_mirror)
		    (op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR))
			break;

		err = bind_op_prepare(vm, tile, pt_update_ops, op->map.vma,
@@ -2252,7 +2252,7 @@ static void op_commit(struct xe_vm *vm,
	switch (op->base.op) {
	case DRM_GPUVA_OP_MAP:
		if ((!op->map.immediate && xe_vm_in_fault_mode(vm)) ||
		    op->map.is_cpu_addr_mirror)
		    (op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR))
			break;

		bind_op_commit(vm, tile, pt_update_ops, op->map.vma, fence,
+5 −0
Original line number Diff line number Diff line
@@ -302,6 +302,11 @@ static int xe_svm_range_set_default_attr(struct xe_vm *vm, u64 range_start, u64
	if (!vma)
		return -EINVAL;

	if (!(vma->gpuva.flags & XE_VMA_MADV_AUTORESET)) {
		drm_dbg(&vm->xe->drm, "Skipping madvise reset for vma.\n");
		return 0;
	}

	if (xe_vma_has_default_mem_attrs(vma))
		return 0;

+37 −59
Original line number Diff line number Diff line
@@ -616,6 +616,13 @@ static void xe_vma_ops_incr_pt_update_ops(struct xe_vma_ops *vops, u8 tile_mask,
			vops->pt_update_ops[i].num_ops += inc_val;
}

#define XE_VMA_CREATE_MASK (		    \
	XE_VMA_READ_ONLY |		    \
	XE_VMA_DUMPABLE |		    \
	XE_VMA_SYSTEM_ALLOCATOR |           \
	DRM_GPUVA_SPARSE |		    \
	XE_VMA_MADV_AUTORESET)

static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
				  u8 tile_mask)
{
@@ -628,8 +635,7 @@ static void xe_vm_populate_rebind(struct xe_vma_op *op, struct xe_vma *vma,
	op->base.map.gem.offset = vma->gpuva.gem.offset;
	op->map.vma = vma;
	op->map.immediate = true;
	op->map.dumpable = vma->gpuva.flags & XE_VMA_DUMPABLE;
	op->map.is_null = xe_vma_is_null(vma);
	op->map.vma_flags = vma->gpuva.flags & XE_VMA_CREATE_MASK;
}

static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma,
@@ -932,11 +938,6 @@ static void xe_vma_free(struct xe_vma *vma)
		kfree(vma);
}

#define VMA_CREATE_FLAG_READ_ONLY		BIT(0)
#define VMA_CREATE_FLAG_IS_NULL			BIT(1)
#define VMA_CREATE_FLAG_DUMPABLE		BIT(2)
#define VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR	BIT(3)

static struct xe_vma *xe_vma_create(struct xe_vm *vm,
				    struct xe_bo *bo,
				    u64 bo_offset_or_userptr,
@@ -947,11 +948,8 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
	struct xe_vma *vma;
	struct xe_tile *tile;
	u8 id;
	bool read_only = (flags & VMA_CREATE_FLAG_READ_ONLY);
	bool is_null = (flags & VMA_CREATE_FLAG_IS_NULL);
	bool dumpable = (flags & VMA_CREATE_FLAG_DUMPABLE);
	bool is_cpu_addr_mirror =
		(flags & VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR);
	bool is_null = (flags & DRM_GPUVA_SPARSE);
	bool is_cpu_addr_mirror = (flags & XE_VMA_SYSTEM_ALLOCATOR);

	xe_assert(vm->xe, start < end);
	xe_assert(vm->xe, end < vm->size);
@@ -972,10 +970,6 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
		if (!vma)
			return ERR_PTR(-ENOMEM);

		if (is_cpu_addr_mirror)
			vma->gpuva.flags |= XE_VMA_SYSTEM_ALLOCATOR;
		if (is_null)
			vma->gpuva.flags |= DRM_GPUVA_SPARSE;
		if (bo)
			vma->gpuva.gem.obj = &bo->ttm.base;
	}
@@ -986,10 +980,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
	vma->gpuva.vm = &vm->gpuvm;
	vma->gpuva.va.addr = start;
	vma->gpuva.va.range = end - start + 1;
	if (read_only)
		vma->gpuva.flags |= XE_VMA_READ_ONLY;
	if (dumpable)
		vma->gpuva.flags |= XE_VMA_DUMPABLE;
	vma->gpuva.flags = flags;

	for_each_tile(tile, vm->xe, id)
		vma->tile_mask |= 0x1 << id;
@@ -2272,12 +2263,16 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
		if (__op->op == DRM_GPUVA_OP_MAP) {
			op->map.immediate =
				flags & DRM_XE_VM_BIND_FLAG_IMMEDIATE;
			op->map.read_only =
				flags & DRM_XE_VM_BIND_FLAG_READONLY;
			op->map.is_null = flags & DRM_XE_VM_BIND_FLAG_NULL;
			op->map.is_cpu_addr_mirror = flags &
				DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;
			op->map.dumpable = flags & DRM_XE_VM_BIND_FLAG_DUMPABLE;
			if (flags & DRM_XE_VM_BIND_FLAG_READONLY)
				op->map.vma_flags |= XE_VMA_READ_ONLY;
			if (flags & DRM_XE_VM_BIND_FLAG_NULL)
				op->map.vma_flags |= DRM_GPUVA_SPARSE;
			if (flags & DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR)
				op->map.vma_flags |= XE_VMA_SYSTEM_ALLOCATOR;
			if (flags & DRM_XE_VM_BIND_FLAG_DUMPABLE)
				op->map.vma_flags |= XE_VMA_DUMPABLE;
			if (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET)
				op->map.vma_flags |= XE_VMA_MADV_AUTORESET;
			op->map.pat_index = pat_index;
			op->map.invalidate_on_bind =
				__xe_vm_needs_clear_scratch_pages(vm, flags);
@@ -2590,14 +2585,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
				.pat_index = op->map.pat_index,
			};

			flags |= op->map.read_only ?
				VMA_CREATE_FLAG_READ_ONLY : 0;
			flags |= op->map.is_null ?
				VMA_CREATE_FLAG_IS_NULL : 0;
			flags |= op->map.dumpable ?
				VMA_CREATE_FLAG_DUMPABLE : 0;
			flags |= op->map.is_cpu_addr_mirror ?
				VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0;
			flags |= op->map.vma_flags & XE_VMA_CREATE_MASK;

			vma = new_vma(vm, &op->base.map, &default_attr,
				      flags);
@@ -2606,7 +2594,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,

			op->map.vma = vma;
			if (((op->map.immediate || !xe_vm_in_fault_mode(vm)) &&
			     !op->map.is_cpu_addr_mirror) ||
			     !(op->map.vma_flags & XE_VMA_SYSTEM_ALLOCATOR)) ||
			    op->map.invalidate_on_bind)
				xe_vma_ops_incr_pt_update_ops(vops,
							      op->tile_mask, 1);
@@ -2637,18 +2625,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
			op->remap.start = xe_vma_start(old);
			op->remap.range = xe_vma_size(old);

			flags |= op->base.remap.unmap->va->flags &
				XE_VMA_READ_ONLY ?
				VMA_CREATE_FLAG_READ_ONLY : 0;
			flags |= op->base.remap.unmap->va->flags &
				DRM_GPUVA_SPARSE ?
				VMA_CREATE_FLAG_IS_NULL : 0;
			flags |= op->base.remap.unmap->va->flags &
				XE_VMA_DUMPABLE ?
				VMA_CREATE_FLAG_DUMPABLE : 0;
			flags |= xe_vma_is_cpu_addr_mirror(old) ?
				VMA_CREATE_FLAG_IS_SYSTEM_ALLOCATOR : 0;

			flags |= op->base.remap.unmap->va->flags & XE_VMA_CREATE_MASK;
			if (op->base.remap.prev) {
				vma = new_vma(vm, op->base.remap.prev,
					      &old->attr, flags);
@@ -3279,7 +3256,8 @@ ALLOW_ERROR_INJECTION(vm_bind_ioctl_ops_execute, ERRNO);
	 DRM_XE_VM_BIND_FLAG_NULL | \
	 DRM_XE_VM_BIND_FLAG_DUMPABLE | \
	 DRM_XE_VM_BIND_FLAG_CHECK_PXP | \
	 DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR)
	 DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR | \
	 DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET)

#ifdef TEST_VM_OPS_ERROR
#define SUPPORTED_FLAGS	(SUPPORTED_FLAGS_STUB | FORCE_OP_ERROR)
@@ -3394,7 +3372,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
		    XE_IOCTL_DBG(xe,  (prefetch_region != DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC &&
				       !(BIT(prefetch_region) & xe->info.mem_region_mask))) ||
		    XE_IOCTL_DBG(xe, obj &&
				 op == DRM_XE_VM_BIND_OP_UNMAP)) {
				 op == DRM_XE_VM_BIND_OP_UNMAP) ||
		    XE_IOCTL_DBG(xe, (flags & DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET) &&
				 (!is_cpu_addr_mirror || op != DRM_XE_VM_BIND_OP_MAP))) {
			err = -EINVAL;
			goto free_bind_ops;
		}
@@ -4212,7 +4192,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
	struct xe_vma_ops vops;
	struct drm_gpuva_ops *ops = NULL;
	struct drm_gpuva_op *__op;
	bool is_cpu_addr_mirror = false;
	unsigned int vma_flags = 0;
	bool remap_op = false;
	struct xe_vma_mem_attr tmp_attr;
	u16 default_pat;
@@ -4242,15 +4222,17 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
				vma = gpuva_to_vma(op->base.unmap.va);
				XE_WARN_ON(!xe_vma_has_default_mem_attrs(vma));
				default_pat = vma->attr.default_pat_index;
				vma_flags = vma->gpuva.flags;
			}

			if (__op->op == DRM_GPUVA_OP_REMAP) {
				vma = gpuva_to_vma(op->base.remap.unmap->va);
				default_pat = vma->attr.default_pat_index;
				vma_flags = vma->gpuva.flags;
			}

			if (__op->op == DRM_GPUVA_OP_MAP) {
				op->map.is_cpu_addr_mirror = true;
				op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK;
				op->map.pat_index = default_pat;
			}
		} else {
@@ -4259,11 +4241,7 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
				xe_assert(vm->xe, !remap_op);
				xe_assert(vm->xe, xe_vma_has_no_bo(vma));
				remap_op = true;

				if (xe_vma_is_cpu_addr_mirror(vma))
					is_cpu_addr_mirror = true;
				else
					is_cpu_addr_mirror = false;
				vma_flags = vma->gpuva.flags;
			}

			if (__op->op == DRM_GPUVA_OP_MAP) {
@@ -4272,10 +4250,10 @@ static int xe_vm_alloc_vma(struct xe_vm *vm,
				/*
				 * In case of madvise ops DRM_GPUVA_OP_MAP is
				 * always after DRM_GPUVA_OP_REMAP, so ensure
				 * we assign op->map.is_cpu_addr_mirror true
				 * if REMAP is for xe_vma_is_cpu_addr_mirror vma
				 * to propagate the flags from the vma we're
				 * unmapping.
				 */
				op->map.is_cpu_addr_mirror = is_cpu_addr_mirror;
				op->map.vma_flags |= vma_flags & XE_VMA_CREATE_MASK;
			}
		}
		print_op(vm->xe, __op);
+2 −8
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct xe_vm_pgtable_update_op;
#define XE_VMA_PTE_COMPACT	(DRM_GPUVA_USERBITS << 7)
#define XE_VMA_DUMPABLE		(DRM_GPUVA_USERBITS << 8)
#define XE_VMA_SYSTEM_ALLOCATOR	(DRM_GPUVA_USERBITS << 9)
#define XE_VMA_MADV_AUTORESET	(DRM_GPUVA_USERBITS << 10)

/**
 * struct xe_vma_mem_attr - memory attributes associated with vma
@@ -345,17 +346,10 @@ struct xe_vm {
struct xe_vma_op_map {
	/** @vma: VMA to map */
	struct xe_vma *vma;
	unsigned int vma_flags;
	/** @immediate: Immediate bind */
	bool immediate;
	/** @read_only: Read only */
	bool read_only;
	/** @is_null: is NULL binding */
	bool is_null;
	/** @is_cpu_addr_mirror: is CPU address mirror binding */
	bool is_cpu_addr_mirror;
	/** @dumpable: whether BO is dumped on GPU hang */
	bool dumpable;
	/** @invalidate: invalidate the VMA before bind */
	bool invalidate_on_bind;
	/** @pat_index: The pat index to use for this operation. */
	u16 pat_index;
Loading