All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Timur Kristóf" <timur.kristof@gmail.com>
To: natalie.vock@gmx.de, honghuan@amd.com, Alexander.Deucher@amd.com,
	Felix.Kuehling@amd.com, Philip.Yang@amd.com,
	christian.koenig@amd.com
Cc: amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH 06/13] drm/amdgpu: add amdgpu_vm_update_leaves()
Date: Fri, 12 Jun 2026 08:54:49 +0200	[thread overview]
Message-ID: <2299736.hkbZ0PkbqX@timur-max> (raw)
In-Reply-To: <20260529114031.3714-7-christian.koenig@amd.com>

On 2026. május 29., péntek 13:24:08 közép-európai nyári idő Christian König 
wrote:
> Add a new function amdgpu_vm_update_leaves() to avoid memory allocation
> on page faults.
> 
> The idea is to only update the leave PTEs to insert a dummy PRT PTE.

We should only use PRT PTEs on GPUs that do not have the SMEM PRT bug,
in other words only GFX9 for now.

As-is, this basically regresses all the work that I did for retry faults.

Due to the SMEM PRT bug, using PRT PTEs is unacceptable because it would imply 
that we can only mitigate VM faults that come from VMEM instructions. That 
creates unnecessary inconsistency (inability to mitigate some VM faults) and 
poor user experience (GPU hangs).

> 
> TODO: HW older than GMC v9 needs a different solution.

Can you elaborate what different solution is needed?
As far as I know, GMC v6-v7-v8 do not use and do not need to call the 
amdgpu_vm_handle_fault() function, they can just mitigate page faults on their 
own.

