[Intel-xe] [PATCH 3/5] drm/xe: Fix extobj dropping issue.

Thomas Hellström thomas.hellstrom at linux.intel.com
Fri May 26 12:31:53 UTC 2023


On 5/26/23 14:10, Maarten Lankhorst wrote:
> I believe originally we did the right thing, but now we hit an issue.
>
> Presumably, this was changed when converting from an array to a list
> in a squashed commit:
> "drm/xe: Use a list for the vm's external objects"
>
> When deleting a vma with an extobj in the list, ensure if it's freed
> but still listed on the vm, we take a different vma and add that to
> the extobj list instead.
>
> I'll add an igt, and make sure it doesn't happen again.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/194

Lgtm. Perhaps add a Fixes: or a !fixup to that broken commit?

Reviewed-by: Thomas Hellström <thomas.hellstrom at linux.intel.com>


> ---
>   drivers/gpu/drm/xe/xe_vm.c | 95 +++++++++++++++++++++++---------------
>   1 file changed, 58 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index f73e08b60670..dd1335e12d4c 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -909,12 +909,14 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
>   	return vma;
>   }
>   
> -static void vm_remove_extobj(struct xe_vma *vma)
> +static bool vm_remove_extobj(struct xe_vma *vma)
>   {
>   	if (!list_empty(&vma->extobj.link)) {
>   		vma->vm->extobj.entries--;
>   		list_del_init(&vma->extobj.link);
> +		return true;
>   	}
> +	return false;
>   }
>   
>   static void xe_vma_destroy_late(struct xe_vma *vma)
> @@ -955,6 +957,51 @@ static void vma_destroy_work_func(struct work_struct *w)
>   	xe_vma_destroy_late(vma);
>   }
>   
> +static struct xe_vma *
> +bo_has_vm_references_locked(struct xe_bo *bo, struct xe_vm *vm,
> +			    struct xe_vma *ignore)
> +{
> +	struct xe_vma *vma;
> +
> +	list_for_each_entry(vma, &bo->vmas, bo_link) {
> +		if (vma != ignore && vma->vm == vm && !vma->destroyed)
> +			return vma;
> +	}
> +
> +	return NULL;
> +}
> +
> +static bool bo_has_vm_references(struct xe_bo *bo, struct xe_vm *vm,
> +				 struct xe_vma *ignore)
> +{
> +	struct ww_acquire_ctx ww;
> +	bool ret;
> +
> +	xe_bo_lock(bo, &ww, 0, false);
> +	ret = !!bo_has_vm_references_locked(bo, vm, ignore);
> +	xe_bo_unlock(bo, &ww);
> +
> +	return ret;
> +}
> +
> +static void __vm_insert_extobj(struct xe_vm *vm, struct xe_vma *vma)
> +{
> +	list_add(&vma->extobj.link, &vm->extobj.list);
> +	vm->extobj.entries++;
> +}
> +
> +static void vm_insert_extobj(struct xe_vm *vm, struct xe_vma *vma)
> +{
> +	struct xe_bo *bo = vma->bo;
> +
> +	lockdep_assert_held_write(&vm->lock);
> +
> +	if (bo_has_vm_references(bo, vm, vma))
> +		return;
> +
> +	__vm_insert_extobj(vm, vma);
> +}
> +
>   static void vma_destroy_cb(struct dma_fence *fence,
>   			   struct dma_fence_cb *cb)
>   {
> @@ -980,11 +1027,19 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
>   	} else {
>   		xe_bo_assert_held(vma->bo);
>   		list_del(&vma->bo_link);
> +
>   		spin_lock(&vm->notifier.list_lock);
>   		list_del(&vma->notifier.rebind_link);
>   		spin_unlock(&vm->notifier.list_lock);
> -		if (!vma->bo->vm)
> -			vm_remove_extobj(vma);
> +
> +		if (!vma->bo->vm && vm_remove_extobj(vma)) {
> +			struct xe_vma *other;
> +
> +			other = bo_has_vm_references_locked(vma->bo, vm, NULL);
> +
> +			if (other)
> +				__vm_insert_extobj(vm, other);
> +		}
>   	}
>   
>   	xe_vm_assert_held(vm);
> @@ -2481,40 +2536,6 @@ static int vm_bind_ioctl_async(struct xe_vm *vm, struct xe_vma *vma,
>   	return err;
>   }
>   
> -static bool bo_has_vm_references(struct xe_bo *bo, struct xe_vm *vm,
> -				 struct xe_vma *ignore)
> -{
> -	struct ww_acquire_ctx ww;
> -	struct xe_vma *vma;
> -	bool ret = false;
> -
> -	xe_bo_lock(bo, &ww, 0, false);
> -	list_for_each_entry(vma, &bo->vmas, bo_link) {
> -		if (vma != ignore && vma->vm == vm && !vma->destroyed) {
> -			ret = true;
> -			break;
> -		}
> -	}
> -	xe_bo_unlock(bo, &ww);
> -
> -	return ret;
> -}
> -
> -static int vm_insert_extobj(struct xe_vm *vm, struct xe_vma *vma)
> -{
> -	struct xe_bo *bo = vma->bo;
> -
> -	lockdep_assert_held_write(&vm->lock);
> -
> -	if (bo_has_vm_references(bo, vm, vma))
> -		return 0;
> -
> -	list_add(&vma->extobj.link, &vm->extobj.list);
> -	vm->extobj.entries++;
> -
> -	return 0;
> -}
> -
>   static int __vm_bind_ioctl_lookup_vma(struct xe_vm *vm, struct xe_bo *bo,
>   				      u64 addr, u64 range, u32 op)
>   {


More information about the Intel-xe mailing list