From 943c4d0637cff358f7be8e71694475538e7b1ce3 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Tue, 27 Jan 2026 20:37:23 +0100 Subject: [PATCH] drm/xe/guc: Limit sleep while waiting for H2G credits Instead of endlessly increasing the sleep timeout while waiting for the H2G credits, use exponential increase only up to the given limit, like it was initially done in the GuC submission code. While here, fix the actual timeout to the 1s as it was documented. Suggested-by: Matthew Brost Signed-off-by: Michal Wajdeczko Reviewed-by: Matthew Brost Link: https://patch.msgid.link/20260127193727.601-4-michal.wajdeczko@intel.com --- drivers/gpu/drm/xe/xe_guc_ct.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index dfbf76037b04..d4111124cd5f 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -32,6 +32,7 @@ #include "xe_guc_tlb_inval.h" #include "xe_map.h" #include "xe_pm.h" +#include "xe_sleep.h" #include "xe_sriov_vf.h" #include "xe_trace_guc.h" @@ -1101,7 +1102,8 @@ static int dequeue_one_g2h(struct xe_guc_ct *ct); */ static bool guc_ct_send_wait_for_retry(struct xe_guc_ct *ct, u32 len, u32 g2h_len, struct g2h_fence *g2h_fence, - unsigned int *sleep_period_ms) + unsigned int *sleep_period_ms, + unsigned int *sleep_total_ms) { struct xe_device *xe = ct_to_xe(ct); @@ -1115,15 +1117,14 @@ static bool guc_ct_send_wait_for_retry(struct xe_guc_ct *ct, u32 len, if (!h2g_has_room(ct, len + GUC_CTB_HDR_LEN)) { struct guc_ctb *h2g = &ct->ctbs.h2g; - if (*sleep_period_ms == 1024) + if (*sleep_total_ms > 1000) return false; trace_xe_guc_ct_h2g_flow_control(xe, h2g->info.head, h2g->info.tail, h2g->info.size, h2g->info.space, len + GUC_CTB_HDR_LEN); - msleep(*sleep_period_ms); - *sleep_period_ms <<= 1; + xe_sleep_exponential_ms(sleep_period_ms, 64); } else { struct xe_device *xe = ct_to_xe(ct); struct guc_ctb *g2h = &ct->ctbs.g2h; @@ -1161,6 +1162,7 @@ static int guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, u32 len, { struct xe_gt *gt = ct_to_gt(ct); unsigned int sleep_period_ms = 1; + unsigned int sleep_total_ms = 0; int ret; xe_gt_assert(gt, !g2h_len || !g2h_fence); @@ -1173,7 +1175,7 @@ static int guc_ct_send_locked(struct xe_guc_ct *ct, const u32 *action, u32 len, if (unlikely(ret == -EBUSY)) { if (!guc_ct_send_wait_for_retry(ct, len, g2h_len, g2h_fence, - &sleep_period_ms)) + &sleep_period_ms, &sleep_total_ms)) goto broken; goto try_again; }