From patchwork Mon Jul 1 17:14:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 13718476 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2371AC3065D for ; Mon, 1 Jul 2024 17:15:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 67ACF10E4BA; Mon, 1 Jul 2024 17:15:02 +0000 (UTC) Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) by gabe.freedesktop.org (Postfix) with ESMTPS id 563F410E4B9 for ; Mon, 1 Jul 2024 17:15:01 +0000 (UTC) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sOKc5-0002p8-2t; Mon, 01 Jul 2024 19:14:49 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1sOKc3-006Q8D-Uc; Mon, 01 Jul 2024 19:14:47 +0200 From: Lucas Stach To: =?utf-8?q?Christian_K=C3=B6nig?= , Alex Deucher , Luben Tuikov , Matthew Brost Cc: Pan Xinhui , Christian Gmeiner , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de Subject: [PATCH 1/4] drm/scheduler: implement hardware time accounting Date: Mon, 1 Jul 2024 19:14:44 +0200 Message-Id: <20240701171447.3823888-1-l.stach@pengutronix.de> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Christian König Multiple drivers came up with the requirement to measure how much runtime each entity accumulated on the HW. A previous attempt of accounting this had to be reverted because HW submissions can have a lifetime exceeding that of the entity originally issuing them. Amdgpu on the other hand solves this task by keeping track of all the submissions and calculating how much time they have used on demand. Move this approach over into the scheduler to provide an easy to use interface for all drivers. Signed-off-by: Christian König Signed-off-by: Lucas Stach --- v2: - rebase to v6.10-rc1 - fix for non-power-of-two number of HW submission - add comment explaining the logic behind the fence tracking array - rename some function and fix documentation --- drivers/gpu/drm/scheduler/sched_entity.c | 82 +++++++++++++++++++++++- drivers/gpu/drm/scheduler/sched_fence.c | 19 ++++++ include/drm/gpu_scheduler.h | 31 +++++++++ 3 files changed, 131 insertions(+), 1 deletion(-) base-commit: 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0 diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 58c8161289fe..d678d0b9b29e 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -62,7 +62,9 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, unsigned int num_sched_list, atomic_t *guilty) { - if (!(entity && sched_list && (num_sched_list == 0 || sched_list[0]))) + unsigned int i, num_submissions = 0; + + if (!entity || !sched_list) return -EINVAL; memset(entity, 0, sizeof(struct drm_sched_entity)); @@ -98,6 +100,11 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, (s32) DRM_SCHED_PRIORITY_KERNEL); } entity->rq = sched_list[0]->sched_rq[entity->priority]; + + for (i = 0; i < num_sched_list; ++i) { + num_submissions = max(num_submissions, + sched_list[i]->credit_limit); + } } init_completion(&entity->entity_idle); @@ -110,11 +117,52 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, atomic_set(&entity->fence_seq, 0); entity->fence_context = dma_fence_context_alloc(2); + spin_lock_init(&entity->accounting_lock); + + if (!num_submissions) + return 0; + + entity->max_hw_submissions = num_submissions; + entity->hw_submissions = kcalloc(num_submissions, sizeof(void *), + GFP_KERNEL); + if (!entity->hw_submissions) + return -ENOMEM; return 0; } EXPORT_SYMBOL(drm_sched_entity_init); +/** + * drm_sched_entity_time_spent - Accumulated HW runtime used by this entity + * @entity: scheduler entity to check + * + * Get the current accumulated HW runtime used by all submissions made through + * this entity. + */ +ktime_t drm_sched_entity_time_spent(struct drm_sched_entity *entity) +{ + ktime_t result; + unsigned int i; + + if (!entity->max_hw_submissions) + return ns_to_ktime(0); + + spin_lock(&entity->accounting_lock); + result = entity->hw_time_used; + for (i = 0; i < entity->max_hw_submissions; ++i) { + struct drm_sched_fence *fence = entity->hw_submissions[i]; + + if (!fence) + continue; + + result = ktime_add(result, drm_sched_fence_get_runtime(fence)); + } + spin_unlock(&entity->accounting_lock); + + return result; +} +EXPORT_SYMBOL(drm_sched_entity_time_spent); + /** * drm_sched_entity_modify_sched - Modify sched of an entity * @entity: scheduler entity to init @@ -326,6 +374,8 @@ EXPORT_SYMBOL(drm_sched_entity_flush); */ void drm_sched_entity_fini(struct drm_sched_entity *entity) { + unsigned int i; + /* * If consumption of existing IBs wasn't completed. Forcefully remove * them here. Also makes sure that the scheduler won't touch this entity @@ -341,6 +391,9 @@ void drm_sched_entity_fini(struct drm_sched_entity *entity) dma_fence_put(rcu_dereference_check(entity->last_scheduled, true)); RCU_INIT_POINTER(entity->last_scheduled, NULL); + for (i = 0; i < entity->max_hw_submissions; ++i) + dma_fence_put(&entity->hw_submissions[i]->scheduled); + kfree(entity->hw_submissions); } EXPORT_SYMBOL(drm_sched_entity_fini); @@ -522,6 +575,33 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) */ sched_job->entity = NULL; + if (entity->max_hw_submissions) { + struct drm_sched_fence *fence = sched_job->s_fence; + unsigned int idx = fence->scheduled.seqno; + + dma_fence_get(&fence->scheduled); + idx %= entity->max_hw_submissions; + + spin_lock(&entity->accounting_lock); + /* + * The fence seqno is dense and monotonically increasing. By + * cycling through a array sized to match the maximum number of + * submissions queued in the HW we can be sure that once we need + * to reuse a slot the fence stored in this slot refers to a + * retired submission and we can safely sum up the accumulated + * runtime and dispose the fence. + */ + swap(fence, entity->hw_submissions[idx]); + if (fence) { + ktime_t runtime = drm_sched_fence_get_runtime(fence); + + entity->hw_time_used = ktime_add(entity->hw_time_used, + runtime); + dma_fence_put(&fence->scheduled); + } + spin_unlock(&entity->accounting_lock); + } + return sched_job; } diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c index 0f35f009b9d3..55981ada1829 100644 --- a/drivers/gpu/drm/scheduler/sched_fence.c +++ b/drivers/gpu/drm/scheduler/sched_fence.c @@ -82,6 +82,25 @@ void drm_sched_fence_finished(struct drm_sched_fence *fence, int result) dma_fence_signal(&fence->finished); } +/** + * drm_sched_fence_get_runtime - accumulated runtime on HW + * @fence: fence + * + * Calculate how much runtime this fence has accumulated on the HW. + */ +ktime_t drm_sched_fence_get_runtime(struct drm_sched_fence *fence) +{ + /* When the fence is not scheduled, it can't have accumulated runtime */ + if (!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->scheduled.flags)) + return ns_to_ktime(0); + + /* When it is still running, calculate runtime until now */ + if (!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->finished.flags)) + return ktime_sub(ktime_get(), fence->scheduled.timestamp); + + return ktime_sub(fence->finished.timestamp, fence->scheduled.timestamp); +} + static const char *drm_sched_fence_get_driver_name(struct dma_fence *fence) { return "drm_sched"; diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 5acc64954a88..52bcff324a92 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -238,6 +238,35 @@ struct drm_sched_entity { */ struct rb_node rb_tree_node; + /** + * @accounting_lock: + * + * Protects the array of fences tracking the in-flight HW submissions + * and the accumulator counter. + */ + spinlock_t accounting_lock; + + /** + * @hw_time_used: + * + * How much HW runtime has been accumulated by retired submissions + * from this entity. + */ + ktime_t hw_time_used; + + /** + * @max_hw_submissions: + * + * Maximum number of submissions queued in the HW. + */ + unsigned int max_hw_submissions; + + /** + * @hw_submissions: + * + * Scheduler fences of the HW submissions in flight. + */ + struct drm_sched_fence **hw_submissions; }; /** @@ -600,6 +629,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, struct drm_gpu_scheduler **sched_list, unsigned int num_sched_list, atomic_t *guilty); +ktime_t drm_sched_entity_time_spent(struct drm_sched_entity *entity); long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout); void drm_sched_entity_fini(struct drm_sched_entity *entity); void drm_sched_entity_destroy(struct drm_sched_entity *entity); @@ -620,6 +650,7 @@ void drm_sched_fence_free(struct drm_sched_fence *fence); void drm_sched_fence_scheduled(struct drm_sched_fence *fence, struct dma_fence *parent); void drm_sched_fence_finished(struct drm_sched_fence *fence, int result); +ktime_t drm_sched_fence_get_runtime(struct drm_sched_fence *fence); unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched, From patchwork Mon Jul 1 17:14:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 13718473 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AA2E4C2BD09 for ; Mon, 1 Jul 2024 17:15:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F33CC10E4A8; Mon, 1 Jul 2024 17:14:59 +0000 (UTC) Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5E54910E4AE for ; Mon, 1 Jul 2024 17:14:58 +0000 (UTC) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sOKc5-0002p9-2z; Mon, 01 Jul 2024 19:14:49 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1sOKc4-006Q8D-0C; Mon, 01 Jul 2024 19:14:48 +0200 From: Lucas Stach To: =?utf-8?q?Christian_K=C3=B6nig?= , Alex Deucher , Luben Tuikov , Matthew Brost Cc: Pan Xinhui , Christian Gmeiner , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de Subject: [PATCH 2/4] drm/amdgpu: mostly revert "fix force APP kill hang(v4)" Date: Mon, 1 Jul 2024 19:14:45 +0200 Message-Id: <20240701171447.3823888-2-l.stach@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240701171447.3823888-1-l.stach@pengutronix.de> References: <20240701171447.3823888-1-l.stach@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Christian König This reverts commit 8ee3a52e3f35e064a3bf82f21dc74ddaf9843648. The new amdgpu_ctx_mgr_entity_fini() was never called, so it was pure coincident that this patch didn't cause a crash. Since the workaround shouldn't be needed any more just mostly revert the changes to amdgpu. Signed-off-by: Christian König Signed-off-by: Lucas Stach --- v2: - rebased to v6.10-rc1 --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 59 ++----------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- 3 files changed, 5 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 5cb33ac99f70..56f2428813e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -284,7 +284,7 @@ static ktime_t amdgpu_ctx_fini_entity(struct amdgpu_device *adev, } amdgpu_xcp_release_sched(adev, entity); - + drm_sched_entity_destroy(&entity->entity); kfree(entity); return res; } @@ -503,24 +503,6 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, return r; } -static void amdgpu_ctx_do_release(struct kref *ref) -{ - struct amdgpu_ctx *ctx; - u32 i, j; - - ctx = container_of(ref, struct amdgpu_ctx, refcount); - for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) { - for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) { - if (!ctx->entities[i][j]) - continue; - - drm_sched_entity_destroy(&ctx->entities[i][j]->entity); - } - } - - amdgpu_ctx_fini(ref); -} - static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) { struct amdgpu_ctx_mgr *mgr = &fpriv->ctx_mgr; @@ -529,7 +511,7 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) mutex_lock(&mgr->lock); ctx = idr_remove(&mgr->ctx_handles, id); if (ctx) - kref_put(&ctx->refcount, amdgpu_ctx_do_release); + kref_put(&ctx->refcount, amdgpu_ctx_fini); mutex_unlock(&mgr->lock); return ctx ? 0 : -EINVAL; } @@ -742,7 +724,7 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx) if (ctx == NULL) return -EINVAL; - kref_put(&ctx->refcount, amdgpu_ctx_do_release); + kref_put(&ctx->refcount, amdgpu_ctx_fini); return 0; } @@ -911,45 +893,12 @@ long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout) return timeout; } -void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr) -{ - struct amdgpu_ctx *ctx; - struct idr *idp; - uint32_t id, i, j; - - idp = &mgr->ctx_handles; - - idr_for_each_entry(idp, ctx, id) { - if (kref_read(&ctx->refcount) != 1) { - DRM_ERROR("ctx %p is still alive\n", ctx); - continue; - } - - for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) { - for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) { - struct drm_sched_entity *entity; - - if (!ctx->entities[i][j]) - continue; - - entity = &ctx->entities[i][j]->entity; - drm_sched_entity_fini(entity); - } - } - } -} - void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr) { struct amdgpu_ctx *ctx; - struct idr *idp; uint32_t id; - amdgpu_ctx_mgr_entity_fini(mgr); - - idp = &mgr->ctx_handles; - - idr_for_each_entry(idp, ctx, id) { + idr_for_each_entry(&mgr->ctx_handles, ctx, id) { if (kref_put(&ctx->refcount, amdgpu_ctx_fini) != 1) DRM_ERROR("ctx %p is still alive\n", ctx); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h index 85376baaa92f..090dfe86f75b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h @@ -92,7 +92,6 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx, void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr, struct amdgpu_device *adev); -void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr); long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout); void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr); void amdgpu_ctx_mgr_usage(struct amdgpu_ctx_mgr *mgr, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index a0ea6fe8d060..9513cf94defb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1401,6 +1401,7 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, return; pm_runtime_get_sync(dev->dev); + amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_UVD) != NULL) amdgpu_uvd_free_handles(adev, file_priv); @@ -1424,7 +1425,6 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, amdgpu_bo_unreserve(pd); } - amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); amdgpu_vm_fini(adev, &fpriv->vm); if (pasid) From patchwork Mon Jul 1 17:14:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 13718475 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BD6B7C3065A for ; Mon, 1 Jul 2024 17:15:05 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F163410E4B0; Mon, 1 Jul 2024 17:15:00 +0000 (UTC) Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) by gabe.freedesktop.org (Postfix) with ESMTPS id E233A10E4A0 for ; Mon, 1 Jul 2024 17:14:58 +0000 (UTC) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sOKc5-0002pA-2r; Mon, 01 Jul 2024 19:14:49 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1sOKc4-006Q8D-3N; Mon, 01 Jul 2024 19:14:48 +0200 From: Lucas Stach To: =?utf-8?q?Christian_K=C3=B6nig?= , Alex Deucher , Luben Tuikov , Matthew Brost Cc: Pan Xinhui , Christian Gmeiner , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de Subject: [PATCH 3/4] drm/amdgpu: use new scheduler accounting Date: Mon, 1 Jul 2024 19:14:46 +0200 Message-Id: <20240701171447.3823888-3-l.stach@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240701171447.3823888-1-l.stach@pengutronix.de> References: <20240701171447.3823888-1-l.stach@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Christian König Instead of implementing this ourself. Signed-off-by: Christian König Signed-off-by: Lucas Stach --- v2: - rebased to v6.10-rc1 - adapted to match new function names --- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 52 ++++--------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 56f2428813e8..392f51e0b2e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -166,41 +166,6 @@ static unsigned int amdgpu_ctx_get_hw_prio(struct amdgpu_ctx *ctx, u32 hw_ip) return hw_prio; } -/* Calculate the time spend on the hw */ -static ktime_t amdgpu_ctx_fence_time(struct dma_fence *fence) -{ - struct drm_sched_fence *s_fence; - - if (!fence) - return ns_to_ktime(0); - - /* When the fence is not even scheduled it can't have spend time */ - s_fence = to_drm_sched_fence(fence); - if (!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &s_fence->scheduled.flags)) - return ns_to_ktime(0); - - /* When it is still running account how much already spend */ - if (!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &s_fence->finished.flags)) - return ktime_sub(ktime_get(), s_fence->scheduled.timestamp); - - return ktime_sub(s_fence->finished.timestamp, - s_fence->scheduled.timestamp); -} - -static ktime_t amdgpu_ctx_entity_time(struct amdgpu_ctx *ctx, - struct amdgpu_ctx_entity *centity) -{ - ktime_t res = ns_to_ktime(0); - uint32_t i; - - spin_lock(&ctx->ring_lock); - for (i = 0; i < amdgpu_sched_jobs; i++) { - res = ktime_add(res, amdgpu_ctx_fence_time(centity->fences[i])); - } - spin_unlock(&ctx->ring_lock); - return res; -} - static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, const u32 ring) { @@ -272,18 +237,17 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, static ktime_t amdgpu_ctx_fini_entity(struct amdgpu_device *adev, struct amdgpu_ctx_entity *entity) { - ktime_t res = ns_to_ktime(0); + ktime_t res; int i; if (!entity) - return res; + return res = ns_to_ktime(0); - for (i = 0; i < amdgpu_sched_jobs; ++i) { - res = ktime_add(res, amdgpu_ctx_fence_time(entity->fences[i])); + for (i = 0; i < amdgpu_sched_jobs; ++i) dma_fence_put(entity->fences[i]); - } amdgpu_xcp_release_sched(adev, entity); + res = drm_sched_entity_time_spent(&entity->entity); drm_sched_entity_destroy(&entity->entity); kfree(entity); return res; @@ -748,9 +712,6 @@ uint64_t amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, centity->sequence++; spin_unlock(&ctx->ring_lock); - atomic64_add(ktime_to_ns(amdgpu_ctx_fence_time(other)), - &ctx->mgr->time_spend[centity->hw_ip]); - dma_fence_put(other); return seq; } @@ -930,12 +891,15 @@ void amdgpu_ctx_mgr_usage(struct amdgpu_ctx_mgr *mgr, for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) { for (i = 0; i < amdgpu_ctx_num_entities[hw_ip]; ++i) { struct amdgpu_ctx_entity *centity; + struct drm_sched_entity *entity; ktime_t spend; centity = ctx->entities[hw_ip][i]; if (!centity) continue; - spend = amdgpu_ctx_entity_time(ctx, centity); + + entity = ¢ity->entity; + spend = drm_sched_entity_time_spent(entity); usage[hw_ip] = ktime_add(usage[hw_ip], spend); } } From patchwork Mon Jul 1 17:14:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lucas Stach X-Patchwork-Id: 13718474 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4DF28C3065B for ; Mon, 1 Jul 2024 17:15:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0253C10E4AF; Mon, 1 Jul 2024 17:15:00 +0000 (UTC) Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3AE3810E4A8 for ; Mon, 1 Jul 2024 17:14:59 +0000 (UTC) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sOKc5-0002pB-2r; Mon, 01 Jul 2024 19:14:49 +0200 Received: from [2a0a:edc0:0:1101:1d::28] (helo=dude02.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1sOKc4-006Q8D-6O; Mon, 01 Jul 2024 19:14:48 +0200 From: Lucas Stach To: =?utf-8?q?Christian_K=C3=B6nig?= , Alex Deucher , Luben Tuikov , Matthew Brost Cc: Pan Xinhui , Christian Gmeiner , amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, etnaviv@lists.freedesktop.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de Subject: [PATCH 4/4] drm/etnaviv: export client GPU usage statistics via fdinfo Date: Mon, 1 Jul 2024 19:14:47 +0200 Message-Id: <20240701171447.3823888-4-l.stach@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240701171447.3823888-1-l.stach@pengutronix.de> References: <20240701171447.3823888-1-l.stach@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: l.stach@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" This exposes a accumulated GPU active time per client via the fdinfo infrastructure. Signed-off-by: Lucas Stach Acked-by: Christian König --- v2: - new patch --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 6500f3999c5f..f42b982f9a16 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -24,6 +24,7 @@ #include "etnaviv_gem.h" #include "etnaviv_mmu.h" #include "etnaviv_perfmon.h" +#include "common.xml.h" /* * DRM operations: @@ -488,7 +489,36 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = { ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW), }; -DEFINE_DRM_GEM_FOPS(fops); +static void etnaviv_fop_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct drm_file *file = f->private_data; + struct drm_device *dev = file->minor->dev; + struct etnaviv_drm_private *priv = dev->dev_private; + struct etnaviv_file_private *ctx = file->driver_priv; + + /* + * For a description of the text output format used here, see + * Documentation/gpu/drm-usage-stats.rst. + */ + seq_printf(m, "drm-driver:\t%s\n", dev->driver->name); + seq_printf(m, "drm-client-id:\t%u\n", ctx->id); + + for (int i = 0; i < ETNA_MAX_PIPES; i++) { + struct etnaviv_gpu *gpu = priv->gpu[i]; + + if (!gpu) + continue; + + seq_printf(m, "drm-engine-pipe%d:\t%llu ns\n", i, + drm_sched_entity_time_spent(&ctx->sched_entity[i])); + } +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + DRM_GEM_FOPS, + .show_fdinfo = etnaviv_fop_show_fdinfo, +}; static const struct drm_driver etnaviv_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_RENDER,