diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 20 | 
4 files changed, 28 insertions, 22 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 039b57e4644c..496f72b134eb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -459,6 +459,7 @@ struct amdgpu_bo {  	u64				metadata_flags;  	void				*metadata;  	u32				metadata_size; +	unsigned			prime_shared_count;  	/* list of all virtual address to which this bo  	 * is associated to  	 */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 651115dcce12..c02db01f6583 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,  		entry->priority = min(info[i].bo_priority,  				      AMDGPU_BO_LIST_MAX_PRIORITY);  		entry->tv.bo = &entry->robj->tbo; -		entry->tv.shared = true; +		entry->tv.shared = !entry->robj->prime_shared_count;  		if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)  			gds_obj = entry->robj; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7ca07e7b25c1..3161d77bf299 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -658,12 +658,10 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev)  		return false;  	if (amdgpu_passthrough(adev)) { -		/* for FIJI: In whole GPU pass-through virtualization case -		 * old smc fw won't clear some registers (e.g. MEM_SIZE, BIOS_SCRATCH) -		 * so amdgpu_card_posted return false and driver will incorrectly skip vPost. -		 * but if we force vPost do in pass-through case, the driver reload will hang. -		 * whether doing vPost depends on amdgpu_card_posted if smc version is above -		 * 00160e00 for FIJI. +		/* for FIJI: In whole GPU pass-through virtualization case, after VM reboot +		 * some old smc fw still need driver do vPost otherwise gpu hang, while +		 * those smc fw version above 22.15 doesn't have this flaw, so we force +		 * vpost executed for smc version below 22.15  		 */  		if (adev->asic_type == CHIP_FIJI) {  			int err; @@ -674,22 +672,11 @@ static bool amdgpu_vpost_needed(struct amdgpu_device *adev)  				return true;  			fw_ver = *((uint32_t *)adev->pm.fw->data + 69); -			if (fw_ver >= 0x00160e00) -				return !amdgpu_card_posted(adev); +			if (fw_ver < 0x00160e00) +				return true;  		} -	} else { -		/* in bare-metal case, amdgpu_card_posted return false -		 * after system reboot/boot, and return true if driver -		 * reloaded. -		 * we shouldn't do vPost after driver reload otherwise GPU -		 * could hang. -		 */ -		if (amdgpu_card_posted(adev)) -			return false;  	} - -	/* we assume vPost is neede for all other cases */ -	return true; +	return !amdgpu_card_posted(adev);  }  /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 7700dc22f243..3826d5aea0a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,  	if (ret)  		return ERR_PTR(ret); +	bo->prime_shared_count = 1;  	return &bo->gem_base;  }  int amdgpu_gem_prime_pin(struct drm_gem_object *obj)  {  	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); -	int ret = 0; +	long ret = 0;  	ret = amdgpu_bo_reserve(bo, false);  	if (unlikely(ret != 0))  		return ret; +	/* +	 * Wait for all shared fences to complete before we switch to future +	 * use of exclusive fence on this prime shared bo. +	 */ +	ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false, +						  MAX_SCHEDULE_TIMEOUT); +	if (unlikely(ret < 0)) { +		DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret); +		amdgpu_bo_unreserve(bo); +		return ret; +	} +  	/* pin buffer into GTT */  	ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL); +	if (likely(ret == 0)) +		bo->prime_shared_count++; +  	amdgpu_bo_unreserve(bo);  	return ret;  } @@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj)  		return;  	amdgpu_bo_unpin(bo); +	if (bo->prime_shared_count) +		bo->prime_shared_count--;  	amdgpu_bo_unreserve(bo);  }  | 

