* [PATCH] drm/amdkfd: preserve the byte address when removing retry faults
@ 2026-11-08 9:15 Aveline Noir
2026-11-13 23:58 ` Kuehling, Felix
0 siblings, 1 reply; 2+ messages in thread
From: Aveline Noir @ 2026-11-08 9:15 UTC (permalink / raw)
To: Felix Kuehling, Alex Deucher, Christian König
Cc: David Airlie, amd-gfx, dri-devel, honghuan, honglei1.huang,
linux-kernel, Mikhail Gavrilov, Natalie Vock, Philip Yang,
Pierre-Eric Pelloux-Prayer, Prike Liang, psirt, sashiko-bot,
sashiko-reviews, Simona Vetter, Srinivasan Shanmugam,
Sunil Khatri, Timur Kristóf
svm_range_restore_pages() receives a CPU page number, but passes it
unchanged to amdgpu_gmc_filter_faults_remove() when recovery is deferred
or returns -EAGAIN. The software fault filter uses a byte address and
PASID as its key, so this can leave the fault filtered until the entry
ages out.
Pass the original byte address to svm_range_restore_pages() and derive
the CPU page number locally for range operations. Use the original
address for both filter removals. This also preserves the GPU subpage
offset when CPU pages are larger than the 4 KiB GPU page size.
Fixes: b3dc91f97317 ("drm/amdkfd: enable subsequent retry fault")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/sashiko-outbox-203586@kernel.org
Signed-off-by: Aveline Noir <jm5905938@gmail.com>
---
No testing on AMD hardware. Any test will be appreciated.
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +-
drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 7 ++++---
drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index c41e9c0916b7..86ef849097fa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3092,7 +3092,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
drm_exec_fini(&exec);
if (!svm_range_restore_pages(adev, pasid, vmid,
- node_id, addr >> PAGE_SHIFT, ts, write_fault))
+ node_id, addr, ts, write_fault))
return true;
/* Re-acquire the VM lock, could be that the VM was freed in between. */
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index 79455e23a030..c85d6bb73629 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -3130,8 +3130,9 @@ svm_fault_allowed(struct vm_area_struct *vma, bool write_fault)
int
svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
uint32_t vmid, uint32_t node_id,
- uint64_t addr, uint64_t ts, bool write_fault)
+ uint64_t fault_addr, uint64_t ts, bool write_fault)
{
+ uint64_t addr = fault_addr >> PAGE_SHIFT;
unsigned long start, last, size;
struct mm_struct *mm = NULL;
struct svm_range_list *svms;
@@ -3249,7 +3250,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
mutex_lock(&prange->migrate_mutex);
if (svm_range_skip_recover(prange)) {
- amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
+ amdgpu_gmc_filter_faults_remove(node->adev, fault_addr, pasid);
r = 0;
goto out_unlock_range;
}
@@ -3353,7 +3354,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
if (r == -EAGAIN) {
pr_debug("recover vm fault later\n");
- amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
+ amdgpu_gmc_filter_faults_remove(node->adev, fault_addr, pasid);
r = 0;
}
return r;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
index c7d7adae4476..38744e716f74 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -178,7 +178,7 @@ int svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
bool clear);
void svm_range_vram_node_free(struct svm_range *prange);
int svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
- uint32_t vmid, uint32_t node_id, uint64_t addr, uint64_t ts,
+ uint32_t vmid, uint32_t node_id, uint64_t fault_addr, uint64_t ts,
bool write_fault);
int svm_range_evict_svm_bo(struct amdgpu_bo *bo);
@@ -230,7 +230,7 @@ static inline void svm_range_list_fini(struct kfd_process *p)
static inline int svm_range_restore_pages(struct amdgpu_device *adev,
unsigned int pasid,
uint32_t client_id, uint32_t node_id,
- uint64_t addr, uint64_t ts, bool write_fault)
+ uint64_t fault_addr, uint64_t ts, bool write_fault)
{
return -EFAULT;
}
---
base-commit: 403b3d68346d7ba25f474f0686ad1d05feb65b7c
change-id: 20261108-kfd-fault-filter-address-20261108-4f096f2b2a1a
Best regards,
--
Aveline Noir <jm5905938@gmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] drm/amdkfd: preserve the byte address when removing retry faults
2026-11-08 9:15 [PATCH] drm/amdkfd: preserve the byte address when removing retry faults Aveline Noir
@ 2026-11-13 23:58 ` Kuehling, Felix
0 siblings, 0 replies; 2+ messages in thread
From: Kuehling, Felix @ 2026-11-13 23:58 UTC (permalink / raw)
To: Aveline Noir, Alex Deucher, Christian König
Cc: David Airlie, amd-gfx, dri-devel, honghuan, honglei1.huang,
linux-kernel, Mikhail Gavrilov, Natalie Vock, Philip Yang,
Pierre-Eric Pelloux-Prayer, Prike Liang, psirt, sashiko-bot,
sashiko-reviews, Simona Vetter, Srinivasan Shanmugam,
Sunil Khatri, Timur Kristóf
On 2026-11-08 04:15, Aveline Noir wrote:
> svm_range_restore_pages() receives a CPU page number, but passes it
> unchanged to amdgpu_gmc_filter_faults_remove() when recovery is deferred
> or returns -EAGAIN. The software fault filter uses a byte address and
> PASID as its key, so this can leave the fault filtered until the entry
> ages out.
>
> Pass the original byte address to svm_range_restore_pages() and derive
> the CPU page number locally for range operations. Use the original
> address for both filter removals. This also preserves the GPU subpage
> offset when CPU pages are larger than the 4 KiB GPU page size.
Good catch. All the addresses in page fault handlers and the filter
should all be be 4KB page aligned (GPU page size). But
svm_range_restore_pages works with page numbers based on the CPU page
size, which may be larger on some architectures. So passing in the byte
address is the most sane way to keep it straight. The patch is
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
I'm applying it to amd-staging-drm-next.
>
> Fixes: b3dc91f97317 ("drm/amdkfd: enable subsequent retry fault")
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://lore.kernel.org/r/sashiko-outbox-203586@kernel.org
> Signed-off-by: Aveline Noir <jm5905938@gmail.com>
> ---
> No testing on AMD hardware. Any test will be appreciated.
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +-
> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 7 ++++---
> drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 4 ++--
> 3 files changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index c41e9c0916b7..86ef849097fa 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -3092,7 +3092,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
> drm_exec_fini(&exec);
>
> if (!svm_range_restore_pages(adev, pasid, vmid,
> - node_id, addr >> PAGE_SHIFT, ts, write_fault))
> + node_id, addr, ts, write_fault))
> return true;
>
> /* Re-acquire the VM lock, could be that the VM was freed in between. */
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> index 79455e23a030..c85d6bb73629 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
> @@ -3130,8 +3130,9 @@ svm_fault_allowed(struct vm_area_struct *vma, bool write_fault)
> int
> svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
> uint32_t vmid, uint32_t node_id,
> - uint64_t addr, uint64_t ts, bool write_fault)
> + uint64_t fault_addr, uint64_t ts, bool write_fault)
> {
> + uint64_t addr = fault_addr >> PAGE_SHIFT;
> unsigned long start, last, size;
> struct mm_struct *mm = NULL;
> struct svm_range_list *svms;
> @@ -3249,7 +3250,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
> mutex_lock(&prange->migrate_mutex);
>
> if (svm_range_skip_recover(prange)) {
> - amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
> + amdgpu_gmc_filter_faults_remove(node->adev, fault_addr, pasid);
> r = 0;
> goto out_unlock_range;
> }
> @@ -3353,7 +3354,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
>
> if (r == -EAGAIN) {
> pr_debug("recover vm fault later\n");
> - amdgpu_gmc_filter_faults_remove(node->adev, addr, pasid);
> + amdgpu_gmc_filter_faults_remove(node->adev, fault_addr, pasid);
> r = 0;
> }
> return r;
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
> index c7d7adae4476..38744e716f74 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
> @@ -178,7 +178,7 @@ int svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
> bool clear);
> void svm_range_vram_node_free(struct svm_range *prange);
> int svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
> - uint32_t vmid, uint32_t node_id, uint64_t addr, uint64_t ts,
> + uint32_t vmid, uint32_t node_id, uint64_t fault_addr, uint64_t ts,
> bool write_fault);
> int svm_range_evict_svm_bo(struct amdgpu_bo *bo);
>
> @@ -230,7 +230,7 @@ static inline void svm_range_list_fini(struct kfd_process *p)
> static inline int svm_range_restore_pages(struct amdgpu_device *adev,
> unsigned int pasid,
> uint32_t client_id, uint32_t node_id,
> - uint64_t addr, uint64_t ts, bool write_fault)
> + uint64_t fault_addr, uint64_t ts, bool write_fault)
> {
> return -EFAULT;
> }
>
> ---
> base-commit: 403b3d68346d7ba25f474f0686ad1d05feb65b7c
> change-id: 20261108-kfd-fault-filter-address-20261108-4f096f2b2a1a
>
> Best regards,
> --
> Aveline Noir <jm5905938@gmail.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-13 23:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-08 9:15 [PATCH] drm/amdkfd: preserve the byte address when removing retry faults Aveline Noir
2026-11-13 23:58 ` Kuehling, Felix
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.