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

drm/radeon: update IB size estimation for VM

That should allow us to allocate bigger BOs.

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
cc6f3536 03f62abd

+30 -13
+30 -13
drivers/gpu/drm/radeon/radeon_vm.c
··· 410 410 addr = radeon_bo_gpu_offset(bo); 411 411 entries = radeon_bo_size(bo) / 8; 412 412 413 - r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, 414 - NULL, entries * 2 + 64); 413 + r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256); 415 414 if (r) 416 415 goto error; 417 416 ··· 418 419 419 420 radeon_vm_set_pages(rdev, &ib, addr, 0, entries, 0, 0); 420 421 radeon_asic_vm_pad_ib(rdev, &ib); 422 + WARN_ON(ib.length_dw > 64); 421 423 422 424 r = radeon_ib_schedule(rdev, &ib, NULL); 423 425 if (r) ··· 642 642 ndw = 64; 643 643 644 644 /* assume the worst case */ 645 - ndw += vm->max_pde_used * 16; 645 + ndw += vm->max_pde_used * 6; 646 646 647 647 /* update too big for an IB */ 648 648 if (ndw > 0xfffff) ··· 692 692 radeon_asic_vm_pad_ib(rdev, &ib); 693 693 radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj); 694 694 radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); 695 + WARN_ON(ib.length_dw > ndw); 695 696 r = radeon_ib_schedule(rdev, &ib, NULL); 696 697 if (r) { 697 698 radeon_ib_free(rdev, &ib); ··· 872 871 { 873 872 struct radeon_vm *vm = bo_va->vm; 874 873 struct radeon_ib ib; 875 - unsigned nptes, ndw; 874 + unsigned nptes, ncmds, ndw; 876 875 uint64_t addr; 876 + uint32_t flags; 877 877 int r; 878 878 879 879 if (!bo_va->it.start) { ··· 913 911 914 912 nptes = bo_va->it.last - bo_va->it.start + 1; 915 913 914 + /* reserve space for one command every (1 << BLOCK_SIZE) entries 915 + or 2k dwords (whatever is smaller) */ 916 + ncmds = (nptes >> min(radeon_vm_block_size, 11)) + 1; 917 + 916 918 /* padding, etc. */ 917 919 ndw = 64; 918 920 919 - if (radeon_vm_block_size > 11) 920 - /* reserve space for one header for every 2k dwords */ 921 - ndw += (nptes >> 11) * 4; 922 - else 923 - /* reserve space for one header for 924 - every (1 << BLOCK_SIZE) entries */ 925 - ndw += (nptes >> radeon_vm_block_size) * 4; 921 + flags = radeon_vm_page_flags(bo_va->flags); 922 + if ((flags & R600_PTE_GART_MASK) == R600_PTE_GART_MASK) { 923 + /* only copy commands needed */ 924 + ndw += ncmds * 7; 926 925 927 - /* reserve space for pte addresses */ 928 - ndw += nptes * 2; 926 + } else if (flags & R600_PTE_SYSTEM) { 927 + /* header for write data commands */ 928 + ndw += ncmds * 4; 929 + 930 + /* body of write data command */ 931 + ndw += nptes * 2; 932 + 933 + } else { 934 + /* set page commands needed */ 935 + ndw += ncmds * 10; 936 + 937 + /* two extra commands for begin/end of fragment */ 938 + ndw += 2 * 10; 939 + } 929 940 930 941 /* update too big for an IB */ 931 942 if (ndw > 0xfffff) ··· 954 939 radeon_vm_page_flags(bo_va->flags)); 955 940 956 941 radeon_asic_vm_pad_ib(rdev, &ib); 942 + WARN_ON(ib.length_dw > ndw); 943 + 957 944 radeon_semaphore_sync_to(ib.semaphore, vm->fence); 958 945 r = radeon_ib_schedule(rdev, &ib, NULL); 959 946 if (r) {