Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: Matthew Brost <matthew.brost@intel.com>, intel-xe@lists.freedesktop.org
Subject: Re: [Intel-xe] [PATCH 2/5] drm/xe: Reduce the number list links in xe_vma
Date: Sat, 15 Jul 2023 15:11:59 +0200	[thread overview]
Message-ID: <1ebf9a3b-fcfc-e30f-eec5-e9c87c5be761@linux.intel.com> (raw)
In-Reply-To: <20230711212748.2029455-3-matthew.brost@intel.com>

Hi, Matthew,

On 7/11/23 23:27, Matthew Brost wrote:
> Combine the userptr, rebind, and destroy links into a union as
> the lists these links belong to are mutually exclusive.
>
> v2: Adjust which lists are combined (Thomas H)
>
> Signed-off-by: Matthew Brost <matthew.brost@intel.com>
> ---
>   drivers/gpu/drm/xe/xe_bo.c       |  6 +++--
>   drivers/gpu/drm/xe/xe_exec.c     |  2 +-
>   drivers/gpu/drm/xe/xe_pt.c       |  2 +-
>   drivers/gpu/drm/xe/xe_vm.c       | 45 ++++++++++++++++----------------
>   drivers/gpu/drm/xe/xe_vm_types.h | 28 +++++++++-----------
>   5 files changed, 41 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index 6353afa8d846..ca7f74ecb753 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
> @@ -474,8 +474,10 @@ static int xe_bo_trigger_rebind(struct xe_device *xe, struct xe_bo *bo,
>   			}
>   
>   			xe_vm_assert_held(vm);
> -			if (list_empty(&vma->rebind_link) && vma->tile_present)
> -				list_add_tail(&vma->rebind_link, &vm->rebind_list);
> +			if (list_empty(&vma->combined_links.rebind) &&
> +			    vma->tile_present)
> +				list_add_tail(&vma->combined_links.rebind,
> +					      &vm->rebind_list);
>   
>   			if (vm_resv_locked)
>   				dma_resv_unlock(&vm->resv);
> diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c
> index ba13d20ed348..bc5bd4bdc582 100644
> --- a/drivers/gpu/drm/xe/xe_exec.c
> +++ b/drivers/gpu/drm/xe/xe_exec.c
> @@ -120,7 +120,7 @@ static int xe_exec_begin(struct xe_engine *e, struct ww_acquire_ctx *ww,
>   	 * BOs have valid placements possibly moving an evicted BO back
>   	 * to a location where the GPU can access it).
>   	 */
> -	list_for_each_entry(vma, &vm->rebind_list, rebind_link) {
> +	list_for_each_entry(vma, &vm->rebind_list, combined_links.rebind) {
>   		XE_WARN_ON(xe_vma_is_null(vma));
>   
>   		if (xe_vma_is_userptr(vma))
> diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
> index a8d96cbd53e3..3b43b32f4a33 100644
> --- a/drivers/gpu/drm/xe/xe_pt.c
> +++ b/drivers/gpu/drm/xe/xe_pt.c
> @@ -1690,7 +1690,7 @@ __xe_pt_unbind_vma(struct xe_tile *tile, struct xe_vma *vma, struct xe_engine *e
>   	}
>   
>   	if (!vma->tile_present)
> -		list_del_init(&vma->rebind_link);
> +		list_del_init(&vma->combined_links.rebind);
>   
>   	if (unbind_pt_update.locked) {
>   		XE_WARN_ON(!xe_vma_is_userptr(vma));
> diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
> index 5f4f6dab270a..b2847be6de6a 100644
> --- a/drivers/gpu/drm/xe/xe_vm.c
> +++ b/drivers/gpu/drm/xe/xe_vm.c
> @@ -467,7 +467,8 @@ int xe_vm_lock_dma_resv(struct xe_vm *vm, struct ww_acquire_ctx *ww,
>   
>   		list_del_init(&vma->notifier.rebind_link);
>   		if (vma->tile_present && !(vma->gpuva.flags & XE_VMA_DESTROYED))
> -			list_move_tail(&vma->rebind_link, &vm->rebind_list);
> +			list_move_tail(&vma->combined_links.rebind,
> +				       &vm->rebind_list);
>   	}
>   	spin_unlock(&vm->notifier.list_lock);
>   
> @@ -608,7 +609,7 @@ static void preempt_rebind_work_func(struct work_struct *w)
>   	if (err)
>   		goto out_unlock;
>   
> -	list_for_each_entry(vma, &vm->rebind_list, rebind_link) {
> +	list_for_each_entry(vma, &vm->rebind_list, combined_links.rebind) {
>   		if (xe_vma_has_no_bo(vma) ||
>   		    vma->gpuva.flags & XE_VMA_DESTROYED)
>   			continue;
> @@ -780,17 +781,20 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
>   	list_for_each_entry_safe(vma, next, &vm->userptr.invalidated,
>   				 userptr.invalidate_link) {
>   		list_del_init(&vma->userptr.invalidate_link);
> -		list_move_tail(&vma->userptr_link, &vm->userptr.repin_list);
> +		if (list_empty(&vma->combined_links.userptr))
> +			list_move_tail(&vma->combined_links.userptr,
> +				       &vm->userptr.repin_list);
>   	}
>   	spin_unlock(&vm->userptr.invalidated_lock);
>   
>   	/* Pin and move to temporary list */
> -	list_for_each_entry_safe(vma, next, &vm->userptr.repin_list, userptr_link) {
> +	list_for_each_entry_safe(vma, next, &vm->userptr.repin_list,
> +				 combined_links.userptr) {
>   		err = xe_vma_userptr_pin_pages(vma);
>   		if (err < 0)
>   			goto out_err;
>   
> -		list_move_tail(&vma->userptr_link, &tmp_evict);
> +		list_move_tail(&vma->combined_links.userptr, &tmp_evict);
>   	}
>   
>   	/* Take lock and move to rebind_list for rebinding. */
> @@ -798,10 +802,8 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
>   	if (err)
>   		goto out_err;
>   
> -	list_for_each_entry_safe(vma, next, &tmp_evict, userptr_link) {
> -		list_del_init(&vma->userptr_link);
> -		list_move_tail(&vma->rebind_link, &vm->rebind_list);
> -	}
> +	list_for_each_entry_safe(vma, next, &tmp_evict, combined_links.userptr)
> +		list_move_tail(&vma->combined_links.rebind, &vm->rebind_list);
>   
>   	dma_resv_unlock(&vm->resv);
>   
> @@ -845,10 +847,11 @@ struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
>   		return NULL;
>   
>   	xe_vm_assert_held(vm);
> -	list_for_each_entry_safe(vma, next, &vm->rebind_list, rebind_link) {
> +	list_for_each_entry_safe(vma, next, &vm->rebind_list,
> +				 combined_links.rebind) {
>   		XE_WARN_ON(!vma->tile_present);
>   
> -		list_del_init(&vma->rebind_link);
> +		list_del_init(&vma->combined_links.rebind);
>   		dma_fence_put(fence);
>   		if (rebind_worker)
>   			trace_xe_vma_rebind_worker(vma);
> @@ -883,9 +886,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
>   		return vma;
>   	}
>   
> -	INIT_LIST_HEAD(&vma->rebind_link);
> -	INIT_LIST_HEAD(&vma->unbind_link);
> -	INIT_LIST_HEAD(&vma->userptr_link);
> +	INIT_LIST_HEAD(&vma->combined_links.rebind);
>   	INIT_LIST_HEAD(&vma->userptr.invalidate_link);
>   	INIT_LIST_HEAD(&vma->notifier.rebind_link);
>   	INIT_LIST_HEAD(&vma->extobj.link);
> @@ -1058,15 +1059,14 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
>   	struct xe_vm *vm = xe_vma_vm(vma);
>   
>   	lockdep_assert_held_write(&vm->lock);
> -	XE_BUG_ON(!list_empty(&vma->unbind_link));
> +	XE_BUG_ON(!list_empty(&vma->combined_links.destroy));
>   
>   	if (xe_vma_is_userptr(vma)) {
>   		XE_WARN_ON(!(vma->gpuva.flags & XE_VMA_DESTROYED));
>   
>   		spin_lock(&vm->userptr.invalidated_lock);
> -		list_del_init(&vma->userptr.invalidate_link);
> +		list_del(&vma->userptr.invalidate_link);
>   		spin_unlock(&vm->userptr.invalidated_lock);
> -		list_del(&vma->userptr_link);
>   	} else if (!xe_vma_is_null(vma)) {
>   		xe_bo_assert_held(xe_vma_bo(vma));
>   
> @@ -1087,9 +1087,6 @@ static void xe_vma_destroy(struct xe_vma *vma, struct dma_fence *fence)
>   	}
>   
>   	xe_vm_assert_held(vm);
> -	if (!list_empty(&vma->rebind_link))
> -		list_del(&vma->rebind_link);
> -
>   	if (fence) {
>   		int ret = dma_fence_add_callback(fence, &vma->destroy_cb,
>   						 vma_destroy_cb);
> @@ -1443,11 +1440,12 @@ void xe_vm_close_and_put(struct xe_vm *vm)
>   
>   		/* easy case, remove from VMA? */
>   		if (xe_vma_has_no_bo(vma) || xe_vma_bo(vma)->vm) {
> +			list_del_init(&vma->combined_links.rebind);
>   			xe_vma_destroy(vma, NULL);
>   			continue;
>   		}
>   
> -		list_add_tail(&vma->unbind_link, &contested);
> +		list_move_tail(&vma->combined_links.destroy, &contested);
>   	}
>   
>   	/*
> @@ -1475,8 +1473,9 @@ void xe_vm_close_and_put(struct xe_vm *vm)
>   	 * Since we hold a refcount to the bo, we can remove and free
>   	 * the members safely without locking.
>   	 */
> -	list_for_each_entry_safe(vma, next_vma, &contested, unbind_link) {
> -		list_del_init(&vma->unbind_link);
> +	list_for_each_entry_safe(vma, next_vma, &contested,
> +				 combined_links.destroy) {
> +		list_del_init(&vma->combined_links.destroy);
>   		xe_vma_destroy_unlocked(vma);
>   	}
>   
> diff --git a/drivers/gpu/drm/xe/xe_vm_types.h b/drivers/gpu/drm/xe/xe_vm_types.h
> index f17dc5d7370e..84bf1620214c 100644
> --- a/drivers/gpu/drm/xe/xe_vm_types.h
> +++ b/drivers/gpu/drm/xe/xe_vm_types.h
> @@ -49,21 +49,19 @@ struct xe_vma {
>   	 */
>   	u64 tile_present;
>   
> -	/** @userptr_link: link into VM repin list if userptr */
> -	struct list_head userptr_link;
> -
> -	/**
> -	 * @rebind_link: link into VM if this VMA needs rebinding, and
> -	 * if it's a bo (not userptr) needs validation after a possible
> -	 * eviction. Protected by the vm's resv lock.
> -	 */
> -	struct list_head rebind_link;

The rebind_link and the userptr_link are not combinable. To be 
combinable they need to either be protected by the same lock or be kept 
mutually exclusive by some other *simple* argument, like construction / 
destruction, used for different subclasses etc.

The userptr_link is protected by the userptr.invalidated_lock and the 
rebind_link by the vm resv, and no simple argument can be made. In fact 
let's say that a userptr sits on or is being moved to the rebind list, 
and then the invalidation notifier gets called, which will try to move 
it to the userptr list again using the userptr link. In the best case it 
will fail the move since the list is not empty, in the worst case list 
corruption due to the list head is currently being modified.

So IMO for any list head being combined like this, we need to kerneldoc 
why this is possible, using either the lock argument or another simple 
argument like detailed above.

I *think* the notifier.rebind_list and the userptr_list are combinable, 
though, using the different vma subclass (userptr/bo) argument.

Thanks,

Thomas


> -
> -	/**
> -	 * @unbind_link: link or list head if an unbind of multiple VMAs, in
> -	 * single unbind op, is being done.
> -	 */
> -	struct list_head unbind_link;
> +	/** @combined_links: links into lists which are mutually exclusive */
> +	union {
> +		/** @userptr: link into VM repin list if userptr */
> +		struct list_head userptr;
> +		/**
> +		 * @rebind: link into VM if this VMA needs rebinding, and
> +		 * if it's a bo (not userptr) needs validation after a possible
> +		 * eviction. Protected by the vm's resv lock.
> +		 */
> +		struct list_head rebind;
> +		/** @destroy: link to contested list when VM is being closed */
> +		struct list_head destroy;
> +	} combined_links;
>   
>   	/** @destroy_cb: callback to destroy VMA when unbind job is done */
>   	struct dma_fence_cb destroy_cb;

  parent reply	other threads:[~2023-07-15 13:12 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-11 21:27 [Intel-xe] [PATCH 0/5] More VM cleanups Matthew Brost
2023-07-11 21:27 ` [Intel-xe] [PATCH 1/5] drm/xe: Avoid doing rebinds Matthew Brost
2023-07-13 20:10   ` Rodrigo Vivi
2023-07-13 20:11   ` Rodrigo Vivi
2023-07-11 21:27 ` [Intel-xe] [PATCH 2/5] drm/xe: Reduce the number list links in xe_vma Matthew Brost
2023-07-13 20:18   ` Rodrigo Vivi
2023-07-14  3:56     ` Matthew Brost
2023-07-14 13:42       ` Rodrigo Vivi
2023-07-15 13:11   ` Thomas Hellström [this message]
2023-07-19 22:19     ` Matthew Brost
2023-07-11 21:27 ` [Intel-xe] [PATCH 3/5] drm/xe: Change tile masks from u64 to u8 Matthew Brost
2023-07-13 20:21   ` Rodrigo Vivi
2023-07-14  3:46     ` Matthew Brost
2023-07-11 21:27 ` [Intel-xe] [PATCH 4/5] drm/xe: Combine destroy_cb and destroy_work in xe_vma into union Matthew Brost
2023-07-13 20:23   ` Rodrigo Vivi
2023-07-14  3:53     ` Matthew Brost
2023-07-14 14:28       ` Rodrigo Vivi
2023-07-11 21:27 ` [Intel-xe] [PATCH 5/5] drm/xe: Only alloc userptr part of xe_vma for userptrs Matthew Brost
2023-07-13 20:26   ` Rodrigo Vivi
2023-07-11 21:29 ` [Intel-xe] ✓ CI.Patch_applied: success for More VM cleanups Patchwork
2023-07-11 21:29 ` [Intel-xe] ✗ CI.checkpatch: warning " Patchwork
2023-07-11 21:30 ` [Intel-xe] ✓ CI.KUnit: success " Patchwork
2023-07-11 21:34 ` [Intel-xe] ✓ CI.Build: " Patchwork
2023-07-11 21:35 ` [Intel-xe] ✓ CI.Hooks: " Patchwork
2023-07-11 21:36 ` [Intel-xe] ✓ CI.checksparse: " Patchwork
2023-07-11 22:10 ` [Intel-xe] ○ CI.BAT: info " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1ebf9a3b-fcfc-e30f-eec5-e9c87c5be761@linux.intel.com \
    --to=thomas.hellstrom@linux.intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=matthew.brost@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox