[PATCH 2/2] drm/amdgpu: clean up UVD instance handling v2

Leo Liu leo.liu at amd.com
Thu Jul 19 13:20:15 UTC 2018



On 07/18/2018 02:44 PM, Christian König wrote:
> The whole handle, filp and entity handling is superfluous here.
>
> We should have reviewed that more thoughtfully. It looks like somebody
> just made the code instance aware without knowing the background.
Yeah It's only required for UVD without VMID support.

Reviewed-by: Leo Liu <leo.liu at amd.com>


> v2: fix one more missed case in amdgpu_uvd_suspend
>
> Signed-off-by: Christian König <christian.koenig at amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 121 ++++++++++++++++----------------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h |  10 +--
>   2 files changed, 64 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> index d708970244eb..80b5c453f8c1 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
> @@ -263,21 +263,20 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
>   			dev_err(adev->dev, "(%d) failed to allocate UVD bo\n", r);
>   			return r;
>   		}
> +	}
>   
> -		ring = &adev->uvd.inst[j].ring;
> -		rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
> -		r = drm_sched_entity_init(&adev->uvd.inst[j].entity, &rq,
> -					  1, NULL);
> -		if (r != 0) {
> -			DRM_ERROR("Failed setting up UVD(%d) run queue.\n", j);
> -			return r;
> -		}
> -
> -		for (i = 0; i < adev->uvd.max_handles; ++i) {
> -			atomic_set(&adev->uvd.inst[j].handles[i], 0);
> -			adev->uvd.inst[j].filp[i] = NULL;
> -		}
> +	ring = &adev->uvd.inst[0].ring;
> +	rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL];
> +	r = drm_sched_entity_init(&adev->uvd.entity, &rq, 1, NULL);
> +	if (r) {
> +		DRM_ERROR("Failed setting up UVD kernel entity.\n");
> +		return r;
>   	}
> +	for (i = 0; i < adev->uvd.max_handles; ++i) {
> +		atomic_set(&adev->uvd.handles[i], 0);
> +		adev->uvd.filp[i] = NULL;
> +	}
> +
>   	/* from uvd v5.0 HW addressing capacity increased to 64 bits */
>   	if (!amdgpu_device_ip_block_version_cmp(adev, AMD_IP_BLOCK_TYPE_UVD, 5, 0))
>   		adev->uvd.address_64_bit = true;
> @@ -306,11 +305,12 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
>   {
>   	int i, j;
>   
> +	drm_sched_entity_destroy(&adev->uvd.inst->ring.sched,
> +				 &adev->uvd.entity);
> +
>   	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
>   		kfree(adev->uvd.inst[j].saved_bo);
>   
> -		drm_sched_entity_destroy(&adev->uvd.inst[j].ring.sched, &adev->uvd.inst[j].entity);
> -
>   		amdgpu_bo_free_kernel(&adev->uvd.inst[j].vcpu_bo,
>   				      &adev->uvd.inst[j].gpu_addr,
>   				      (void **)&adev->uvd.inst[j].cpu_addr);
> @@ -333,20 +333,20 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
>   
>   	cancel_delayed_work_sync(&adev->uvd.idle_work);
>   
> +	/* only valid for physical mode */
> +	if (adev->asic_type < CHIP_POLARIS10) {
> +		for (i = 0; i < adev->uvd.max_handles; ++i)
> +			if (atomic_read(&adev->uvd.handles[i]))
> +				break;
> +
> +		if (i == adev->uvd.max_handles)
> +			return 0;
> +	}
> +
>   	for (j = 0; j < adev->uvd.num_uvd_inst; ++j) {
>   		if (adev->uvd.inst[j].vcpu_bo == NULL)
>   			continue;
>   
> -		/* only valid for physical mode */
> -		if (adev->asic_type < CHIP_POLARIS10) {
> -			for (i = 0; i < adev->uvd.max_handles; ++i)
> -				if (atomic_read(&adev->uvd.inst[j].handles[i]))
> -					break;
> -
> -			if (i == adev->uvd.max_handles)
> -				continue;
> -		}
> -
>   		size = amdgpu_bo_size(adev->uvd.inst[j].vcpu_bo);
>   		ptr = adev->uvd.inst[j].cpu_addr;
>   
> @@ -398,30 +398,27 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
>   
>   void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp)
>   {
> -	struct amdgpu_ring *ring;
> -	int i, j, r;
> -
> -	for (j = 0; j < adev->uvd.num_uvd_inst; j++) {
> -		ring = &adev->uvd.inst[j].ring;
> +	struct amdgpu_ring *ring = &adev->uvd.inst[0].ring;
> +	int i, r;
>   
> -		for (i = 0; i < adev->uvd.max_handles; ++i) {
> -			uint32_t handle = atomic_read(&adev->uvd.inst[j].handles[i]);
> -			if (handle != 0 && adev->uvd.inst[j].filp[i] == filp) {
> -				struct dma_fence *fence;
> -
> -				r = amdgpu_uvd_get_destroy_msg(ring, handle,
> -							       false, &fence);
> -				if (r) {
> -					DRM_ERROR("Error destroying UVD(%d) %d!\n", j, r);
> -					continue;
> -				}
> +	for (i = 0; i < adev->uvd.max_handles; ++i) {
> +		uint32_t handle = atomic_read(&adev->uvd.handles[i]);
>   
> -				dma_fence_wait(fence, false);
> -				dma_fence_put(fence);
> +		if (handle != 0 && adev->uvd.filp[i] == filp) {
> +			struct dma_fence *fence;
>   
> -				adev->uvd.inst[j].filp[i] = NULL;
> -				atomic_set(&adev->uvd.inst[j].handles[i], 0);
> +			r = amdgpu_uvd_get_destroy_msg(ring, handle, false,
> +						       &fence);
> +			if (r) {
> +				DRM_ERROR("Error destroying UVD %d!\n", r);
> +				continue;
>   			}
> +
> +			dma_fence_wait(fence, false);
> +			dma_fence_put(fence);
> +
> +			adev->uvd.filp[i] = NULL;
> +			atomic_set(&adev->uvd.handles[i], 0);
>   		}
>   	}
>   }
> @@ -692,20 +689,19 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
>   			     struct amdgpu_bo *bo, unsigned offset)
>   {
>   	struct amdgpu_device *adev = ctx->parser->adev;
> -	uint32_t ip_instance = ctx->parser->ring->me;
>   	int32_t *msg, msg_type, handle;
>   	void *ptr;
>   	long r;
>   	int i;
>   
>   	if (offset & 0x3F) {
> -		DRM_ERROR("UVD(%d) messages must be 64 byte aligned!\n", ip_instance);
> +		DRM_ERROR("UVD messages must be 64 byte aligned!\n");
>   		return -EINVAL;
>   	}
>   
>   	r = amdgpu_bo_kmap(bo, &ptr);
>   	if (r) {
> -		DRM_ERROR("Failed mapping the UVD(%d) message (%ld)!\n", ip_instance, r);
> +		DRM_ERROR("Failed mapping the UVD) message (%ld)!\n", r);
>   		return r;
>   	}
>   
> @@ -715,7 +711,7 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
>   	handle = msg[2];
>   
>   	if (handle == 0) {
> -		DRM_ERROR("Invalid UVD(%d) handle!\n", ip_instance);
> +		DRM_ERROR("Invalid UVD handle!\n");
>   		return -EINVAL;
>   	}
>   
> @@ -726,18 +722,19 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
>   
>   		/* try to alloc a new handle */
>   		for (i = 0; i < adev->uvd.max_handles; ++i) {
> -			if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) {
> -				DRM_ERROR("(%d)Handle 0x%x already in use!\n", ip_instance, handle);
> +			if (atomic_read(&adev->uvd.handles[i]) == handle) {
> +				DRM_ERROR(")Handle 0x%x already in use!\n",
> +					  handle);
>   				return -EINVAL;
>   			}
>   
> -			if (!atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], 0, handle)) {
> -				adev->uvd.inst[ip_instance].filp[i] = ctx->parser->filp;
> +			if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) {
> +				adev->uvd.filp[i] = ctx->parser->filp;
>   				return 0;
>   			}
>   		}
>   
> -		DRM_ERROR("No more free UVD(%d) handles!\n", ip_instance);
> +		DRM_ERROR("No more free UVD handles!\n");
>   		return -ENOSPC;
>   
>   	case 1:
> @@ -749,27 +746,27 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx,
>   
>   		/* validate the handle */
>   		for (i = 0; i < adev->uvd.max_handles; ++i) {
> -			if (atomic_read(&adev->uvd.inst[ip_instance].handles[i]) == handle) {
> -				if (adev->uvd.inst[ip_instance].filp[i] != ctx->parser->filp) {
> -					DRM_ERROR("UVD(%d) handle collision detected!\n", ip_instance);
> +			if (atomic_read(&adev->uvd.handles[i]) == handle) {
> +				if (adev->uvd.filp[i] != ctx->parser->filp) {
> +					DRM_ERROR("UVD handle collision detected!\n");
>   					return -EINVAL;
>   				}
>   				return 0;
>   			}
>   		}
>   
> -		DRM_ERROR("Invalid UVD(%d) handle 0x%x!\n", ip_instance, handle);
> +		DRM_ERROR("Invalid UVD handle 0x%x!\n", handle);
>   		return -ENOENT;
>   
>   	case 2:
>   		/* it's a destroy msg, free the handle */
>   		for (i = 0; i < adev->uvd.max_handles; ++i)
> -			atomic_cmpxchg(&adev->uvd.inst[ip_instance].handles[i], handle, 0);
> +			atomic_cmpxchg(&adev->uvd.handles[i], handle, 0);
>   		amdgpu_bo_kunmap(bo);
>   		return 0;
>   
>   	default:
> -		DRM_ERROR("Illegal UVD(%d) message type (%d)!\n", ip_instance, msg_type);
> +		DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type);
>   		return -EINVAL;
>   	}
>   	BUG();
> @@ -1071,7 +1068,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
>   		if (r)
>   			goto err_free;
>   
> -		r = amdgpu_job_submit(job, &adev->uvd.inst[ring->me].entity,
> +		r = amdgpu_job_submit(job, &adev->uvd.entity,
>   				      AMDGPU_FENCE_OWNER_UNDEFINED, &f);
>   		if (r)
>   			goto err_free;
> @@ -1273,7 +1270,7 @@ uint32_t amdgpu_uvd_used_handles(struct amdgpu_device *adev)
>   		 * necessarily linear. So we need to count
>   		 * all non-zero handles.
>   		 */
> -		if (atomic_read(&adev->uvd.inst->handles[i]))
> +		if (atomic_read(&adev->uvd.handles[i]))
>   			used_handles++;
>   	}
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
> index cae3f526216b..66872286ab12 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h
> @@ -42,12 +42,9 @@ struct amdgpu_uvd_inst {
>   	void			*cpu_addr;
>   	uint64_t		gpu_addr;
>   	void			*saved_bo;
> -	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];
> -	struct drm_file		*filp[AMDGPU_MAX_UVD_HANDLES];
>   	struct amdgpu_ring	ring;
>   	struct amdgpu_ring	ring_enc[AMDGPU_MAX_UVD_ENC_RINGS];
>   	struct amdgpu_irq_src	irq;
> -	struct drm_sched_entity entity;
>   	uint32_t                srbm_soft_reset;
>   };
>   
> @@ -56,10 +53,13 @@ struct amdgpu_uvd {
>   	unsigned		fw_version;
>   	unsigned		max_handles;
>   	unsigned		num_enc_rings;
> -	uint8_t		num_uvd_inst;
> +	uint8_t			num_uvd_inst;
>   	bool			address_64_bit;
>   	bool			use_ctx_buf;
> -	struct amdgpu_uvd_inst		inst[AMDGPU_MAX_UVD_INSTANCES];
> +	struct amdgpu_uvd_inst	inst[AMDGPU_MAX_UVD_INSTANCES];
> +	struct drm_file		*filp[AMDGPU_MAX_UVD_HANDLES];
> +	atomic_t		handles[AMDGPU_MAX_UVD_HANDLES];
> +	struct drm_sched_entity entity;
>   	struct delayed_work	idle_work;
>   };
>   



More information about the amd-gfx mailing list