> 
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c    | 40 ++++++++++---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h    |  3 +
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 71 ++++++++++++++++++++++-
>  3 files changed, 103 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index e5588346a03f..94632a660b79
> 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -2984,10 +2984,12 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device
> *adev, u32 pasid, u32 vmid, u32 node_id, uint64_t addr,
>  			    uint64_t ts, bool write_fault)
>  {
> -	bool is_compute_context = false;
> +	struct amdgpu_vm_update_params params;
> +	bool is_compute_context;
>  	struct amdgpu_bo *root;
>  	uint64_t value, flags;
>  	struct amdgpu_vm *vm;
> +	unsigned int idx;
>  	int r;
> 
>  	vm = amdgpu_vm_lock_by_pasid(adev, &root, pasid);
> @@ -3029,24 +3031,46 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device
> *adev, u32 pasid, value = adev->dummy_page_addr;
>  		flags |= AMDGPU_PTE_EXECUTABLE | AMDGPU_PTE_READABLE |
>  			AMDGPU_PTE_WRITEABLE;
> -
> +		/* On +gfx9 we can use the PRT functionality instead */
> +		if (!adev->gmc.gmc_funcs->set_prt) {
> +			flags &= ~AMDGPU_PTE_VALID;
> +			flags |= AMDGPU_PTE_PRT;
> +		}

As noted above, PRT should only be used on GFX9 (and potentially, future 
products where the SMEM PRT bug is fixed).

Also, checking the set_prt is not necessary here as this function only makes 
sense on GFX9 and newer.

Maybe we could help the confusion by documenting both amdgpu_vm_handle_fault() 
and amdgpu_gmc_handle_retry_fault() that they are only applicable to GFX9 and 
newer that support recoverable faults or retry faults. (In a separate commit 
from this one, though.)

>  	} else {
>  		/* Let the hw retry silently on the PTE */
>  		value = 0;
>  	}
> 
> +	if (!drm_dev_enter(adev_to_drm(adev), &idx)) {
> +		r = -ENODEV;
> +		goto error_unlock;
> +	}
> +
> +	amdgpu_vm_eviction_lock(vm);
> +	if (vm->evicting) {
> +		r = -EBUSY;
> +		goto error_dev_exit;
> +	}
> +
> +	memset(&params, 0, sizeof(params));
> +	params.adev = adev;
> +	params.vm = vm;
> +	params.immediate = true;
> +	params.pages_addr = NULL;
> +
>  	r = dma_resv_reserve_fences(root->tbo.base.resv, 1);
>  	if (r) {
>  		pr_debug("failed %d to reserve fence slot\n", r);
> -		goto error_unlock;
> +		goto error_eviction_lock;
>  	}
> 
> -	r = amdgpu_vm_update_range(adev, vm, true, false, false, false,
> -				   NULL, addr, addr, flags, value, 
0, NULL, NULL, NULL);
> -	if (r)
> -		goto error_unlock;
> +	amdgpu_vm_update_leaves(&params, addr, addr, value, flags);
> 
> -	r = amdgpu_vm_update_pdes(adev, vm, true);
> +error_eviction_lock:
> +	amdgpu_vm_eviction_unlock(vm);
> +
> +error_dev_exit:
> +	drm_dev_exit(idx);
> 
>  error_unlock:
>  	amdgpu_bo_unreserve(root);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index cc096c005e34..04b32accfa3f
> 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -613,6 +613,9 @@ int amdgpu_vm_pde_update(struct amdgpu_vm_update_params
> *params, int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
> uint64_t start, uint64_t end,
>  			  uint64_t dst, uint64_t flags);
> +void amdgpu_vm_update_leaves(struct amdgpu_vm_update_params *params,
> +			     uint64_t start, uint64_t end,
> +			     int64_t dst, uint64_t flags);
>  void amdgpu_vm_pt_free_work(struct work_struct *work);
>  void amdgpu_vm_pt_free_list(struct amdgpu_device *adev,
>  			    struct amdgpu_vm_update_params *params);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c index
> e43a60d09808..9766b6b9aecc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
> @@ -790,6 +790,8 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params
> *params, uint64_t dst, uint64_t flags)
>  {
>  	struct amdgpu_device *adev = params->adev;
> +	struct amdgpu_vm *vm = params->vm;
> +	pid_t tgid = vm->task_info ? vm->task_info->tgid : 0;

These spurious changes in amdgpu_vm_ptes_update() look unrelated the rest of 
the commit, so I think they should either be split off into a separate commit 
or explained in the commit message why they are necessary here.

>  	struct amdgpu_vm_pt_cursor cursor;
>  	uint64_t frag_start = start, frag_end;
>  	unsigned int frag;
> @@ -881,7 +883,6 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params
> *params, entry_end = min(entry_end, end);
> 
>  		do {
> -			struct amdgpu_vm *vm = params->vm;
>  			uint64_t upd_end = min(entry_end, frag_end);
>  			unsigned int nptes = (upd_end - frag_start) 
>> shift;
>  			uint64_t upd_flags = flags | 
AMDGPU_PTE_FRAG(frag);
> @@ -893,8 +894,7 @@ int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params
> *params,
> 
>  			trace_amdgpu_vm_update_ptes(params, 
frag_start, upd_end,
>  						    
min(nptes, 32u), dst, incr,
> -						    
upd_flags,
> -						    vm-
>task_info ? vm->task_info->tgid : 0,
> +						    
upd_flags, tgid,
>  						    vm-
>immediate.fence_context);
>  			amdgpu_vm_pte_update_flags(params, 
to_amdgpu_bo_vm(pt),
>  						   
cursor.level, pe_start, dst,
> @@ -938,6 +938,71 @@ int amdgpu_vm_ptes_update(struct
> amdgpu_vm_update_params *params, return 0;
>  }
> 
> +/**
> + * amdgpu_vm_update_leaves - update leave PDEs/PTEs
> + *
> + * @params: see amdgpu_vm_update_params definition
> + * @start: start of GPU address range
> + * @end: end of GPU address range
> + * @dst: destination address to insert into the leave PDEs/PTEs
> + * @flags: mapping flags
> + *
> + * Update the leave PDEs/PTEs in the range @start - @end without allocating
> or + * freeing page tables.
> + *
> + * Returns:
> + * 0 for success, negative error code for failure.
> + */
> +void amdgpu_vm_update_leaves(struct amdgpu_vm_update_params *params,
> +			     uint64_t start, uint64_t end,
> +			     int64_t dst, uint64_t flags)
> +{
> +	struct amdgpu_device *adev = params->adev;
> +	struct amdgpu_vm *vm = params->vm;
> +	pid_t tgid = vm->task_info ? vm->task_info->tgid : 0;
> +	struct amdgpu_vm_pt_cursor cursor;
> +
> +	amdgpu_vm_pt_start(adev, params->vm, start, &cursor);
> +	while (cursor.pfn < end) {
> +		unsigned int shift, mask;
> +		uint64_t entry_end, pe_start;
> +		struct amdgpu_bo *pt;
> +		unsigned int nptes;
> +
> +		/* Walk to the leave entries */
> +		if (amdgpu_vm_pt_descendant(adev, &cursor))
> +			continue;
> +
> +		pt = cursor.parent->bo;
> +		shift = amdgpu_vm_pt_level_shift(adev, cursor.level - 
1);
> +		mask = amdgpu_vm_pt_entries_mask(adev, cursor.level - 
1);
> +
> +		/* Looks good so far, calculate parameters for the 
update */
> +		pe_start = ((cursor.pfn >> shift) & mask) * 8;
> +
> +		entry_end = ((uint64_t)mask + 1) << shift;
> +		entry_end += cursor.pfn & ~(entry_end - 1);
> +		entry_end = min(entry_end, end);
> +
> +		nptes = (entry_end - cursor.pfn) >> shift;
> +		/*
> +		 * This can happen when we set higher level PDEs to 
unmap and/or
> +		 * silent to stop fault floods.
> +		 */
> +		nptes = max(nptes, 1u);
> +
> +		trace_amdgpu_vm_update_ptes(params, cursor.pfn, 
entry_end,
> +					    min(nptes, 32u), 
dst, 0, flags,
> +					    tgid,
> +					    vm-
>immediate.fence_context);
> +		amdgpu_vm_pte_update_flags(params, to_amdgpu_bo_vm(pt),
> +					   cursor.level - 1, 
pe_start, dst,
> +					   nptes, 0, flags);
> +
> +		amdgpu_vm_pt_next(adev, &cursor);
> +	}
> +}
> +
>  /**
>   * amdgpu_vm_pt_map_tables - have bo of root PD cpu accessible
>   * @adev: amdgpu device structure





  reply	other threads:[~2026-06-12  6:54 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-29 11:24 Christian König
2026-05-29 11:24 ` [PATCH 01/13] drm/amdgpu: move suballoc defines into own header Christian König
2026-06-10  7:53   ` Christian König
2026-06-10 16:14   ` Kuehling, Felix
2026-06-12  6:12   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 02/13] drm/amdgpu: give different sizes for each SA pool type Christian König
2026-06-12  6:13   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 03/13] drm/amdgpu: add gfp_flags to amdgpu_sa_manager Christian König
2026-06-12  6:18   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 04/13] drm/amdgpu: move job parameter to the end in amdgpu_job_alloc() and *_with_ib() Christian König
2026-06-12  6:21   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 05/13] drm/amdgpu: use correct gfp_t for job allocation Christian König
2026-06-12  6:33   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 06/13] drm/amdgpu: add amdgpu_vm_update_leaves() Christian König
2026-06-12  6:54   ` Timur Kristóf [this message]
2026-05-29 11:24 ` [PATCH 07/13] drm/amdgpu: drop immediate updates from amdgpu_vm_update_range Christian König
2026-06-12  6:58   ` Timur Kristóf
2026-05-29 11:24 ` [PATCH 08/13] drm/amdgpu: split amdgpu_vm_update_range Christian König
2026-06-01 13:51   ` Pierre-Eric Pelloux-Prayer
2026-06-01 13:58     ` Christian König
2026-06-03 17:54   ` Kuehling, Felix
2026-06-05  9:21     ` Christian König
2026-06-05 19:21       ` Kuehling, Felix
2026-06-04 10:03   ` Huang, Honglei
2026-05-29 11:24 ` [PATCH 09/13] drm/amdgpu: start to move VM internals into amdgpu_vm_internal.h Christian König
2026-05-29 11:24 ` [PATCH 10/13] drm/amdgpu: remove unecessary parameters from trace_amdgpu_vm_update_ptes Christian König
2026-05-29 11:24 ` [PATCH 11/13] drm/amdgpu: nuke most amdgpu_vm_eviction_(try)lock uses Christian König
2026-06-03 18:00   ` Kuehling, Felix
2026-05-29 11:24 ` [PATCH 12/13] drm/amdgpu: rework eviction lock handling into critical section Christian König
2026-05-29 11:24 ` [PATCH 13/13] drm/amdgpu: fix the HMM range handling for KFD SVM Christian König
2026-06-03 19:23   ` Kuehling, Felix
2026-05-29 13:35 ` VM reworks Natalie Vock
2026-06-01  2:46 ` Huang, Honglei1

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=2299736.hkbZ0PkbqX@timur-max \
    --to=timur.kristof@gmail.com \
    --cc=Alexander.Deucher@amd.com \
    --cc=Felix.Kuehling@amd.com \
    --cc=Philip.Yang@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=honghuan@amd.com \
    --cc=natalie.vock@gmx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.