On 6/3/26 19:54, Kuehling, Felix wrote:
...
>> +    r = vm->update_funcs->prepare(&params, sync,
>> +                      AMDGPU_KERNEL_JOB_ID_VM_UNMAP_RANGE);
>> +    if (r)
>> +        goto error_free;
>> +
>> +    amdgpu_vm_update_leaves(&params, start, last, 0, flags);
>> +
>> +    r = vm->update_funcs->commit(&params, fence);
>> +    if (r)
>> +        goto error_free;
> 
> So this wraps amdgpu_vm_update_leaves with all the stuff that's necessary to 
> actually execute the page table update.

Yes, exactly that.

> I don't understand how amdgpu_vm_update_leaves works without this when you 
> call it directly from amdgpu_vm_handle_fault (in patch 6).

It does mostly the same, but not 100%.

> Shouldn't you use amdgpu_vm_unmap_range there instead?

No, the main difference is that calling amdgpu_vm_update_leaves() from the 
fault handler needs to bypass the normal sequencial handling of VM updates.

Background is that this is a band aid for a dma_fence based submission to avoid 
a full GPU lockup and instead just continue even when the rendering is 
incorrect.

> And if that's true, then maybe you can use the name amdgpu_vm_update_leaves 
> for this instead.

I'm certainly open for better naming.

Maybe we should call the function in amdgpu_vm_pt.c 
amdgpu_vm_pt_update_leaves() and the higher level function in amdgpu_vm.c just 
amdgpu_vm_update_leaves() ?

Thanks for the review,
Christian.


