[PATCH 14/15] drm/xe: Convert xe_bo_create_pin_map() for exhaustive eviction

Thomas Hellström thomas.hellstrom at linux.intel.com
Thu Aug 14 13:14:57 UTC 2025


On Wed, 2025-08-13 at 21:18 -0700, Matthew Brost wrote:
> On Wed, Aug 13, 2025 at 12:51:20PM +0200, Thomas Hellström wrote:
> > Introduce an xe_bo_create_pin_map_novm() function that does not
> > take the drm_exec paramenter to simplify the conversion of many
> > callsites.
> > For the rest, ensure that the same drm_exec context that was used
> > for locking the vm is passed down to validation.
> > 
> > Use xe_validation_guard() where appropriate.
> > 
> > Signed-off-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>
> > ---
> >  drivers/gpu/drm/xe/display/intel_fbdev_fb.c   |  18 +--
> >  drivers/gpu/drm/xe/display/xe_dsb_buffer.c    |  10 +-
> >  drivers/gpu/drm/xe/display/xe_fb_pin.c        |  39 +++---
> >  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c      |   8 +-
> >  drivers/gpu/drm/xe/tests/xe_migrate.c         |   9 +-
> >  drivers/gpu/drm/xe/xe_bo.c                    |  53 +++++++-
> >  drivers/gpu/drm/xe/xe_bo.h                    |   6 +-
> >  drivers/gpu/drm/xe/xe_gsc.c                   |   8 +-
> >  drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c    |  24 ++--
> >  drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c |  24 ++--
> >  drivers/gpu/drm/xe/xe_guc_engine_activity.c   |  13 +-
> >  drivers/gpu/drm/xe/xe_lmtt.c                  |  12 +-
> >  drivers/gpu/drm/xe/xe_lrc.c                   |   7 +-
> >  drivers/gpu/drm/xe/xe_migrate.c               |  20 ++-
> >  drivers/gpu/drm/xe/xe_oa.c                    |   6 +-
> >  drivers/gpu/drm/xe/xe_pt.c                    |  10 +-
> >  drivers/gpu/drm/xe/xe_pt.h                    |   3 +-
> >  drivers/gpu/drm/xe/xe_pxp_submit.c            |  34 +++--
> >  drivers/gpu/drm/xe/xe_vm.c                    | 119 ++++++++++----
> > ----
> >  19 files changed, 252 insertions(+), 171 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
> > b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
> > index d96ba2b51065..8ea9a472113c 100644
> > --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
> > +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c
> > @@ -42,11 +42,11 @@ struct intel_framebuffer
> > *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
> >  	obj = ERR_PTR(-ENODEV);
> >  
> >  	if (!IS_DGFX(xe) && !XE_GT_WA(xe_root_mmio_gt(xe),
> > 22019338487_display)) {
> > -		obj = xe_bo_create_pin_map(xe,
> > xe_device_get_root_tile(xe),
> > -					   NULL, size,
> > -					   ttm_bo_type_kernel,
> > XE_BO_FLAG_SCANOUT |
> > -					   XE_BO_FLAG_STOLEN |
> > -					   XE_BO_FLAG_GGTT);
> > +		obj = xe_bo_create_pin_map_novm(xe,
> > xe_device_get_root_tile(xe),
> > +						size,
> > +						ttm_bo_type_kernel
> > , XE_BO_FLAG_SCANOUT |
> > +						XE_BO_FLAG_STOLEN
> > |
> > +						XE_BO_FLAG_GGTT,
> > false);
> >  		if (!IS_ERR(obj))
> >  			drm_info(&xe->drm, "Allocated fbdev into
> > stolen\n");
> >  		else
> > @@ -54,10 +54,10 @@ struct intel_framebuffer
> > *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
> >  	}
> >  
> >  	if (IS_ERR(obj)) {
> > -		obj = xe_bo_create_pin_map(xe,
> > xe_device_get_root_tile(xe), NULL, size,
> > -					   ttm_bo_type_kernel,
> > XE_BO_FLAG_SCANOUT |
> > -					  
> > XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
> > -					   XE_BO_FLAG_GGTT);
> > +		obj = xe_bo_create_pin_map_novm(xe,
> > xe_device_get_root_tile(xe), size,
> > +						ttm_bo_type_kernel
> > , XE_BO_FLAG_SCANOUT |
> > +						XE_BO_FLAG_VRAM_IF
> > _DGFX(xe_device_get_root_tile(xe)) |
> > +						XE_BO_FLAG_GGTT,
> > false);
> >  	}
> >  
> >  	if (IS_ERR(obj)) {
> > diff --git a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
> > b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
> > index 9f941fc2e36b..58581d7aaae6 100644
> > --- a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
> > +++ b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c
> > @@ -43,11 +43,11 @@ bool intel_dsb_buffer_create(struct intel_crtc
> > *crtc, struct intel_dsb_buffer *d
> >  		return false;
> >  
> >  	/* Set scanout flag for WC mapping */
> > -	obj = xe_bo_create_pin_map(xe,
> > xe_device_get_root_tile(xe),
> > -				   NULL, PAGE_ALIGN(size),
> > -				   ttm_bo_type_kernel,
> > -				  
> > XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
> > -				   XE_BO_FLAG_SCANOUT |
> > XE_BO_FLAG_GGTT);
> > +	obj = xe_bo_create_pin_map_novm(xe,
> > xe_device_get_root_tile(xe),
> > +					PAGE_ALIGN(size),
> > +					ttm_bo_type_kernel,
> > +					XE_BO_FLAG_VRAM_IF_DGFX(xe
> > _device_get_root_tile(xe)) |
> > +					XE_BO_FLAG_SCANOUT |
> > XE_BO_FLAG_GGTT, false);
> >  	if (IS_ERR(obj)) {
> >  		kfree(vma);
> >  		return false;
> > diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c
> > b/drivers/gpu/drm/xe/display/xe_fb_pin.c
> > index d46ff7ebb0a1..d8e15ebb740c 100644
> > --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
> > +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
> > @@ -102,32 +102,23 @@ static int __xe_pin_fb_vma_dpt(const struct
> > intel_framebuffer *fb,
> >  				 XE_PAGE_SIZE);
> >  
> >  	if (IS_DGFX(xe))
> > -		dpt = xe_bo_create_pin_map_at_novm(xe, tile0,
> > -						   dpt_size,
> > ~0ull,
> > -						  
> > ttm_bo_type_kernel,
> > -						   true,
> > -						  
> > XE_BO_FLAG_VRAM0 |
> > -						   XE_BO_FLAG_GGTT
> > |
> > -						  
> > XE_BO_FLAG_PAGETABLE,
> > -						   alignment,
> > false);
> > +		dpt = xe_bo_create_pin_map_novm(xe, tile0,
> > dpt_size,
> > +						ttm_bo_type_kernel
> > ,
> > +						XE_BO_FLAG_VRAM0 |
> > +						XE_BO_FLAG_GGTT |
> > +						XE_BO_FLAG_PAGETAB
> > LE, true);
> >  	else
> > -		dpt = xe_bo_create_pin_map_at_novm(xe, tile0,
> > -						   dpt_size, 
> > ~0ull,
> > -						  
> > ttm_bo_type_kernel,
> > -						   true,
> > -						  
> > XE_BO_FLAG_STOLEN |
> > -						   XE_BO_FLAG_GGTT
> > |
> > -						  
> > XE_BO_FLAG_PAGETABLE,
> > -						   alignment,
> > false);
> > +		dpt = xe_bo_create_pin_map_novm(xe, tile0,
> > dpt_size,
> > +						ttm_bo_type_kernel
> > ,
> > +						XE_BO_FLAG_STOLEN
> > |
> > +						XE_BO_FLAG_GGTT |
> > +						XE_BO_FLAG_PAGETAB
> > LE, true);
> >  	if (IS_ERR(dpt))
> > -		dpt = xe_bo_create_pin_map_at_novm(xe, tile0,
> > -						   dpt_size, 
> > ~0ull,
> > -						  
> > ttm_bo_type_kernel,
> > -						   true,
> > -						  
> > XE_BO_FLAG_SYSTEM |
> > -						   XE_BO_FLAG_GGTT
> > |
> > -						  
> > XE_BO_FLAG_PAGETABLE,
> > -						   alignment,
> > false);
> > +		dpt = xe_bo_create_pin_map_novm(xe, tile0,
> > dpt_size,
> > +						ttm_bo_type_kernel
> > ,
> > +						XE_BO_FLAG_SYSTEM
> > |
> > +						XE_BO_FLAG_GGTT |
> > +						XE_BO_FLAG_PAGETAB
> > LE, true);
> >  	if (IS_ERR(dpt))
> >  		return PTR_ERR(dpt);
> >  
> > diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
> > b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
> > index 30f1073141fc..4ae847b628e2 100644
> > --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
> > +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
> > @@ -72,10 +72,10 @@ static int
> > intel_hdcp_gsc_initialize_message(struct xe_device *xe,
> >  	int ret = 0;
> >  
> >  	/* allocate object of two page for HDCP command memory and
> > store it */
> > -	bo = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe),
> > NULL, PAGE_SIZE * 2,
> > -				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > -				  XE_BO_FLAG_GGTT);
> > +	bo = xe_bo_create_pin_map_novm(xe,
> > xe_device_get_root_tile(xe), PAGE_SIZE * 2,
> > +				       ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > +				       XE_BO_FLAG_GGTT, false);
> >  
> >  	if (IS_ERR(bo)) {
> >  		drm_err(&xe->drm, "Failed to allocate bo for HDCP
> > streaming command!\n");
> > diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c
> > b/drivers/gpu/drm/xe/tests/xe_migrate.c
> > index afa794e56065..5904d658d1f2 100644
> > --- a/drivers/gpu/drm/xe/tests/xe_migrate.c
> > +++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
> > @@ -204,7 +204,8 @@ static void xe_migrate_sanity_test(struct
> > xe_migrate *m, struct kunit *test,
> >  
> >  	big = xe_bo_create_pin_map(xe, tile, m->q->vm, SZ_4M,
> >  				   ttm_bo_type_kernel,
> > -				   XE_BO_FLAG_VRAM_IF_DGFX(tile));
> > +				   XE_BO_FLAG_VRAM_IF_DGFX(tile),
> > +				   exec);
> >  	if (IS_ERR(big)) {
> >  		KUNIT_FAIL(test, "Failed to allocate bo: %li\n",
> > PTR_ERR(big));
> >  		goto vunmap;
> > @@ -212,7 +213,8 @@ static void xe_migrate_sanity_test(struct
> > xe_migrate *m, struct kunit *test,
> >  
> >  	pt = xe_bo_create_pin_map(xe, tile, m->q->vm,
> > XE_PAGE_SIZE,
> >  				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_VRAM_IF_DGFX(tile));
> > +				  XE_BO_FLAG_VRAM_IF_DGFX(tile),
> > +				  exec);
> >  	if (IS_ERR(pt)) {
> >  		KUNIT_FAIL(test, "Failed to allocate fake pt:
> > %li\n",
> >  			   PTR_ERR(pt));
> > @@ -222,7 +224,8 @@ static void xe_migrate_sanity_test(struct
> > xe_migrate *m, struct kunit *test,
> >  	tiny = xe_bo_create_pin_map(xe, tile, m->q->vm,
> >  				    2 * SZ_4K,
> >  				    ttm_bo_type_kernel,
> > -				   
> > XE_BO_FLAG_VRAM_IF_DGFX(tile));
> > +				    XE_BO_FLAG_VRAM_IF_DGFX(tile),
> > +				    exec);
> >  	if (IS_ERR(tiny)) {
> >  		KUNIT_FAIL(test, "Failed to allocate tiny fake pt:
> > %li\n",
> >  			   PTR_ERR(tiny));
> > diff --git a/drivers/gpu/drm/xe/xe_bo.c
> > b/drivers/gpu/drm/xe/xe_bo.c
> > index c9928d4ee5a0..82bf158426ad 100644
> > --- a/drivers/gpu/drm/xe/xe_bo.c
> > +++ b/drivers/gpu/drm/xe/xe_bo.c
> > @@ -2343,16 +2343,60 @@ xe_bo_create_pin_map_at_novm(struct
> > xe_device *xe, struct xe_tile *tile,
> >  	return ret ? ERR_PTR(ret) : bo;
> >  }
> >  
> > +/**
> > + * xe_bo_create_pin_map() - Create pinned and mapped bo
> > + * @xe: The xe device.
> > + * @tile: The tile to select for migration of this bo, and the
> > tile used for
> > + * @vm: The vm to associate the buffer object with. The vm's resv
> > must be locked
> > + * with the transaction represented by @exec.
> > + * GGTT binding if any. Only to be non-NULL for ttm_bo_type_kernel
> > bos.
> > + * @size: The storage size to use for the bo.
> > + * @type: The TTM buffer object type.
> > + * @flags: XE_BO_FLAG_ flags.
> > + * @exec: The drm_exec transaction to use for exhaustive eviction,
> > and
> > + * previously used for locking @vm's resv.
> > + *
> > + * Create a pinned and mapped bo. The bo will be external and not
> > associated
> > + * with a VM.
> > + *
> > + * Return: The buffer object on success. Negative error pointer on
> > failure.
> > + * In particular, the function may return ERR_PTR(%-EINTR) if
> > @intr was set
> > + * to true on entry.
> > + */
> >  struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct
> > xe_tile *tile,
> >  				   struct xe_vm *vm, size_t size,
> > -				   enum ttm_bo_type type, u32
> > flags)
> > +				   enum ttm_bo_type type, u32
> > flags,
> > +				   struct drm_exec *exec)
> >  {
> > -	struct drm_exec *exec = vm ? xe_vm_validation_exec(vm) :
> > XE_VALIDATION_UNIMPLEMENTED;
> > -
> > +	xe_assert(xe, exec);
> >  	return xe_bo_create_pin_map_at_aligned(xe, tile, vm, size,
> > ~0ull, type, flags,
> >  					       true, 0, exec);
> >  }
> >  
> > +/**
> > + * xe_bo_create_pin_map_novm() - Create pinned and mapped bo
> > + * @xe: The xe device.
> > + * @tile: The tile to select for migration of this bo, and the
> > tile used for
> > + * GGTT binding if any. Only to be non-NULL for ttm_bo_type_kernel
> > bos.
> > + * @size: The storage size to use for the bo.
> > + * @type: The TTM buffer object type.
> > + * @flags: XE_BO_FLAG_ flags.
> > + * @intr: Whether to execut any waits for backing store
> > interruptible.
> > + *
> > + * Create a pinned and mapped bo. The bo will be external and not
> > associated
> > + * with a VM.
> > + *
> > + * Return: The buffer object on success. Negative error pointer on
> > failure.
> > + * In particular, the function may return ERR_PTR(%-EINTR) if
> > @intr was set
> > + * to true on entry.
> > + */
> > +struct xe_bo *xe_bo_create_pin_map_novm(struct xe_device *xe,
> > struct xe_tile *tile,
> > +					size_t size, enum
> > ttm_bo_type type, u32 flags,
> > +					bool intr)
> > +{
> > +	return xe_bo_create_pin_map_at_novm(xe, tile, size, ~0ull,
> > type, flags, true, 0, intr);
> > +}
> > +
> >  static void __xe_bo_unpin_map_no_vm(void *arg)
> >  {
> >  	xe_bo_unpin_map_no_vm(arg);
> > @@ -2365,8 +2409,7 @@ struct xe_bo
> > *xe_managed_bo_create_pin_map(struct xe_device *xe, struct xe_tile
> >  	int ret;
> >  
> >  	KUNIT_STATIC_STUB_REDIRECT(xe_managed_bo_create_pin_map,
> > xe, tile, size, flags);
> > -
> > -	bo = xe_bo_create_pin_map(xe, tile, NULL, size,
> > ttm_bo_type_kernel, flags);
> > +	bo = xe_bo_create_pin_map_novm(xe, tile, size,
> > ttm_bo_type_kernel, flags, true);
> >  	if (IS_ERR(bo))
> >  		return bo;
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_bo.h
> > b/drivers/gpu/drm/xe/xe_bo.h
> > index d06266af9662..802e3c7d7872 100644
> > --- a/drivers/gpu/drm/xe/xe_bo.h
> > +++ b/drivers/gpu/drm/xe/xe_bo.h
> > @@ -108,7 +108,11 @@ struct xe_bo *xe_bo_create_user(struct
> > xe_device *xe, struct xe_vm *vm, size_t s
> >  				u16 cpu_caching, u32 flags, struct
> > drm_exec *exec);
> >  struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct
> > xe_tile *tile,
> >  				   struct xe_vm *vm, size_t size,
> > -				   enum ttm_bo_type type, u32
> > flags);
> > +				   enum ttm_bo_type type, u32
> > flags,
> > +				   struct drm_exec *exec);
> > +struct xe_bo *xe_bo_create_pin_map_novm(struct xe_device *xe,
> > struct xe_tile *tile,
> > +					size_t size, enum
> > ttm_bo_type type, u32 flags,
> > +					bool intr);
> >  struct xe_bo *
> >  xe_bo_create_pin_map_at_novm(struct xe_device *xe, struct xe_tile
> > *tile,
> >  			     size_t size, u64 offset, enum
> > ttm_bo_type type,
> > diff --git a/drivers/gpu/drm/xe/xe_gsc.c
> > b/drivers/gpu/drm/xe/xe_gsc.c
> > index f5ae28af60d4..83d61bf8ec62 100644
> > --- a/drivers/gpu/drm/xe/xe_gsc.c
> > +++ b/drivers/gpu/drm/xe/xe_gsc.c
> > @@ -136,10 +136,10 @@ static int query_compatibility_version(struct
> > xe_gsc *gsc)
> >  	u64 ggtt_offset;
> >  	int err;
> >  
> > -	bo = xe_bo_create_pin_map(xe, tile, NULL, GSC_VER_PKT_SZ *
> > 2,
> > -				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > -				  XE_BO_FLAG_GGTT);
> > +	bo = xe_bo_create_pin_map_novm(xe, tile, GSC_VER_PKT_SZ *
> > 2,
> > +				       ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > +				       XE_BO_FLAG_GGTT, false);
> >  	if (IS_ERR(bo)) {
> >  		xe_gt_err(gt, "failed to allocate bo for GSC
> > version query\n");
> >  		return PTR_ERR(bo);
> > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> > b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> > index 906011671b60..d0a87d7b028b 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> > @@ -1452,7 +1452,6 @@ static bool pf_release_vf_config_lmem(struct
> > xe_gt *gt, struct xe_gt_sriov_confi
> >  static int pf_provision_vf_lmem(struct xe_gt *gt, unsigned int
> > vfid, u64 size)
> >  {
> >  	struct xe_gt_sriov_config *config = pf_pick_vf_config(gt,
> > vfid);
> > -	struct drm_exec *exec = XE_VALIDATION_UNIMPLEMENTED;
> >  	struct xe_device *xe = gt_to_xe(gt);
> >  	struct xe_tile *tile = gt_to_tile(gt);
> >  	struct xe_bo *bo;
> > @@ -1479,24 +1478,17 @@ static int pf_provision_vf_lmem(struct
> > xe_gt *gt, unsigned int vfid, u64 size)
> >  		return 0;
> >  
> >  	xe_gt_assert(gt, pf_get_lmem_alignment(gt) == SZ_2M);
> > -	bo = xe_bo_create_locked(xe, tile, NULL,
> > -				 ALIGN(size, PAGE_SIZE),
> > -				 ttm_bo_type_kernel,
> > -				 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > -				 XE_BO_FLAG_NEEDS_2M |
> > -				 XE_BO_FLAG_PINNED |
> > -				 XE_BO_FLAG_PINNED_LATE_RESTORE,
> > -				 exec);
> > +	bo = xe_bo_create_pin_map_at_novm(xe, tile,
> > +					  ALIGN(size, PAGE_SIZE),
> > +					  0,
> > +					  ttm_bo_type_kernel,
> > +					 
> > XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > +					  XE_BO_FLAG_NEEDS_2M |
> > +					 
> > XE_BO_FLAG_PINNED_LATE_RESTORE,
> > +					  false, 0, false);
> >  	if (IS_ERR(bo))
> >  		return PTR_ERR(bo);
> >  
> > -	err = xe_bo_pin(bo, exec);
> > -	xe_bo_unlock(bo);
> > -	if (unlikely(err)) {
> > -		xe_bo_put(bo);
> > -		return err;
> > -	}
> > -
> >  	config->lmem_obj = bo;
> >  
> >  	if (xe_device_has_lmtt(xe)) {
> > diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
> > b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
> > index c712111aa30d..44cc612b0a75 100644
> > --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
> > +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
> > @@ -55,12 +55,12 @@ static int pf_send_guc_save_vf_state(struct
> > xe_gt *gt, unsigned int vfid,
> >  	xe_gt_assert(gt, size % sizeof(u32) == 0);
> >  	xe_gt_assert(gt, size == ndwords * sizeof(u32));
> >  
> > -	bo = xe_bo_create_pin_map(xe, tile, NULL,
> > -				  ALIGN(size, PAGE_SIZE),
> > -				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > -				  XE_BO_FLAG_GGTT |
> > -				  XE_BO_FLAG_GGTT_INVALIDATE);
> > +	bo = xe_bo_create_pin_map_novm(xe, tile,
> > +				       ALIGN(size, PAGE_SIZE),
> > +				       ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > +				       XE_BO_FLAG_GGTT |
> > +				       XE_BO_FLAG_GGTT_INVALIDATE,
> > false);
> >  	if (IS_ERR(bo))
> >  		return PTR_ERR(bo);
> >  
> > @@ -91,12 +91,12 @@ static int pf_send_guc_restore_vf_state(struct
> > xe_gt *gt, unsigned int vfid,
> >  	xe_gt_assert(gt, size % sizeof(u32) == 0);
> >  	xe_gt_assert(gt, size == ndwords * sizeof(u32));
> >  
> > -	bo = xe_bo_create_pin_map(xe, tile, NULL,
> > -				  ALIGN(size, PAGE_SIZE),
> > -				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > -				  XE_BO_FLAG_GGTT |
> > -				  XE_BO_FLAG_GGTT_INVALIDATE);
> > +	bo = xe_bo_create_pin_map_novm(xe, tile,
> > +				       ALIGN(size, PAGE_SIZE),
> > +				       ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > +				       XE_BO_FLAG_GGTT |
> > +				       XE_BO_FLAG_GGTT_INVALIDATE,
> > false);
> >  	if (IS_ERR(bo))
> >  		return PTR_ERR(bo);
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_guc_engine_activity.c
> > b/drivers/gpu/drm/xe/xe_guc_engine_activity.c
> > index 92e1f9f41b8c..2b99c1ebdd58 100644
> > --- a/drivers/gpu/drm/xe/xe_guc_engine_activity.c
> > +++ b/drivers/gpu/drm/xe/xe_guc_engine_activity.c
> > @@ -94,16 +94,17 @@ static int
> > allocate_engine_activity_buffers(struct xe_guc *guc,
> >  	struct xe_tile *tile = gt_to_tile(gt);
> >  	struct xe_bo *bo, *metadata_bo;
> >  
> > -	metadata_bo = xe_bo_create_pin_map(gt_to_xe(gt), tile,
> > NULL, PAGE_ALIGN(metadata_size),
> > -					   ttm_bo_type_kernel,
> > XE_BO_FLAG_SYSTEM |
> > -					   XE_BO_FLAG_GGTT |
> > XE_BO_FLAG_GGTT_INVALIDATE);
> > +	metadata_bo = xe_bo_create_pin_map_novm(gt_to_xe(gt),
> > tile, PAGE_ALIGN(metadata_size),
> > +						ttm_bo_type_kernel
> > , XE_BO_FLAG_SYSTEM |
> > +						XE_BO_FLAG_GGTT |
> > XE_BO_FLAG_GGTT_INVALIDATE,
> > +						false);
> >  
> >  	if (IS_ERR(metadata_bo))
> >  		return PTR_ERR(metadata_bo);
> >  
> > -	bo = xe_bo_create_pin_map(gt_to_xe(gt), tile, NULL,
> > PAGE_ALIGN(size),
> > -				  ttm_bo_type_kernel,
> > XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > -				  XE_BO_FLAG_GGTT |
> > XE_BO_FLAG_GGTT_INVALIDATE);
> > +	bo = xe_bo_create_pin_map_novm(gt_to_xe(gt), tile,
> > PAGE_ALIGN(size),
> > +				       ttm_bo_type_kernel,
> > XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > +				       XE_BO_FLAG_GGTT |
> > XE_BO_FLAG_GGTT_INVALIDATE, false);
> >  
> >  	if (IS_ERR(bo)) {
> >  		xe_bo_unpin_map_no_vm(metadata_bo);
> > diff --git a/drivers/gpu/drm/xe/xe_lmtt.c
> > b/drivers/gpu/drm/xe/xe_lmtt.c
> > index a78c9d474a6e..4ad468574174 100644
> > --- a/drivers/gpu/drm/xe/xe_lmtt.c
> > +++ b/drivers/gpu/drm/xe/xe_lmtt.c
> > @@ -67,12 +67,12 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct
> > xe_lmtt *lmtt, unsigned int level
> >  		goto out;
> >  	}
> >  
> > -	bo = xe_bo_create_pin_map(lmtt_to_xe(lmtt),
> > lmtt_to_tile(lmtt), NULL,
> > -				  PAGE_ALIGN(lmtt->ops-
> > >lmtt_pte_size(level) *
> > -					     lmtt->ops-
> > >lmtt_pte_num(level)),
> > -				  ttm_bo_type_kernel,
> > -				 
> > XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |
> > -				  XE_BO_FLAG_NEEDS_64K);
> > +	bo = xe_bo_create_pin_map_novm(lmtt_to_xe(lmtt),
> > lmtt_to_tile(lmtt),
> > +				       PAGE_ALIGN(lmtt->ops-
> > >lmtt_pte_size(level) *
> > +						  lmtt->ops-
> > >lmtt_pte_num(level)),
> > +				       ttm_bo_type_kernel,
> > +				      
> > XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |
> > +				       XE_BO_FLAG_NEEDS_64K,
> > false);
> >  	if (IS_ERR(bo)) {
> >  		err = PTR_ERR(bo);
> >  		goto out_free_pt;
> > diff --git a/drivers/gpu/drm/xe/xe_lrc.c
> > b/drivers/gpu/drm/xe/xe_lrc.c
> > index 8f6c3ba47882..6d52e0eb97f5 100644
> > --- a/drivers/gpu/drm/xe/xe_lrc.c
> > +++ b/drivers/gpu/drm/xe/xe_lrc.c
> > @@ -1340,9 +1340,10 @@ static int xe_lrc_init(struct xe_lrc *lrc,
> > struct xe_hw_engine *hwe,
> >  	if (vm && vm->xef) /* userspace */
> >  		bo_flags |= XE_BO_FLAG_PINNED_LATE_RESTORE;
> >  
> > -	lrc->bo = xe_bo_create_pin_map(xe, tile, NULL, bo_size,
> > -				       ttm_bo_type_kernel,
> > -				       bo_flags);
> > +	lrc->bo = xe_bo_create_pin_map_novm(xe, tile,
> > +					    bo_size,
> > +					    ttm_bo_type_kernel,
> > +					    bo_flags, false);
> >  	if (IS_ERR(lrc->bo))
> >  		return PTR_ERR(lrc->bo);
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_migrate.c
> > b/drivers/gpu/drm/xe/xe_migrate.c
> > index ddfad7506a82..fe0d15ab340e 100644
> > --- a/drivers/gpu/drm/xe/xe_migrate.c
> > +++ b/drivers/gpu/drm/xe/xe_migrate.c
> > @@ -35,6 +35,7 @@
> >  #include "xe_sched_job.h"
> >  #include "xe_sync.h"
> >  #include "xe_trace_bo.h"
> > +#include "xe_validation.h"
> >  #include "xe_vm.h"
> >  #include "xe_vram.h"
> >  
> > @@ -173,7 +174,7 @@ static void xe_migrate_program_identity(struct
> > xe_device *xe, struct xe_vm *vm,
> >  }
> >  
> >  static int xe_migrate_prepare_vm(struct xe_tile *tile, struct
> > xe_migrate *m,
> > -				 struct xe_vm *vm)
> > +				 struct xe_vm *vm, struct drm_exec
> > *exec)
> >  {
> >  	struct xe_device *xe = tile_to_xe(tile);
> >  	u16 pat_index = xe->pat.idx[XE_CACHE_WB];
> > @@ -200,7 +201,7 @@ static int xe_migrate_prepare_vm(struct xe_tile
> > *tile, struct xe_migrate *m,
> >  				  num_entries * XE_PAGE_SIZE,
> >  				  ttm_bo_type_kernel,
> >  				  XE_BO_FLAG_VRAM_IF_DGFX(tile) |
> > -				  XE_BO_FLAG_PAGETABLE);
> > +				  XE_BO_FLAG_PAGETABLE, exec);
> >  	if (IS_ERR(bo))
> >  		return PTR_ERR(bo);
> >  
> > @@ -404,6 +405,8 @@ int xe_migrate_init(struct xe_migrate *m)
> >  	struct xe_tile *tile = m->tile;
> >  	struct xe_gt *primary_gt = tile->primary_gt;
> >  	struct xe_device *xe = tile_to_xe(tile);
> > +	struct xe_validation_ctx ctx;
> > +	struct drm_exec exec;
> >  	struct xe_vm *vm;
> >  	int err;
> >  
> > @@ -413,11 +416,16 @@ int xe_migrate_init(struct xe_migrate *m)
> >  	if (IS_ERR(vm))
> >  		return PTR_ERR(vm);
> >  
> > -	xe_vm_lock(vm, false);
> > -	err = xe_migrate_prepare_vm(tile, m, vm);
> > -	xe_vm_unlock(vm);
> > +	err = 0;
> > +	xe_validation_guard(&ctx, &xe->val, &exec, 0, err, false)
> > {
> > +		err = xe_vm_drm_exec_lock(vm, &exec);
> > +		drm_exec_retry_on_contention(&exec);
> > +		err = xe_migrate_prepare_vm(tile, m, vm, &exec);
> > +		drm_exec_retry_on_contention(&exec);
> > +		xe_validation_retry_on_oom(&ctx, &err);
> > +	}
> >  	if (err)
> > -		goto err_out;
> > +		return err;
> >  
> >  	if (xe->info.has_usm) {
> >  		struct xe_hw_engine *hwe =
> > xe_gt_hw_engine(primary_gt,
> > diff --git a/drivers/gpu/drm/xe/xe_oa.c
> > b/drivers/gpu/drm/xe/xe_oa.c
> > index a188bad172ad..a4894eb0d7f3 100644
> > --- a/drivers/gpu/drm/xe/xe_oa.c
> > +++ b/drivers/gpu/drm/xe/xe_oa.c
> > @@ -883,9 +883,9 @@ static int xe_oa_alloc_oa_buffer(struct
> > xe_oa_stream *stream, size_t size)
> >  {
> >  	struct xe_bo *bo;
> >  
> > -	bo = xe_bo_create_pin_map(stream->oa->xe, stream->gt-
> > >tile, NULL,
> > -				  size, ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_GGTT);
> > +	bo = xe_bo_create_pin_map_novm(stream->oa->xe, stream->gt-
> > >tile,
> > +				       size, ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_GGTT, false);
> >  	if (IS_ERR(bo))
> >  		return PTR_ERR(bo);
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_pt.c
> > b/drivers/gpu/drm/xe/xe_pt.c
> > index f3a39e734a90..33ad40418ceb 100644
> > --- a/drivers/gpu/drm/xe/xe_pt.c
> > +++ b/drivers/gpu/drm/xe/xe_pt.c
> > @@ -88,6 +88,7 @@ static void xe_pt_free(struct xe_pt *pt)
> >   * @vm: The vm to create for.
> >   * @tile: The tile to create for.
> >   * @level: The page-table level.
> > + * @exec: The drm_exec object used to lock the vm.
> >   *
> >   * Allocate and initialize a single struct xe_pt metadata
> > structure. Also
> >   * create the corresponding page-table bo, but don't initialize
> > it. If the
> > @@ -99,7 +100,7 @@ static void xe_pt_free(struct xe_pt *pt)
> >   * error.
> >   */
> >  struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile,
> > -			   unsigned int level)
> > +			   unsigned int level, struct drm_exec
> > *exec)
> >  {
> >  	struct xe_pt *pt;
> >  	struct xe_bo *bo;
> > @@ -123,9 +124,11 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm,
> > struct xe_tile *tile,
> >  		bo_flags |= XE_BO_FLAG_PINNED_LATE_RESTORE;
> >  
> >  	pt->level = level;
> > +
> > +	drm_WARN_ON(&vm->xe->drm, IS_ERR_OR_NULL(exec));
> >  	bo = xe_bo_create_pin_map(vm->xe, tile, vm, SZ_4K,
> >  				  ttm_bo_type_kernel,
> > -				  bo_flags);
> > +				  bo_flags, exec);
> >  	if (IS_ERR(bo)) {
> >  		err = PTR_ERR(bo);
> >  		goto err_kfree;
> > @@ -589,7 +592,8 @@ xe_pt_stage_bind_entry(struct xe_ptw *parent,
> > pgoff_t offset,
> >  	if (covers || !*child) {
> >  		u64 flags = 0;
> >  
> > -		xe_child = xe_pt_create(xe_walk->vm, xe_walk-
> > >tile, level - 1);
> > +		xe_child = xe_pt_create(xe_walk->vm, xe_walk-
> > >tile, level - 1,
> > +					xe_vm_validation_exec(vm))
> > ;
> >  		if (IS_ERR(xe_child))
> >  			return PTR_ERR(xe_child);
> >  
> > diff --git a/drivers/gpu/drm/xe/xe_pt.h
> > b/drivers/gpu/drm/xe/xe_pt.h
> > index 5ecf003d513c..4daeebaab5a1 100644
> > --- a/drivers/gpu/drm/xe/xe_pt.h
> > +++ b/drivers/gpu/drm/xe/xe_pt.h
> > @@ -10,6 +10,7 @@
> >  #include "xe_pt_types.h"
> >  
> >  struct dma_fence;
> > +struct drm_exec;
> >  struct xe_bo;
> >  struct xe_device;
> >  struct xe_exec_queue;
> > @@ -29,7 +30,7 @@ struct xe_vma_ops;
> >  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);
> > +			   unsigned int level, struct drm_exec
> > *exec);
> >  
> >  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_pxp_submit.c
> > b/drivers/gpu/drm/xe/xe_pxp_submit.c
> > index ca95f2a4d4ef..54bd6b64dc6d 100644
> > --- a/drivers/gpu/drm/xe/xe_pxp_submit.c
> > +++ b/drivers/gpu/drm/xe/xe_pxp_submit.c
> > @@ -54,8 +54,9 @@ static int
> > allocate_vcs_execution_resources(struct xe_pxp *pxp)
> >  	 * Each termination is 16 DWORDS, so 4K is enough to
> > contain a
> >  	 * termination for each sessions.
> >  	 */
> > -	bo = xe_bo_create_pin_map(xe, tile, NULL, SZ_4K,
> > ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_PINNED | XE_BO_FLAG_GGTT);
> > +	bo = xe_bo_create_pin_map_novm(xe, tile, SZ_4K,
> > ttm_bo_type_kernel,
> > +				       XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_PINNED | XE_BO_FLAG_GGTT,
> > +				       false);
> >  	if (IS_ERR(bo)) {
> >  		err = PTR_ERR(bo);
> >  		goto out_queue;
> > @@ -87,7 +88,9 @@ static int allocate_gsc_client_resources(struct
> > xe_gt *gt,
> >  {
> >  	struct xe_tile *tile = gt_to_tile(gt);
> >  	struct xe_device *xe = tile_to_xe(tile);
> > +	struct xe_validation_ctx ctx;
> >  	struct xe_hw_engine *hwe;
> > +	struct drm_exec exec;
> >  	struct xe_vm *vm;
> >  	struct xe_bo *bo;
> >  	struct xe_exec_queue *q;
> > @@ -106,15 +109,26 @@ static int
> > allocate_gsc_client_resources(struct xe_gt *gt,
> >  		return PTR_ERR(vm);
> >  
> >  	/* We allocate a single object for the batch and the
> > in/out memory */
> > -	xe_vm_lock(vm, false);
> > -	bo = xe_bo_create_pin_map(xe, tile, vm, PXP_BB_SIZE +
> > inout_size * 2,
> > -				  ttm_bo_type_kernel,
> > -				  XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_PINNED | XE_BO_FLAG_NEEDS_UC);
> > -	xe_vm_unlock(vm);
> > -	if (IS_ERR(bo)) {
> > -		err = PTR_ERR(bo);
> > -		goto vm_out;
> > +
> > +	xe_validation_guard(&ctx, &xe->val, &exec, 0, err, false)
> > {
> > +		err = xe_vm_drm_exec_lock(vm, &exec);
> > +		drm_exec_retry_on_contention(&exec);
> > +		if (err)
> > +			break;
> > +
> > +		bo = xe_bo_create_pin_map(xe, tile, vm,
> > PXP_BB_SIZE + inout_size * 2,
> > +					  ttm_bo_type_kernel,
> > +					  XE_BO_FLAG_SYSTEM |
> > XE_BO_FLAG_PINNED |
> > +					  XE_BO_FLAG_NEEDS_UC,
> > &exec);
> > +		drm_exec_retry_on_contention(&exec);
> > +		if (IS_ERR(bo)) {
> > +			err = PTR_ERR(bo);
> > +			xe_validation_retry_on_oom(&ctx, &err);
> > +			break;
> > +		}
> >  	}
> > +	if (err)
> > +		goto vm_out;
> >  
> >  	fence = xe_vm_bind_kernel_bo(vm, bo, NULL, 0,
> > XE_CACHE_WB);
> >  	if (IS_ERR(fence)) {
> > diff --git a/drivers/gpu/drm/xe/xe_vm.c
> > b/drivers/gpu/drm/xe/xe_vm.c
> > index 989d84c2e82f..b3ee65126841 100644
> > --- a/drivers/gpu/drm/xe/xe_vm.c
> > +++ b/drivers/gpu/drm/xe/xe_vm.c
> > @@ -1606,6 +1606,7 @@ static void vm_destroy_work_func(struct
> > work_struct *w);
> >   * @xe: xe device.
> >   * @tile: tile to set up for.
> >   * @vm: vm to set up for.
> > + * @exec: The struct drm_exec object used to lock the vm resv.
> >   *
> >   * 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,
> > @@ -1615,20 +1616,19 @@ static void vm_destroy_work_func(struct
> > work_struct *w);
> >   * 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)
> > +				struct xe_vm *vm, struct drm_exec
> > *exec)
> >  {
> >  	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);
> > +		vm->scratch_pt[id][i] = xe_pt_create(vm, tile, i,
> > exec);
> >  		if (IS_ERR(vm->scratch_pt[id][i])) {
> >  			int err = PTR_ERR(vm->scratch_pt[id][i]);
> >  
> >  			vm->scratch_pt[id][i] = NULL;
> >  			return err;
> >  		}
> > -
> >  		xe_pt_populate_empty(tile, vm, vm-
> > >scratch_pt[id][i]);
> >  	}
> >  
> > @@ -1656,9 +1656,26 @@ static void xe_vm_free_scratch(struct xe_vm
> > *vm)
> >  	}
> >  }
> >  
> > +static void xe_vm_pt_destroy(struct xe_vm *vm)
> > +{
> > +	struct xe_tile *tile;
> > +	u8 id;
> > +
> > +	xe_vm_assert_held(vm);
> > +
> > +	for_each_tile(tile, vm->xe, id) {
> > +		if (vm->pt_root[id]) {
> > +			xe_pt_destroy(vm->pt_root[id], vm->flags,
> > NULL);
> > +			vm->pt_root[id] = NULL;
> > +		}
> > +	}
> > +}
> > +
> >  struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags, struct
> > xe_file *xef)
> >  {
> >  	struct drm_gem_object *vm_resv_obj;
> > +	struct xe_validation_ctx ctx;
> > +	struct drm_exec exec;
> >  	struct xe_vm *vm;
> >  	int err, number_tiles = 0;
> >  	struct xe_tile *tile;
> > @@ -1745,49 +1762,64 @@ struct xe_vm *xe_vm_create(struct xe_device
> > *xe, u32 flags, struct xe_file *xef)
> >  
> >  	drm_gem_object_put(vm_resv_obj);
> >  
> > -	err = xe_vm_lock(vm, true);
> > -	if (err)
> > -		goto err_close;
> > +	err = 0;
> > +	xe_validation_guard(&ctx, &xe->val, &exec,
> > DRM_EXEC_INTERRUPTIBLE_WAIT,
> > +			    err, true) {
> > +		err = xe_vm_drm_exec_lock(vm, &exec);
> > +		drm_exec_retry_on_contention(&exec);
> >  
> > -	if (IS_DGFX(xe) && xe->info.vram_flags &
> > XE_VRAM_FLAGS_NEED64K)
> > -		vm->flags |= XE_VM_FLAG_64K;
> > +		if (IS_DGFX(xe) && xe->info.vram_flags &
> > XE_VRAM_FLAGS_NEED64K)
> > +			vm->flags |= XE_VM_FLAG_64K;
> >  
> > -	for_each_tile(tile, xe, id) {
> > -		if (flags & XE_VM_FLAG_MIGRATION &&
> > -		    tile->id != XE_VM_FLAG_TILE_ID(flags))
> > -			continue;
> > +		for_each_tile(tile, xe, id) {
> > +			if (flags & XE_VM_FLAG_MIGRATION &&
> > +			    tile->id != XE_VM_FLAG_TILE_ID(flags))
> > +				continue;
> >  
> > -		vm->pt_root[id] = xe_pt_create(vm, tile, xe-
> > >info.vm_max_level);
> > -		if (IS_ERR(vm->pt_root[id])) {
> > -			err = PTR_ERR(vm->pt_root[id]);
> > -			vm->pt_root[id] = NULL;
> > -			goto err_unlock_close;
> > +			vm->pt_root[id] = xe_pt_create(vm, tile,
> > xe->info.vm_max_level,
> > +						       &exec);
> > +			if (IS_ERR(vm->pt_root[id])) {
> > +				err = PTR_ERR(vm->pt_root[id]);
> > +				vm->pt_root[id] = NULL;
> > +				xe_vm_pt_destroy(vm);
> > +				drm_exec_retry_on_contention(&exec
> > );
> > +				xe_validation_retry_on_oom(&ctx,
> > &err);
> > +				goto err_close;
> > +			}
> >  		}
> > -	}
> >  
> > -	if (xe_vm_has_scratch(vm)) {
> > +		if (xe_vm_has_scratch(vm)) {
> > +			for_each_tile(tile, xe, id) {
> > +				if (!vm->pt_root[id])
> > +					continue;
> > +
> > +				err = xe_vm_create_scratch(xe,
> > tile, vm, &exec);
> > +				if (err) {
> > +					xe_vm_free_scratch(vm);
> > +					xe_vm_pt_destroy(vm);
> > +					drm_exec_retry_on_contenti
> > on(&exec);
> > +					xe_validation_retry_on_oom
> > (&ctx, &err);
> > +					goto err_close;
> > +				}
> > +			}
> > +			vm->batch_invalidate_tlb = true;
> > +		}
> > +
> > +		if (vm->flags & XE_VM_FLAG_LR_MODE) {
> > +			INIT_WORK(&vm->preempt.rebind_work,
> > preempt_rebind_work_func);
> > +			vm->batch_invalidate_tlb = false;
> > +		}
> > +
> > +		/* Fill pt_root after allocating scratch tables */
> >  		for_each_tile(tile, xe, id) {
> >  			if (!vm->pt_root[id])
> >  				continue;
> >  
> > -			err = xe_vm_create_scratch(xe, tile, vm);
> > -			if (err)
> > -				goto err_unlock_close;
> > +			xe_pt_populate_empty(tile, vm, vm-
> > >pt_root[id]);
> >  		}
> > -		vm->batch_invalidate_tlb = true;
> > -	}
> > -
> > -	if (vm->flags & XE_VM_FLAG_LR_MODE)
> > -		vm->batch_invalidate_tlb = false;
> > -
> > -	/* Fill pt_root after allocating scratch tables */
> > -	for_each_tile(tile, xe, id) {
> > -		if (!vm->pt_root[id])
> > -			continue;
> > -
> > -		xe_pt_populate_empty(tile, vm, vm->pt_root[id]);
> >  	}
> > -	xe_vm_unlock(vm);
> > +	if (err)
> > +		goto err_close;
> >  
> >  	/* Kernel migration VM shouldn't have a circular loop.. */
> >  	if (!(flags & XE_VM_FLAG_MIGRATION)) {
> > @@ -1820,7 +1852,7 @@ struct xe_vm *xe_vm_create(struct xe_device
> > *xe, u32 flags, struct xe_file *xef)
> >  				      &xe->usm.next_asid,
> > GFP_KERNEL);
> >  		up_write(&xe->usm.lock);
> >  		if (err < 0)
> > -			goto err_unlock_close;
> > +			goto err_close;
> >  
> >  		vm->usm.asid = asid;
> >  	}
> > @@ -1829,8 +1861,6 @@ struct xe_vm *xe_vm_create(struct xe_device
> > *xe, u32 flags, struct xe_file *xef)
> >  
> >  	return vm;
> >  
> > -err_unlock_close:
> > -	xe_vm_unlock(vm);
> >  err_close:
> >  	xe_vm_close_and_put(vm);
> >  	return ERR_PTR(err);
> > @@ -1959,13 +1989,7 @@ void xe_vm_close_and_put(struct xe_vm *vm)
> >  	 * destroy the pagetables immediately.
> >  	 */
> >  	xe_vm_free_scratch(vm);
> > -
> > -	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;
> > -		}
> > -	}
> > +	xe_vm_pt_destroy(vm);
> >  	xe_vm_unlock(vm);
> >  
> >  	/*
> > @@ -3845,7 +3869,6 @@ struct dma_fence *xe_vm_bind_kernel_bo(struct
> > xe_vm *vm, struct xe_bo *bo,
> >   */
> >  int xe_vm_lock(struct xe_vm *vm, bool intr)
> >  {
> > -	struct drm_exec *exec = XE_VALIDATION_UNIMPLEMENTED;
> 
> You add this earlier in the series and then delete it here, which
> seems
> odd. If the intent is to apply a workaround (WA) earlier and finalize
> it
> here, that makes sense.

Yes, the patch that introduces these identifies all the call-sites
where we need a fix-up, and uses lockdep to verify that a validation
transaction starting there doesn't violate the dma_resv locking orders.

Most of the series then eliminates these _UNIMPLEMENTED one by one.
Of course one could do it in the opposite order to avoid introducing
and then eliminating these but I think that would be harder both for
the developer and reviewer.

> 
> However, deleting it here appears to leave a problematic path in
> xe_svm.c around xe_vm_range_rebind, where vm->validating._exec may
> remain unset/stale. I’m surprised CI didn’t catch this—perhaps due to
> an
> unbalanced xe_vm_set_validation_exec leaving stale state—or I’m
> missing
> something.

Yes, you are correct. There was an imbalance and I will fix that.

Thanks,
Thomas

> 
> Matt
> 
> >  	int ret;
> >  
> >  	if (intr)
> > @@ -3853,9 +3876,6 @@ int xe_vm_lock(struct xe_vm *vm, bool intr)
> >  	else
> >  		ret = dma_resv_lock(xe_vm_resv(vm), NULL);
> >  
> > -	if (!ret)
> > -		xe_vm_set_validation_exec(vm, exec);
> > -
> >  	return ret;
> >  }
> >  
> > @@ -3867,7 +3887,6 @@ int xe_vm_lock(struct xe_vm *vm, bool intr)
> >   */
> >  void xe_vm_unlock(struct xe_vm *vm)
> >  {
> > -	xe_vm_set_validation_exec(vm, NULL);
> >  	dma_resv_unlock(xe_vm_resv(vm));
> >  }
> >  
> > -- 
> > 2.50.1
> > 



More information about the Intel-xe mailing list