diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 78 | 
1 files changed, 78 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 0350205c4897..fc83445fbc40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -651,3 +651,81 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr)  	idr_destroy(&mgr->ctx_handles);  	mutex_destroy(&mgr->lock);  } + +static void amdgpu_ctx_fence_time(struct amdgpu_ctx *ctx, +		struct amdgpu_ctx_entity *centity, ktime_t *total, ktime_t *max) +{ +	ktime_t now, t1; +	uint32_t i; + +	*total = *max = 0; + +	now = ktime_get(); +	for (i = 0; i < amdgpu_sched_jobs; i++) { +		struct dma_fence *fence; +		struct drm_sched_fence *s_fence; + +		spin_lock(&ctx->ring_lock); +		fence = dma_fence_get(centity->fences[i]); +		spin_unlock(&ctx->ring_lock); +		if (!fence) +			continue; +		s_fence = to_drm_sched_fence(fence); +		if (!dma_fence_is_signaled(&s_fence->scheduled)) { +			dma_fence_put(fence); +			continue; +		} +		t1 = s_fence->scheduled.timestamp; +		if (!ktime_before(t1, now)) { +			dma_fence_put(fence); +			continue; +		} +		if (dma_fence_is_signaled(&s_fence->finished) && +			s_fence->finished.timestamp < now) +			*total += ktime_sub(s_fence->finished.timestamp, t1); +		else +			*total += ktime_sub(now, t1); +		t1 = ktime_sub(now, t1); +		dma_fence_put(fence); +		*max = max(t1, *max); +	} +} + +ktime_t amdgpu_ctx_mgr_fence_usage(struct amdgpu_ctx_mgr *mgr, uint32_t hwip, +		uint32_t idx, uint64_t *elapsed) +{ +	struct idr *idp; +	struct amdgpu_ctx *ctx; +	uint32_t id; +	struct amdgpu_ctx_entity *centity; +	ktime_t total = 0, max = 0; + +	if (idx >= AMDGPU_MAX_ENTITY_NUM) +		return 0; +	idp = &mgr->ctx_handles; +	mutex_lock(&mgr->lock); +	idr_for_each_entry(idp, ctx, id) { +		ktime_t ttotal, tmax; + +		if (!ctx->entities[hwip][idx]) +			continue; + +		centity = ctx->entities[hwip][idx]; +		amdgpu_ctx_fence_time(ctx, centity, &ttotal, &tmax); + +		/* Harmonic mean approximation diverges for very small +		 * values. If ratio < 0.01% ignore +		 */ +		if (AMDGPU_CTX_FENCE_USAGE_MIN_RATIO(tmax, ttotal)) +			continue; + +		total = ktime_add(total, ttotal); +		max = ktime_after(tmax, max) ? tmax : max; +	} + +	mutex_unlock(&mgr->lock); +	if (elapsed) +		*elapsed = max; + +	return total; +} | 
