Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: invalidate moved BOs in the VM (v2)

Don't wait for the BO to be used again, just
update the PT on the next VM use.

v2: remove stray semicolon.

Signed-off-by: Christian König <christian.koenig@amd.com>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
e31ad969 c08abf11

+49 -12
+6 -1
drivers/gpu/drm/radeon/radeon.h
··· 450 450 uint64_t soffset; 451 451 uint64_t eoffset; 452 452 uint32_t flags; 453 - bool valid; 453 + uint64_t addr; 454 454 unsigned ref_count; 455 455 456 456 /* protected by vm mutex */ ··· 879 879 struct radeon_vm { 880 880 struct list_head va; 881 881 unsigned id; 882 + 883 + /* BOs moved, but not yet updated in the PT */ 884 + struct list_head invalidated; 882 885 883 886 /* BOs freed, but not yet updated in the PT */ 884 887 struct list_head freed; ··· 2890 2887 struct radeon_vm *vm); 2891 2888 int radeon_vm_clear_freed(struct radeon_device *rdev, 2892 2889 struct radeon_vm *vm); 2890 + int radeon_vm_clear_invalids(struct radeon_device *rdev, 2891 + struct radeon_vm *vm); 2893 2892 int radeon_vm_bo_update(struct radeon_device *rdev, 2894 2893 struct radeon_bo_va *bo_va, 2895 2894 struct ttm_mem_reg *mem);
+2 -1
drivers/gpu/drm/radeon/radeon_cs.c
··· 500 500 if (r) 501 501 return r; 502 502 } 503 - return 0; 503 + 504 + return radeon_vm_clear_invalids(rdev, vm); 504 505 } 505 506 506 507 static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev,
+41 -10
drivers/gpu/drm/radeon/radeon_vm.c
··· 329 329 bo_va->soffset = 0; 330 330 bo_va->eoffset = 0; 331 331 bo_va->flags = 0; 332 - bo_va->valid = false; 332 + bo_va->addr = 0; 333 333 bo_va->ref_count = 1; 334 334 INIT_LIST_HEAD(&bo_va->bo_list); 335 335 INIT_LIST_HEAD(&bo_va->vm_list); ··· 486 486 bo_va->soffset = soffset; 487 487 bo_va->eoffset = eoffset; 488 488 bo_va->flags = flags; 489 - bo_va->valid = false; 489 + bo_va->addr = 0; 490 490 list_move(&bo_va->vm_list, head); 491 491 492 492 soffset = (soffset / RADEON_GPU_PAGE_SIZE) >> radeon_vm_block_size; ··· 847 847 uint64_t addr; 848 848 int r; 849 849 850 - 851 850 if (!bo_va->soffset) { 852 851 dev_err(rdev->dev, "bo %p don't has a mapping in vm %p\n", 853 852 bo_va->bo, vm); 854 853 return -EINVAL; 855 854 } 856 855 857 - if ((bo_va->valid && mem) || (!bo_va->valid && mem == NULL)) 858 - return 0; 856 + list_del_init(&bo_va->vm_status); 859 857 860 858 bo_va->flags &= ~RADEON_VM_PAGE_VALID; 861 859 bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; ··· 862 864 addr = mem->start << PAGE_SHIFT; 863 865 if (mem->mem_type != TTM_PL_SYSTEM) { 864 866 bo_va->flags |= RADEON_VM_PAGE_VALID; 865 - bo_va->valid = true; 866 867 } 867 868 if (mem->mem_type == TTM_PL_TT) { 868 869 bo_va->flags |= RADEON_VM_PAGE_SYSTEM; ··· 873 876 } 874 877 } else { 875 878 addr = 0; 876 - bo_va->valid = false; 877 879 } 880 + 881 + if (addr == bo_va->addr) 882 + return 0; 883 + bo_va->addr = addr; 878 884 879 885 trace_radeon_vm_bo_update(bo_va); 880 886 ··· 941 941 int r; 942 942 943 943 list_for_each_entry_safe(bo_va, tmp, &vm->freed, vm_status) { 944 - list_del(&bo_va->vm_status); 945 944 r = radeon_vm_bo_update(rdev, bo_va, NULL); 946 945 kfree(bo_va); 947 946 if (r) ··· 948 949 } 949 950 return 0; 950 951 952 + } 953 + 954 + /** 955 + * radeon_vm_clear_invalids - clear invalidated BOs in the PT 956 + * 957 + * @rdev: radeon_device pointer 958 + * @vm: requested vm 959 + * 960 + * Make sure all invalidated BOs are cleared in the PT. 961 + * Returns 0 for success. 962 + * 963 + * PTs have to be reserved and mutex must be locked! 964 + */ 965 + int radeon_vm_clear_invalids(struct radeon_device *rdev, 966 + struct radeon_vm *vm) 967 + { 968 + struct radeon_bo_va *bo_va, *tmp; 969 + int r; 970 + 971 + list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, vm_status) { 972 + r = radeon_vm_bo_update(rdev, bo_va, NULL); 973 + if (r) 974 + return r; 975 + } 976 + return 0; 951 977 } 952 978 953 979 /** ··· 994 970 995 971 mutex_lock(&vm->mutex); 996 972 list_del(&bo_va->vm_list); 973 + list_del(&bo_va->vm_status); 997 974 998 - if (bo_va->soffset) { 975 + if (bo_va->addr) { 999 976 bo_va->bo = NULL; 1000 977 list_add(&bo_va->vm_status, &vm->freed); 1001 978 } else { ··· 1021 996 struct radeon_bo_va *bo_va; 1022 997 1023 998 list_for_each_entry(bo_va, &bo->va, bo_list) { 1024 - bo_va->valid = false; 999 + if (bo_va->addr) { 1000 + mutex_lock(&bo_va->vm->mutex); 1001 + list_del(&bo_va->vm_status); 1002 + list_add(&bo_va->vm_status, &bo_va->vm->invalidated); 1003 + mutex_unlock(&bo_va->vm->mutex); 1004 + } 1025 1005 } 1026 1006 } 1027 1007 ··· 1052 1022 vm->last_id_use = NULL; 1053 1023 mutex_init(&vm->mutex); 1054 1024 INIT_LIST_HEAD(&vm->va); 1025 + INIT_LIST_HEAD(&vm->invalidated); 1055 1026 INIT_LIST_HEAD(&vm->freed); 1056 1027 1057 1028 pd_size = radeon_vm_directory_size(rdev);