Skip to content

Commit fe25595

Browse files
drm/amdgpu: Do non-delayed updates correctly.
1 parent e1e599d commit fe25595

File tree

3 files changed

+89
-11
lines changed

3 files changed

+89
-11
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,11 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
608608
static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
609609
struct amdgpu_vm *vm,
610610
struct amdgpu_bo_va *bo_va,
611+
struct amdgpu_bo_va **old_bo_va,
611612
uint32_t operation,
612613
struct dma_fence **last_update)
613614
{
614-
int r;
615+
int r, i;
615616

616617
if (!amdgpu_vm_ready(vm))
617618
return;
@@ -625,6 +626,19 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
625626
r = amdgpu_vm_bo_update(adev, bo_va, false, NULL, last_update);
626627
if (r)
627628
goto error;
629+
} else {
630+
bo_va = NULL;
631+
}
632+
633+
for (i = 0; i < 2 && old_bo_va[i]; ++i) {
634+
if (old_bo_va[i] == bo_va ||
635+
(i && old_bo_va[i - 1] == old_bo_va[i]))
636+
continue;
637+
638+
r = amdgpu_vm_bo_update(adev, old_bo_va[i], false, NULL,
639+
last_update);
640+
if (r)
641+
goto error;
628642
}
629643

630644
r = amdgpu_vm_update_pdes(adev, vm, false, last_update);
@@ -680,6 +694,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
680694
struct drm_syncobj *syncobj = NULL;
681695
struct amdgpu_bo *abo;
682696
struct amdgpu_bo_va *bo_va;
697+
struct amdgpu_bo_va *old_bo_va[2] = {NULL, NULL};
683698
struct amdgpu_bo_list_entry vm_pd;
684699
struct ttm_validate_buffer tv;
685700
struct ww_acquire_ctx ticket;
@@ -786,9 +801,19 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
786801
* Update the VM once before to make sure there are no other
787802
* pending updates.
788803
*/
789-
if (!(args->flags & AMDGPU_VM_DELAY_UPDATE))
804+
if (!(args->flags & AMDGPU_VM_DELAY_UPDATE)) {
805+
if (args->operation == AMDGPU_VA_OP_CLEAR ||
806+
args->operation == AMDGPU_VA_OP_REPLACE) {
807+
amdgpu_vm_bo_clear_mappings_bo_va(adev, &fpriv->vm,
808+
args->va_address,
809+
args->map_size,
810+
old_bo_va);
811+
}
812+
790813
amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
791-
args->operation, NULL);
814+
old_bo_va, args->operation,
815+
NULL);
816+
}
792817
}
793818

