diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 84 | 
1 files changed, 24 insertions, 60 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 352b30409060..e73d152659a2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -181,7 +181,7 @@ static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,  	if (level == adev->vm_manager.root_level)  		/* For the root directory */ -		return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift; +		return round_up(adev->vm_manager.max_pfn, 1ULL << shift) >> shift;  	else if (level != AMDGPU_VM_PTB)  		/* Everything in between */  		return 512; @@ -617,7 +617,8 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm,  {  	entry->priority = 0;  	entry->tv.bo = &vm->root.base.bo->tbo; -	entry->tv.shared = true; +	/* One for the VM updates, one for TTM and one for the CS job */ +	entry->tv.num_shared = 3;  	entry->user_pages = NULL;  	list_add(&entry->tv.head, validated);  } @@ -773,10 +774,6 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,  	ring = container_of(vm->entity.rq->sched, struct amdgpu_ring, sched); -	r = reservation_object_reserve_shared(bo->tbo.resv); -	if (r) -		return r; -  	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);  	if (r)  		goto error; @@ -1632,13 +1629,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,  			continue;  		} -		/* First check if the entry is already handled */ -		if (cursor.pfn < frag_start) { -			cursor.entry->huge = true; -			amdgpu_vm_pt_next(adev, &cursor); -			continue; -		} -  		/* If it isn't already handled it can't be a huge page */  		if (cursor.entry->huge) {  			/* Add the entry to the relocated list to update it. */ @@ -1663,9 +1653,11 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,  			if (!amdgpu_vm_pt_descendant(adev, &cursor))  				return -ENOENT;  			continue; -		} else if (frag >= parent_shift) { +		} else if (frag >= parent_shift && +			   cursor.level - 1 != adev->vm_manager.root_level) {  			/* If the fragment size is even larger than the parent -			 * shift we should go up one level and check it again. +			 * shift we should go up one level and check it again +			 * unless one level up is the root level.  			 */  			if (!amdgpu_vm_pt_ancestor(&cursor))  				return -ENOENT; @@ -1673,10 +1665,10 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,  		}  		/* Looks good so far, calculate parameters for the update */ -		incr = AMDGPU_GPU_PAGE_SIZE << shift; +		incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;  		mask = amdgpu_vm_entries_mask(adev, cursor.level);  		pe_start = ((cursor.pfn >> shift) & mask) * 8; -		entry_end = (mask + 1) << shift; +		entry_end = (uint64_t)(mask + 1) << shift;  		entry_end += cursor.pfn & ~(entry_end - 1);  		entry_end = min(entry_end, end); @@ -1689,7 +1681,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,  					      flags | AMDGPU_PTE_FRAG(frag));  			pe_start += nptes * 8; -			dst += nptes * AMDGPU_GPU_PAGE_SIZE << shift; +			dst += (uint64_t)nptes * AMDGPU_GPU_PAGE_SIZE << shift;  			frag_start = upd_end;  			if (frag_start >= frag_end) { @@ -1701,8 +1693,17 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,  			}  		} while (frag_start < entry_end); -		if (frag >= shift) +		if (amdgpu_vm_pt_descendant(adev, &cursor)) { +			/* Mark all child entries as huge */ +			while (cursor.pfn < frag_start) { +				cursor.entry->huge = true; +				amdgpu_vm_pt_next(adev, &cursor); +			} + +		} else if (frag >= shift) { +			/* or just move on to the next on the same level. */  			amdgpu_vm_pt_next(adev, &cursor); +		}  	}  	return 0; @@ -1840,10 +1841,6 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,  	if (r)  		goto error_free; -	r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv); -	if (r) -		goto error_free; -  	r = amdgpu_vm_update_ptes(¶ms, start, last + 1, addr, flags);  	if (r)  		goto error_free; @@ -3024,6 +3021,10 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	if (r)  		goto error_free_root; +	r = reservation_object_reserve_shared(root->tbo.resv, 1); +	if (r) +		goto error_unreserve; +  	r = amdgpu_vm_clear_bo(adev, vm, root,  			       adev->vm_manager.root_level,  			       vm->pte_support_ats); @@ -3053,7 +3054,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,  	}  	INIT_KFIFO(vm->faults); -	vm->fault_credit = 16;  	return 0; @@ -3266,42 +3266,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)  }  /** - * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID - * - * @adev: amdgpu_device pointer - * @pasid: PASID do identify the VM - * - * This function is expected to be called in interrupt context. - * - * Returns: - * True if there was fault credit, false otherwise - */ -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, -				  unsigned int pasid) -{ -	struct amdgpu_vm *vm; - -	spin_lock(&adev->vm_manager.pasid_lock); -	vm = idr_find(&adev->vm_manager.pasid_idr, pasid); -	if (!vm) { -		/* VM not found, can't track fault credit */ -		spin_unlock(&adev->vm_manager.pasid_lock); -		return true; -	} - -	/* No lock needed. only accessed by IRQ handler */ -	if (!vm->fault_credit) { -		/* Too many faults in this VM */ -		spin_unlock(&adev->vm_manager.pasid_lock); -		return false; -	} - -	vm->fault_credit--; -	spin_unlock(&adev->vm_manager.pasid_lock); -	return true; -} - -/**   * amdgpu_vm_manager_init - init the VM manager   *   * @adev: amdgpu_device pointer | 