> 
> Regards,
>   Felix
> 
> 
>> +
>> +    amdgpu_vm_tlb_flush(&params, fence, tlb_cb);
>> +    amdgpu_vm_pt_free_list(adev, &params);
>> +    tlb_cb = NULL;
>> +
>> +error_free:
>> +    kfree(tlb_cb);
>> +    amdgpu_vm_eviction_unlock(vm);
>> +    drm_dev_exit(idx);
>> +    return r;
>> +}
>> +
>>   void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
>>                 struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM])
>>   {
>> @@ -1362,11 +1434,11 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, 
>> struct amdgpu_bo_va *bo_va,
>>             trace_amdgpu_vm_bo_update(mapping);
>>   -        r = amdgpu_vm_update_range(adev, vm, false, flush_tlb,
>> -                       !uncached, &sync, mapping->start,
>> -                       mapping->last, update_flags,
>> -                       mapping->offset, vram_base, mem,
>> -                       pages_addr, last_update);
>> +        r = amdgpu_vm_map_range(adev, vm, flush_tlb, !uncached, &sync,
>> +                    mapping->start, mapping->last,
>> +                    update_flags, mapping->offset,
>> +                    vram_base, mem, pages_addr,
>> +                    last_update);
>>           if (r)
>>               goto error_free;
>>       }
>> @@ -1565,9 +1637,9 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
>>               struct amdgpu_bo_va_mapping, list);
>>           list_del(&mapping->list);
>>   -        r = amdgpu_vm_update_range(adev, vm, false, true, false,
>> -                       &sync, mapping->start, mapping->last,
>> -                       0, 0, 0, NULL, NULL, &f);
>> +        r = amdgpu_vm_map_range(adev, vm, true, false,
>> +                    &sync, mapping->start, mapping->last,
>> +                    0, 0, 0, NULL, NULL, &f);
>>           amdgpu_vm_free_mapping(adev, vm, mapping, f);
>>           if (r) {
>>               dma_fence_put(f);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> index 3e86a2a470f0..561f2873d2ec 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
>> @@ -529,12 +529,16 @@ int amdgpu_vm_flush_compute_tlb(struct amdgpu_device 
>> *adev,
>>                   uint32_t xcc_mask);
>>   void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
>>                   struct amdgpu_vm *vm, struct amdgpu_bo *bo);
>> -int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>> -               bool unlocked, bool flush_tlb, bool allow_override,
>> +int amdgpu_vm_map_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>> +            bool flush_tlb, bool allow_override,
>> +            struct amdgpu_sync *sync, uint64_t start,
>> +            uint64_t last, uint64_t flags, uint64_t offset,
>> +            uint64_t vram_base, struct ttm_resource *res,
>> +            dma_addr_t *pages_addr, struct dma_fence **fence);
>> +int amdgpu_vm_unmap_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
>>                  struct amdgpu_sync *sync, uint64_t start,
>> -               uint64_t last, uint64_t flags, uint64_t offset,
>> -               uint64_t vram_base, struct ttm_resource *res,
>> -               dma_addr_t *pages_addr, struct dma_fence **fence);
>> +               uint64_t last, uint64_t flags,
>> +               struct dma_fence **fence);
>>   int amdgpu_vm_bo_update(struct amdgpu_device *adev,
>>               struct amdgpu_bo_va *bo_va,
>>               bool clear);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
>> index 6f5415d5a1bc..ac3f3e31e2e2 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
>> @@ -553,7 +553,6 @@ void amdgpu_vm_pt_free_list(struct amdgpu_device *adev,
>>                   struct amdgpu_vm_update_params *params)
>>   {
>>       struct amdgpu_vm_bo_base *entry, *next;
>> -    bool unlocked = params->unlocked;
>>         if (list_empty(&params->tlb_flush_waitlist))
>>           return;
>> @@ -561,7 +560,7 @@ void amdgpu_vm_pt_free_list(struct amdgpu_device *adev,
>>       /*
>>        * unlocked unmap clear page table leaves, warning to free the page 
>> entry.
>>        */
>> -    WARN_ON(unlocked);
>> +    WARN_ON(params->unlocked);
>>         list_for_each_entry_safe(entry, next, &params->tlb_flush_waitlist, 
>> vm_status)
>>           amdgpu_vm_pt_free(entry);
>> @@ -801,24 +800,17 @@ int amdgpu_vm_ptes_update(struct 
>> amdgpu_vm_update_params *params,
>>           uint64_t incr, entry_end, pe_start;
>>           struct amdgpu_bo *pt;
>>   -        if (!params->unlocked) {
>> -            /* make sure that the page tables covering the
>> -             * address range are actually allocated
>> -             */
>> -            r = amdgpu_vm_pt_alloc(params->adev, params->vm,
>> -                           &cursor);
>> -            if (r)
>> -                return r;
>> -        }
>> +        /* make sure that the page tables covering the
>> +         * address range are actually allocated
>> +         */
>> +        r = amdgpu_vm_pt_alloc(params->adev, params->vm, &cursor);
>> +        if (r)
>> +            return r;
>>             shift = amdgpu_vm_pt_level_shift(adev, cursor.level);
>>           parent_shift = amdgpu_vm_pt_level_shift(adev, cursor.level - 1);
>> -        if (params->unlocked) {
>> -            /* Unlocked updates are only allowed on the leaves */
>> -            if (amdgpu_vm_pt_descendant(adev, &cursor))
>> -                continue;
>> -        } else if (adev->asic_type < CHIP_VEGA10 &&
>> -               (flags & AMDGPU_PTE_VALID)) {
>> +        if (adev->asic_type < CHIP_VEGA10 &&
>> +            (flags & AMDGPU_PTE_VALID)) {
>>               /* No huge page support before GMC v9 */
>>               if (cursor.level != AMDGPU_VM_PTB) {
>>                   if (!amdgpu_vm_pt_descendant(adev, &cursor))
>> @@ -864,14 +856,7 @@ int amdgpu_vm_ptes_update(struct 
>> amdgpu_vm_update_params *params,
>>           mask = amdgpu_vm_pt_entries_mask(adev, cursor.level);
>>           pe_start = ((cursor.pfn >> shift) & mask) * 8;
>>   -        if (cursor.level < AMDGPU_VM_PTB && params->unlocked)
>> -            /*
>> -             * MMU notifier callback unlocked unmap huge page, leave is PDE 
>> entry,
>> -             * only clear one entry. Next entry search again for PDE or PTE 
>> leave.
>> -             */
>> -            entry_end = 1ULL << shift;
>> -        else
>> -            entry_end = ((uint64_t)mask + 1) << shift;
>> +        entry_end = ((uint64_t)mask + 1) << shift;
>>           entry_end += cursor.pfn & ~(entry_end - 1);
>>           entry_end = min(entry_end, end);
>>   diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c 
>> b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>> index 37b5166e9a14..d0ea20dea3e1 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>> @@ -1372,9 +1372,8 @@ svm_range_unmap_from_gpu(struct amdgpu_device *adev, 
>> struct amdgpu_vm *vm,
>>           return -EINVAL;
>>       }
>>   -    return amdgpu_vm_update_range(adev, vm, true, true, false, NULL, 
>> gpu_start,
>> -                      gpu_end, init_pte_value, 0, 0, NULL, NULL,
>> -                      fence);
>> +    return amdgpu_vm_unmap_range(adev, vm, NULL, gpu_start, gpu_end,
>> +                     init_pte_value, fence);
>>   }
>>     static int
>> @@ -1489,12 +1488,11 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, 
>> struct svm_range *prange,
>>                (last_domain == SVM_RANGE_VRAM_DOMAIN) ? 1 : 0,
>>                pte_flags);
>>   -        r = amdgpu_vm_update_range(adev, vm, false, flush_tlb, true,
>> -                       NULL, gpu_start, gpu_end,
>> -                       pte_flags,
>> -                       (last_start - prange->start) << PAGE_SHIFT,
>> -                       bo_adev ? bo_adev->vm_manager.vram_base_offset : 0,
>> -                       NULL, dma_addr, &vm->last_update);
>> +        r = amdgpu_vm_map_range(adev, vm, flush_tlb, true, NULL,
>> +                    gpu_start, gpu_end, pte_flags,
>> +                    (last_start - prange->start) << PAGE_SHIFT,
>> +                    bo_adev ? bo_adev->vm_manager.vram_base_offset : 0,
>> +                    NULL, dma_addr, &vm->last_update);
>>             for (j = last_start - prange->start; j <= i; j++)
>>               dma_addr[j] |= last_domain;

Reply via email to