794819
switch (args->operation) {
@@ -805,13 +830,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
805830
case AMDGPU_VA_OP_CLEAR:
806831
r = amdgpu_vm_bo_clear_mappings(adev, &fpriv->vm,
807832
args->va_address,
808-
args->map_size);
833+
args->map_size, old_bo_va);
809834
break;
810835
case AMDGPU_VA_OP_REPLACE:
811836
va_flags = amdgpu_gem_va_map_flags(adev, args->flags);
812837
r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address,
813838
args->offset_in_bo, args->map_size,
814-
va_flags);
839+
va_flags, old_bo_va);
815840
break;
816841
default:
817842
dev_dbg(dev->dev, "unsupported operation %d\n",
@@ -823,7 +848,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
823848
goto error_free_chain;
824849

825850
if (!(args->flags & AMDGPU_VM_DELAY_UPDATE))
826-
amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va,
851+
amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, old_bo_va,
827852
args->operation, syncobj ?
828853
&fence : NULL);
829854

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
23902390
* @offset: requested offset in the BO
23912391
* @size: BO size in bytes
23922392
* @flags: attributes of pages (read/write/valid/etc.)
2393+
* @updated_bo_va: will be set to the (up to 2) bo_va's that have new shrunk
2394+
* mappings, or unchanged otherwise.
23932395
*
23942396
* Add a mapping of the BO at the specefied addr into the VM. Replace existing
23952397
* mappings as we do so.
@@ -2402,7 +2404,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
24022404
int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
24032405
struct amdgpu_bo_va *bo_va,
24042406
uint64_t saddr, uint64_t offset,
2405-
uint64_t size, uint64_t flags)
2407+
uint64_t size, uint64_t flags,
2408+
struct amdgpu_bo_va **updated_bo_va)
24062409
{
24072410
struct amdgpu_bo_va_mapping *mapping;
24082411
struct amdgpu_bo *bo = bo_va->base.bo;
@@ -2426,7 +2429,8 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
24262429
if (!mapping)
24272430
return -ENOMEM;
24282431

2429-
r = amdgpu_vm_bo_clear_mappings(adev, bo_va->base.vm, saddr, size);
2432+
r = amdgpu_vm_bo_clear_mappings(adev, bo_va->base.vm, saddr, size,
2433+
updated_bo_va);
24302434
if (r) {
24312435
kfree(mapping);
24322436
return r;
@@ -2499,13 +2503,53 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
24992503
return 0;
25002504
}
25012505

2506+
/**
2507+
* amdgpu_vm_bo_clear_mappings_bo_va - determine bo_va of split mappings.
2508+
*
2509+
* @adev: amdgpu_device pointer
2510+
* @vm: VM structure to use
2511+
* @saddr: start of the range
2512+
* @size: size of the range
2513+
* @updated_bo_va: will be set to the (up to 2) bo_va's that have new shrunk
2514+
* mappings, or unchanged otherwise.
2515+
*
2516+
* Determines the bo_va of the split mappings that would result from
2517+
* amdgpu_vm_bo_clear_mappings.
2518+
*/
2519+
void amdgpu_vm_bo_clear_mappings_bo_va(struct amdgpu_device *adev,
2520+
struct amdgpu_vm *vm,
2521+
uint64_t saddr, uint64_t size,
2522+
struct amdgpu_bo_va **updated_bo_va)
2523+
{
2524+
struct amdgpu_bo_va_mapping *tmp;
2525+
uint64_t eaddr;
2526+
2527+
eaddr = saddr + size - 1;
2528+
saddr /= AMDGPU_GPU_PAGE_SIZE;
2529+
eaddr /= AMDGPU_GPU_PAGE_SIZE;
2530+
2531+
/* Now gather all removed mappings */
2532+
tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr);
2533+
while (tmp) {
2534+
if (tmp->start < saddr)
2535+
*updated_bo_va++ = tmp->bo_va;
2536+
2537+
if (tmp->last > eaddr)
2538+
*updated_bo_va++ = tmp->bo_va;
2539+
2540+
tmp = amdgpu_vm_it_iter_next(tmp, saddr, eaddr);
2541+
}
2542+
}
2543+
25022544
/**
25032545
* amdgpu_vm_bo_clear_mappings - remove all mappings in a specific range
25042546
*
25052547
* @adev: amdgpu_device pointer
25062548
* @vm: VM structure to use
25072549
* @saddr: start of the range
25082550
* @size: size of the range
2551+
* @updated_bo_va: will be set to the (up to 2) bo_va's that have new shrunk
2552+
* mappings, or unchanged otherwise.
25092553
*
25102554
* Remove all mappings in a range, split them as appropriate.
25112555
*
@@ -2514,7 +2558,8 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
25142558
*/
25152559
int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
25162560
struct amdgpu_vm *vm,
2517-
uint64_t saddr, uint64_t size)
2561+
uint64_t saddr, uint64_t size,
2562+
struct amdgpu_bo_va **updated_bo_va)
25182563
{
25192564
struct amdgpu_bo_va_mapping *before, *after, *tmp, *next;
25202565
LIST_HEAD(removed);
@@ -2584,6 +2629,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
25842629

25852630
/* Insert partial mapping before the range */
25862631
if (!list_empty(&before->list)) {
2632+
*updated_bo_va++ = before->bo_va;
25872633
amdgpu_vm_it_insert(before, &vm->va);
25882634
if (before->flags & AMDGPU_PTE_PRT)
25892635
amdgpu_vm_prt_get(adev);
@@ -2593,6 +2639,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
25932639

25942640
/* Insert partial mapping after the range */
25952641
if (!list_empty(&after->list)) {
2642+
*updated_bo_va++ = after->bo_va;
25962643
amdgpu_vm_it_insert(after, &vm->va);
25972644
if (after->flags & AMDGPU_PTE_PRT)
25982645
amdgpu_vm_prt_get(adev);

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,19 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
427427
int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
428428
struct amdgpu_bo_va *bo_va,
429429
uint64_t addr, uint64_t offset,
430-
uint64_t size, uint64_t flags);
430+
uint64_t size, uint64_t flags,
431+
struct amdgpu_bo_va **updated_bo_va);
431432
int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
432433
struct amdgpu_bo_va *bo_va,
433434
uint64_t addr);
434435
int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
435436
struct amdgpu_vm *vm,
436-
uint64_t saddr, uint64_t size);
437+
uint64_t saddr, uint64_t size,
438+
struct amdgpu_bo_va **updated_bo_va);
439+
void amdgpu_vm_bo_clear_mappings_bo_va(struct amdgpu_device *adev,
440+
struct amdgpu_vm *vm,
441+
uint64_t saddr, uint64_t size,
442+
struct amdgpu_bo_va **updated_bo_va);
437443
struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
438444
uint64_t addr);
439445
void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);

0 commit comments

Comments
 (0)