From patchwork Wed Aug 2 23:34:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Teres Alexis, Alan Previn" X-Patchwork-Id: 13338940 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 AC0C7C04A6A for ; Wed, 2 Aug 2023 23:35:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5541C10E58A; Wed, 2 Aug 2023 23:35:08 +0000 (UTC) Received: from mgamail.intel.com (unknown [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3B3FE10E586; Wed, 2 Aug 2023 23:35:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1691019304; x=1722555304; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xYyG6KUJst2lvyCaZcp1CQFnBeOQgqR/NNb3dixdZpc=; b=aSrPB+SaQhunFo3gYRxjhdSM2acSYXuTP3iauXey3F6ZhSd74p9fiW22 1bs8QmzuKywA8S00WB6bJ4Xezqu/lmylP41HE54p2SWQoC6rO4mXgrJzA eWBO/kBX7fwpTBkXbAubNvNHxLsaCqzte00gLhlgJbGqBUPMBcgecGSjN CF5l4uIKa4BX8b8YzeV33c+958ziCPdoNm36K2wZzqyM26Wfb/G/NL8EZ GXOPyidNEYSZVC50bkIBMVC/MPpWDFu/XpdwGjwBNDh9lXuBufe0t90xX o1+nd/mCx/fC5p4s0izyjHemw19y6TaABLql6mih4mDRrQc1PGFVV3b6k Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="367185055" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="367185055" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2023 16:35:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="853030283" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="853030283" Received: from aalteres-desk.fm.intel.com ([10.80.57.53]) by orsmga004.jf.intel.com with ESMTP; 02 Aug 2023 16:35:03 -0700 From: Alan Previn To: intel-gfx@lists.freedesktop.org Date: Wed, 2 Aug 2023 16:34:59 -0700 Message-Id: <20230802233501.17074-2-alan.previn.teres.alexis@intel.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> References: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v1 1/3] drm/i915/guc: Flush context destruction worker at suspend X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dri-devel@lists.freedesktop.org, Alan Previn Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Suspend is not like reset, it can unroll, so we have to properly flush pending context-guc-id deregistrations to complete before we return from suspend calls. Signed-off-by: Alan Previn --- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 6 +++++- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 5 +++++ drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h | 2 ++ drivers/gpu/drm/i915/gt/uc/intel_uc.c | 7 +++++++ drivers/gpu/drm/i915/gt/uc/intel_uc.h | 1 + 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index 5a942af0a14e..3162d859ed68 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -289,8 +289,10 @@ int intel_gt_resume(struct intel_gt *gt) static void wait_for_suspend(struct intel_gt *gt) { - if (!intel_gt_pm_is_awake(gt)) + if (!intel_gt_pm_is_awake(gt)) { + intel_uc_suspend_prepare(>->uc); return; + } if (intel_gt_wait_for_idle(gt, I915_GT_SUSPEND_IDLE_TIMEOUT) == -ETIME) { /* @@ -299,6 +301,8 @@ static void wait_for_suspend(struct intel_gt *gt) */ intel_gt_set_wedged(gt); intel_gt_retire_requests(gt); + } else { + intel_uc_suspend_prepare(>->uc); } intel_gt_pm_wait_for_idle(gt); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index a0e3ef1c65d2..dc7735a19a5a 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1578,6 +1578,11 @@ static void guc_flush_submissions(struct intel_guc *guc) spin_unlock_irqrestore(&sched_engine->lock, flags); } +void intel_guc_submission_suspend_prepare(struct intel_guc *guc) +{ + flush_work(&guc->submission_state.destroyed_worker); +} + static void guc_flush_destroyed_contexts(struct intel_guc *guc); void intel_guc_submission_reset_prepare(struct intel_guc *guc) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h index c57b29cdb1a6..7f0705ece74b 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h @@ -38,6 +38,8 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc, bool interruptible, long timeout); +void intel_guc_submission_suspend_prepare(struct intel_guc *guc); + static inline bool intel_guc_submission_is_supported(struct intel_guc *guc) { return guc->submission_supported; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c index 18250fb64bd8..468d7b397927 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c @@ -679,6 +679,13 @@ void intel_uc_runtime_suspend(struct intel_uc *uc) guc_disable_communication(guc); } +void intel_uc_suspend_prepare(struct intel_uc *uc) +{ + struct intel_guc *guc = &uc->guc; + + intel_guc_submission_suspend_prepare(guc); +} + void intel_uc_suspend(struct intel_uc *uc) { struct intel_guc *guc = &uc->guc; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h index 014bb7d83689..036877a07261 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h @@ -49,6 +49,7 @@ void intel_uc_reset_prepare(struct intel_uc *uc); void intel_uc_reset(struct intel_uc *uc, intel_engine_mask_t stalled); void intel_uc_reset_finish(struct intel_uc *uc); void intel_uc_cancel_requests(struct intel_uc *uc); +void intel_uc_suspend_prepare(struct intel_uc *uc); void intel_uc_suspend(struct intel_uc *uc); void intel_uc_runtime_suspend(struct intel_uc *uc); int intel_uc_resume(struct intel_uc *uc); From patchwork Wed Aug 2 23:35:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Teres Alexis, Alan Previn" X-Patchwork-Id: 13338939 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 19C4DC04A6A for ; Wed, 2 Aug 2023 23:35:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9392710E58B; Wed, 2 Aug 2023 23:35:08 +0000 (UTC) Received: from mgamail.intel.com (unknown [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id ED01010E155; Wed, 2 Aug 2023 23:35:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1691019305; x=1722555305; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JQTC6RMOI5lhoMEhjHBSLbyPw3WZkzNwZXH2zYXyAj4=; b=GPoaxrheJ0dankt1KgfSBKMtRxg85tEWntoa5aMECnZKE2FGkmAMNhkM pffQqyeFVTazT8rd9BzXceO+pfcmE0A53G+P6iAO+Lvr+Wbe8TnSWhdBQ dLRO61Bg16Q9DeuigmS48FEjEPtADCy5XM6AO9DjjceRdBp7L+nYO1+i5 6vIbsj0EBLsb1sGhHpuRm4CHpgcLRaVXWoo6sDg71VwfgjAkK0+qEzzWO ywTqRnfVJac0OkZv7jqqj8iQbPhajX+EsQ5QZekwVTXzXOL6jhhZAQE/M xiulbEBkWl7I8rCZBvB39hRpRSKZ/pRgqL42+k/qqyqxLgo06WtgKDtc4 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="367185058" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="367185058" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2023 16:35:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="853030290" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="853030290" Received: from aalteres-desk.fm.intel.com ([10.80.57.53]) by orsmga004.jf.intel.com with ESMTP; 02 Aug 2023 16:35:04 -0700 From: Alan Previn To: intel-gfx@lists.freedesktop.org Date: Wed, 2 Aug 2023 16:35:00 -0700 Message-Id: <20230802233501.17074-3-alan.previn.teres.alexis@intel.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> References: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v1 2/3] drm/i915/guc: Close deregister-context race against CT-loss X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dri-devel@lists.freedesktop.org, Alan Previn Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" If we are at the end of suspend or very early in resume its possible an async fence signal could lead us to the execution of the context destruction worker (after the prior worker flush). Even if checking that the CT is enabled before calling destroyed_worker_func, guc_lrc_desc_unpin may still fail because in corner cases, as we traverse the GuC's context-destroy list, the CT could get disabled in the mid of it right before calling the GuC's CT send function. We've witnessed this race condition once every ~6000-8000 suspend-resume cycles while ensuring workloads that render something onscreen is continuously started just before we suspend (and the workload is small enough to complete either very late in suspend or very early in resume). In such a case, we need to unroll the unpin process because guc-lrc-unpin takes a gt wakeref which only gets released in the G2H IRQ reply that never comes through in this corner case. That will cascade into a kernel hang later at the tail end of suspend in this function: intel_wakeref_wait_for_idle(>->wakeref) (called by) - intel_gt_pm_wait_for_idle (called by) - wait_for_suspend Doing this unroll and keeping the context in the GuC's destroy-list will allow the context to get picked up on the next destroy worker invocation or purged as part of a major GuC sanitization or reset flow. While we fix this race condition, let's also ensure we never allow the kernel to hang in intel_gt_pm_wait_for_idle with a huge timeout and drm_warn. Signed-off-by: Alan Previn --- .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index dc7735a19a5a..a7530ad7008d 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -235,6 +235,13 @@ set_context_destroyed(struct intel_context *ce) ce->guc_state.sched_state |= SCHED_STATE_DESTROYED; } +static inline void +clr_context_destroyed(struct intel_context *ce) +{ + lockdep_assert_held(&ce->guc_state.lock); + ce->guc_state.sched_state &= ~SCHED_STATE_DESTROYED; +} + static inline bool context_pending_disable(struct intel_context *ce) { return ce->guc_state.sched_state & SCHED_STATE_PENDING_DISABLE; @@ -3175,7 +3182,7 @@ static void guc_context_close(struct intel_context *ce) spin_unlock_irqrestore(&ce->guc_state.lock, flags); } -static inline void guc_lrc_desc_unpin(struct intel_context *ce) +static inline int guc_lrc_desc_unpin(struct intel_context *ce) { struct intel_guc *guc = ce_to_guc(ce); struct intel_gt *gt = guc_to_gt(guc); @@ -3199,10 +3206,20 @@ static inline void guc_lrc_desc_unpin(struct intel_context *ce) if (unlikely(disabled)) { release_guc_id(guc, ce); __guc_context_destroy(ce); - return; + return 0; } - deregister_context(ce, ce->guc_id.id); + if (deregister_context(ce, ce->guc_id.id)) { + /* Seal race with concurrent suspend by unrolling */ + spin_lock_irqsave(&ce->guc_state.lock, flags); + set_context_registered(ce); + clr_context_destroyed(ce); + intel_gt_pm_put(gt); + spin_unlock_irqrestore(&ce->guc_state.lock, flags); + return -ENODEV; + } + + return 0; } static void __guc_context_destroy(struct intel_context *ce) @@ -3270,7 +3287,20 @@ static void deregister_destroyed_contexts(struct intel_guc *guc) if (!ce) break; - guc_lrc_desc_unpin(ce); + if (guc_lrc_desc_unpin(ce)) { + /* + * This means GuC's CT link severed mid-way which only happens + * in suspend-resume corner cases. In this case, put the + * context back into the destroyed_contexts list which will + * get picked up on the next context deregistration event or + * purged in a GuC sanitization event (reset/unload/wedged/...). + */ + spin_lock_irqsave(&guc->submission_state.lock, flags); + list_add_tail(&ce->destroyed_link, + &guc->submission_state.destroyed_contexts); + spin_unlock_irqrestore(&guc->submission_state.lock, flags); + } + } } From patchwork Wed Aug 2 23:35:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Teres Alexis, Alan Previn" X-Patchwork-Id: 13338938 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 ECBE2C001DE for ; Wed, 2 Aug 2023 23:35:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C76E710E58C; Wed, 2 Aug 2023 23:35:08 +0000 (UTC) Received: from mgamail.intel.com (unknown [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9EE2C10E155; Wed, 2 Aug 2023 23:35:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1691019305; x=1722555305; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KPpkYgYyFBImxWbV1UvSDvRiC0M4HN3HrHFvTk9Wr3Q=; b=a+QT1G2PXX53tPglfI7gtJdGCbiApL8zeRNEjOsG9zK5ptkNj2fM5X6N x7XE4I3T/6D47MOCSxpyqe5EZMbQ0iwEd3PzMBBIk5gbZbZMuK/s0qAJi odSpegpO3kbfOZY0OH/uwOqteZCQBS8fmnb3Sza6nVS/ELUIk3NJVKJDL 2IrcyKC1kp4Jt0qyo7dN5bkJPu3fQAVV5mnjmrtsw8YG4d19VCEhdGVHn rrOa2YqUhrxX/wJuiZOxgUIKL4dN3C4fEanT0+sUG4BCiHVpNqvPi8MHd b/jCodeVPMoOOqUVKM5U2rioorIc6d+0i3Vzitu2kxtkvw5itrEpY86BO w==; X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="367185061" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="367185061" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2023 16:35:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10790"; a="853030293" X-IronPort-AV: E=Sophos;i="6.01,250,1684825200"; d="scan'208";a="853030293" Received: from aalteres-desk.fm.intel.com ([10.80.57.53]) by orsmga004.jf.intel.com with ESMTP; 02 Aug 2023 16:35:05 -0700 From: Alan Previn To: intel-gfx@lists.freedesktop.org Date: Wed, 2 Aug 2023 16:35:01 -0700 Message-Id: <20230802233501.17074-4-alan.previn.teres.alexis@intel.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> References: <20230802233501.17074-1-alan.previn.teres.alexis@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v1 3/3] drm/i915/gt: Timeout when waiting for idle in suspending X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dri-devel@lists.freedesktop.org, Alan Previn Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" When suspending, add a timeout when calling intel_gt_pm_wait_for_idle else if we have a lost G2H event that holds a wakeref (which would be indicating of a bug elsewhere in the driver), we get to complete the suspend-resume cycle, albeit without all the lower power hw counters hitting its targets, instead of hanging in the kernel. Signed-off-by: Alan Previn --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 7 ++++++- drivers/gpu/drm/i915/gt/intel_gt_pm.h | 7 ++++++- drivers/gpu/drm/i915/intel_wakeref.c | 14 ++++++++++---- drivers/gpu/drm/i915/intel_wakeref.h | 5 +++-- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index ee15486fed0d..090438eb8682 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -688,7 +688,7 @@ void intel_engines_release(struct intel_gt *gt) if (!engine->release) continue; - intel_wakeref_wait_for_idle(&engine->wakeref); + intel_wakeref_wait_for_idle(&engine->wakeref, 0); GEM_BUG_ON(intel_engine_pm_is_awake(engine)); engine->release(engine); diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index 3162d859ed68..dfe77eb3efd1 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -289,6 +289,8 @@ int intel_gt_resume(struct intel_gt *gt) static void wait_for_suspend(struct intel_gt *gt) { + int timeout_ms = CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT ? : 10000; + if (!intel_gt_pm_is_awake(gt)) { intel_uc_suspend_prepare(>->uc); return; @@ -305,7 +307,10 @@ static void wait_for_suspend(struct intel_gt *gt) intel_uc_suspend_prepare(>->uc); } - intel_gt_pm_wait_for_idle(gt); + /* we are suspending, so we shouldn't be waiting forever */ + if (intel_gt_pm_wait_timeout_for_idle(gt, timeout_ms) == -ETIME) + drm_warn(>->i915->drm, "Bailing from %s after %d milisec timeout\n", + __func__, timeout_ms); } void intel_gt_suspend_prepare(struct intel_gt *gt) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.h b/drivers/gpu/drm/i915/gt/intel_gt_pm.h index 6c9a46452364..5358acc2b5b1 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.h @@ -68,7 +68,12 @@ static inline void intel_gt_pm_might_put(struct intel_gt *gt) static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt) { - return intel_wakeref_wait_for_idle(>->wakeref); + return intel_wakeref_wait_for_idle(>->wakeref, 0); +} + +static inline int intel_gt_pm_wait_timeout_for_idle(struct intel_gt *gt, int timeout_ms) +{ + return intel_wakeref_wait_for_idle(>->wakeref, timeout_ms); } void intel_gt_pm_init_early(struct intel_gt *gt); diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c index 718f2f1b6174..7e01d4cc300c 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.c +++ b/drivers/gpu/drm/i915/intel_wakeref.c @@ -111,14 +111,20 @@ void __intel_wakeref_init(struct intel_wakeref *wf, "wakeref.work", &key->work, 0); } -int intel_wakeref_wait_for_idle(struct intel_wakeref *wf) +int intel_wakeref_wait_for_idle(struct intel_wakeref *wf, int timeout_ms) { - int err; + int err = 0; might_sleep(); - err = wait_var_event_killable(&wf->wakeref, - !intel_wakeref_is_active(wf)); + if (!timeout_ms) + err = wait_var_event_killable(&wf->wakeref, + !intel_wakeref_is_active(wf)); + else if (wait_var_event_timeout(&wf->wakeref, + !intel_wakeref_is_active(wf), + msecs_to_jiffies(timeout_ms)) < 1) + err = -ETIME; + if (err) return err; diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index ec881b097368..6fbb7a2fb6ea 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -251,15 +251,16 @@ __intel_wakeref_defer_park(struct intel_wakeref *wf) /** * intel_wakeref_wait_for_idle: Wait until the wakeref is idle * @wf: the wakeref + * @timeout_ms: timeout to wait in milisecs, zero means forever * * Wait for the earlier asynchronous release of the wakeref. Note * this will wait for any third party as well, so make sure you only wait * when you have control over the wakeref and trust no one else is acquiring * it. * - * Return: 0 on success, error code if killed. + * Return: 0 on success, error code if killed, -ETIME if timed-out. */ -int intel_wakeref_wait_for_idle(struct intel_wakeref *wf); +int intel_wakeref_wait_for_idle(struct intel_wakeref *wf, int timeout_ms); struct intel_wakeref_auto { struct drm_i915_private *i915;