From mboxrd@z Thu Jan 1 00:00:00 1970 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 4FDF6C88E53 for ; Tue, 15 Sep 2026 08:59:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C50FE10E264; Tue, 15 Sep 2026 08:59:18 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="TWss5aLX"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2D11710E264 for ; Tue, 15 Sep 2026 08:59:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1789462757; x=1820998757; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=Izf9QNLjGOdk7WaIOLTAhdqZ4STHQIPm9A+Ur1s4mog=; b=TWss5aLXirpvkOC8m0dhIIcTUgK6vmTkPjHUK61wDg2wFtv06WzYoFs2 /dJr6yr1bTo0w5JzuA9u7lopq58b7qdBzCA4tHS4iHzOVnXiiLSHu0pHa MkPto1nQ3m4soogPYxSLVpHLR8WboGHYUgWGegZV/CIBuLijpDXYi3ngr 4cik+xWaWERn8k0ZID7tw0+662oY1NeT7o/FsADkVcjwVBSYjqRWZGUcd BWMBj3HoaR6dLUd+d29rXJ/WTCyeA6MMx1CSAnkWVfa6VfrZqBXAy2V8k UX/fco9p9389625vPKR0k5ny+v/sULu9+tYLhvp5dW6Qg11SywPh3ItTi g==; X-CSE-ConnectionGUID: OryRzGTVRGCpNtiIHdM8Ug== X-CSE-MsgGUID: eJLEhtbjQ8KCzjfIhxhKpg== X-IronPort-AV: E=McAfee;i="6800,10657,11905"; a="115355554" X-IronPort-AV: E=Sophos;i="6.27,103,1787036400"; d="scan'208";a="115355554" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Sep 2026 01:59:16 -0700 X-CSE-ConnectionGUID: YzH2k9MaSnqw5Ta7h0mFqg== X-CSE-MsgGUID: SUDcCIJWSvmrRdEgzBm0kw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.27,103,1787036400"; d="scan'208";a="311184913" Received: from black.igk.intel.com ([10.91.253.5]) by orviesa001.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Sep 2026 01:59:15 -0700 Date: Tue, 15 Sep 2026 10:59:12 +0200 From: Raag Jadav To: Vinay Belgaumkar Cc: intel-xe@lists.freedesktop.org, Badal Nilawar , Rodrigo Vivi Subject: Re: [PATCH v4] drm/xe: Poll GT for C6 before D3 Message-ID: References: <20260915071145.2866414-1-vinay.belgaumkar@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260915071145.2866414-1-vinay.belgaumkar@intel.com> X-BeenThere: intel-xe@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel Xe graphics driver List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-xe-bounces@lists.freedesktop.org Sender: "Intel-xe" On Tue, Sep 15, 2026 at 12:11:45AM -0700, Vinay Belgaumkar wrote: > Ensure GT C6 state before D3 transition in runtime suspend flow. > This avoids the scenario where GT is being accessed after D3 state > is programmed. If the check for C6 fails, resume the device so it is > not stuck in an intermediate state. > > v2: Force resume when we cancel suspend due to C6 check (Sashiko) > v3: Abort the suspend properly when idle check fails (Sashiko) > v4: Only check for C6 during suspend (Rodrigo). Have check in > xe_pci_runtime_suspend() instead of xe_pci_suspend(). > > Cc: Badal Nilawar > Cc: Rodrigo Vivi > Signed-off-by: Vinay Belgaumkar > --- > drivers/gpu/drm/xe/xe_gt_idle.c | 36 +++++++++++++++++++++++++++++++++ > drivers/gpu/drm/xe/xe_gt_idle.h | 1 + > drivers/gpu/drm/xe/xe_pci.c | 13 +++++++++++- > drivers/gpu/drm/xe/xe_pm.c | 21 +++++++++++++++++++ > drivers/gpu/drm/xe/xe_pm.h | 1 + > 5 files changed, 71 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c > index c208d7563e36..8242feede1dd 100644 > --- a/drivers/gpu/drm/xe/xe_gt_idle.c > +++ b/drivers/gpu/drm/xe/xe_gt_idle.c > @@ -8,10 +8,12 @@ > #include > > #include > +#include > #include "xe_force_wake.h" > #include "xe_device.h" > #include "xe_gt.h" > #include "xe_gt_idle.h" > +#include "xe_gt_printk.h" > #include "xe_gt_sysfs.h" > #include "xe_guc_pc.h" > #include "regs/xe_gt_regs.h" > @@ -451,3 +453,37 @@ int xe_gt_idle_disable_c6(struct xe_gt *gt) > > return 0; > } > + > +static int wait_for_gt_c6_state(struct xe_gt *gt, u32 timeout_ms) > +{ > + struct xe_guc_pc *pc = >->uc.guc.pc; > + enum xe_gt_idle_state state; > + > + return poll_timeout_us(state = gt->gtidle.idle_status(pc), > + state == GT_IDLE_C6, > + 20, > + timeout_ms * USEC_PER_MSEC, > + false); > +} > + > +/** > + * xe_gt_idle_wait_for_c6 - Poll for GT C6 > + * @gt: GT object > + * @timeout_ms: wait time in ms > + * > + * This function waits for GT to enter C6. > + * > + * Return: 0 on success, -EAGAIN otherwise > + */ > +int xe_gt_idle_wait_for_c6(struct xe_gt *gt, u32 timeout_ms) > +{ > + if (IS_SRIOV_VF(gt_to_xe(gt))) > + return 0; > + > + if (wait_for_gt_c6_state(gt, timeout_ms)) { > + xe_gt_dbg(gt, "GT is not in C6\n"); > + return -EAGAIN; > + } > + > + return 0; > +} > diff --git a/drivers/gpu/drm/xe/xe_gt_idle.h b/drivers/gpu/drm/xe/xe_gt_idle.h > index 9c34a155e102..2c8e9adf4a68 100644 > --- a/drivers/gpu/drm/xe/xe_gt_idle.h > +++ b/drivers/gpu/drm/xe/xe_gt_idle.h > @@ -18,5 +18,6 @@ void xe_gt_idle_enable_pg(struct xe_gt *gt); > void xe_gt_idle_disable_pg(struct xe_gt *gt); > int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p); > u64 xe_gt_idle_residency_msec(struct xe_gt_idle *gtidle); > +int xe_gt_idle_wait_for_c6(struct xe_gt *gt, u32 timeout_ms); > > #endif /* _XE_GT_IDLE_H_ */ > diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c > index ab4da1d9a9f1..379795ac5e7b 100644 > --- a/drivers/gpu/drm/xe/xe_pci.c > +++ b/drivers/gpu/drm/xe/xe_pci.c > @@ -1381,7 +1381,7 @@ static int xe_pci_runtime_suspend(struct device *dev) > { > struct pci_dev *pdev = to_pci_dev(dev); > struct xe_device *xe = pdev_to_xe_device(pdev); > - int err; > + int err, ret; > > /* > * We hold an additional reference to the runtime PM to keep PF in D0 > @@ -1396,6 +1396,17 @@ static int xe_pci_runtime_suspend(struct device *dev) > if (err) > return err; > > + err = xe_pm_check_device_idle(xe); Considering driver has no control over C state here, is there a guarantee that GT will remain in C6 after this point? Raag > + if (err) { > + drm_dbg(&xe->drm, "Resuming - Device idle check failed!"); > + ret = xe_pm_runtime_resume(xe); > + if (ret) { > + drm_err(&xe->drm, "Resume failed after suspend was canceled"); > + return ret; > + } > + return err; > + } > + > pci_save_state(pdev); > > if (xe->d3cold.allowed) { > diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c > index f517bf453b54..678afd7a1d08 100644 > --- a/drivers/gpu/drm/xe/xe_pm.c > +++ b/drivers/gpu/drm/xe/xe_pm.c > @@ -1030,6 +1030,27 @@ void xe_pm_d3cold_allowed_toggle(struct xe_device *xe) > mutex_unlock(&xe->d3cold.lock); > } > > +/** > + * xe_pm_check_device_idle() - Check if all GTs are idle. > + * @xe: xe device instance > + * > + * One of the ways to do this is to check for GT C6 state. This check > + * will fail if some component is holding a forcewake, for example. > + * > + * Return: 0 on success, -EAGAIN on failure > + */ > +int xe_pm_check_device_idle(struct xe_device *xe) > +{ > + struct xe_gt *gt; > + u8 id; > + > + for_each_gt(gt, xe, id) > + if (xe_gt_idle_wait_for_c6(gt, 200)) > + return -EAGAIN; > + > + return 0; > +} > + > /** > * xe_pm_module_init() - Perform xe_pm specific module initialization. > * > diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h > index 6d5ab09cb769..a4fdc9c5cb10 100644 > --- a/drivers/gpu/drm/xe/xe_pm.h > +++ b/drivers/gpu/drm/xe/xe_pm.h > @@ -36,6 +36,7 @@ void xe_pm_d3cold_allowed_toggle(struct xe_device *xe); > bool xe_rpm_reclaim_safe(const struct xe_device *xe); > struct task_struct *xe_pm_read_callback_task(struct xe_device *xe); > int xe_pm_block_on_suspend(struct xe_device *xe); > +int xe_pm_check_device_idle(struct xe_device *xe); > void xe_pm_might_block_on_suspend(void); > int xe_pm_module_init(void); > > -- > 2.38.1 >