From: Maarten Lankhorst <dev@lankhorst.se>
To: intel-xe@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
Maarten Lankhorst <dev@lankhorst.se>,
Ingo Molnar <mingo@kernel.org>,
David Lechner <dlechner@baylibre.com>,
Peter Zijlstra <peterz@infradead.org>,
Will Deacon <will@kernel.org>, Waiman Long <longman@redhat.com>,
Boqun Feng <boqun.feng@gmail.com>
Subject: [PATCH-resent-to-correct-ml 4/8] drm/xe: Add xe_force_wake_get_all
Date: Tue, 4 Feb 2025 14:22:33 +0100 [thread overview]
Message-ID: <20250204132238.162608-5-dev@lankhorst.se> (raw)
In-Reply-To: <20250204132238.162608-1-dev@lankhorst.se>
For most usecases, we want to get all the forcewakes, and failing to
grab any is similar to failure to grab all.
This makes the next patch to add cond guards a lot easier.
Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
---
drivers/gpu/drm/xe/xe_force_wake.c | 110 ++++++++++++++++++++---------
drivers/gpu/drm/xe/xe_force_wake.h | 2 +
2 files changed, 77 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_force_wake.c b/drivers/gpu/drm/xe/xe_force_wake.c
index 805c19f6de9e7..cc00d5de8f0ae 100644
--- a/drivers/gpu/drm/xe/xe_force_wake.c
+++ b/drivers/gpu/drm/xe/xe_force_wake.c
@@ -211,27 +211,36 @@ static int domain_sleep_wait(struct xe_gt *gt,
(ffs(tmp__) - 1))) && \
domain__->reg_ctl.addr)
-/**
- * xe_force_wake_get() : Increase the domain refcount
- * @fw: struct xe_force_wake
- * @domains: forcewake domains to get refcount on
- *
- * This function wakes up @domains if they are asleep and takes references.
- * If requested domain is XE_FORCEWAKE_ALL then only applicable/initialized
- * domains will be considered for refcount and it is a caller responsibility
- * to check returned ref if it includes any specific domain by using
- * xe_force_wake_ref_has_domain() function. Caller must call
- * xe_force_wake_put() function to decrease incremented refcounts.
- *
- * Return: opaque reference to woken domains or zero if none of requested
- * domains were awake.
- */
-unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
- enum xe_force_wake_domains domains)
+static void __xe_force_wake_put_inner(struct xe_force_wake *fw,
+ unsigned int fw_ref, unsigned int *ack_fail)
+{
+ struct xe_gt *gt = fw->gt;
+ struct xe_force_wake_domain *domain;
+ unsigned int tmp, sleep = 0;
+
+ for_each_fw_domain_masked(domain, fw_ref, fw, tmp) {
+ xe_gt_assert(gt, domain->ref);
+
+ if (!--domain->ref) {
+ sleep |= BIT(domain->id);
+ domain_sleep(gt, domain);
+ }
+ }
+ for_each_fw_domain_masked(domain, sleep, fw, tmp) {
+ if (domain_sleep_wait(gt, domain) == 0)
+ fw->awake_domains &= ~BIT(domain->id);
+ else
+ *ack_fail |= BIT(domain->id);
+ }
+}
+
+static int __must_check __xe_force_wake_get(struct xe_force_wake *fw,
+ enum xe_force_wake_domains domains,
+ bool all_or_nothing)
{
struct xe_gt *gt = fw->gt;
struct xe_force_wake_domain *domain;
- unsigned int ref_incr = 0, awake_rqst = 0, awake_failed = 0;
+ unsigned int ref_incr = 0, awake_rqst = 0, awake_failed = 0, sleep_failed = 0;
unsigned int tmp, ref_rqst;
unsigned long flags;
@@ -257,6 +266,12 @@ unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
}
}
ref_incr &= ~awake_failed;
+
+ if (all_or_nothing && awake_failed && ref_incr) {
+ __xe_force_wake_put_inner(fw, ref_incr, &sleep_failed);
+ ref_incr = 0;
+ }
+
spin_unlock_irqrestore(&fw->lock, flags);
xe_gt_WARN(gt, awake_failed, "Forcewake domain%s %#x failed to acknowledge awake request\n",
@@ -268,6 +283,46 @@ unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
return ref_incr;
}
+/**
+ * xe_force_wake_get() : Increase the domain refcount
+ * @fw: struct xe_force_wake
+ * @domains: forcewake domains to get refcount on
+ *
+ * This function wakes up @domains if they are asleep and takes references.
+ * If requested domain is XE_FORCEWAKE_ALL then only applicable/initialized
+ * domains will be considered for refcount and it is a caller responsibility
+ * to check returned ref if it includes any specific domain by using
+ * xe_force_wake_ref_has_domain() function. Caller must call
+ * xe_force_wake_put() function to decrease incremented refcounts.
+ *
+ * Return: opaque reference to woken domains or zero if none of requested
+ * domains were awake.
+ */
+unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
+ enum xe_force_wake_domains domains)
+{
+ return __xe_force_wake_get(fw, domains, false);
+}
+
+/**
+ * xe_force_wake_get_all() : Increase the domain refcount
+ * @fw: struct xe_force_wake
+ * @domains: forcewake domains to get refcount on
+ *
+ * This function wakes up @domains if they are asleep and takes references.
+ * Unlike xe_force_wake_get(), this function fails if any of the domains
+ * could not be woken up. It's all or nothing. This makes it always safe
+ * to check for 0 only.
+ *
+ * Return: opaque reference to woken domains or zero if not all of the requested
+ * domains could be woken up.
+ */
+unsigned int __must_check xe_force_wake_get_all(struct xe_force_wake *fw,
+ enum xe_force_wake_domains domains)
+{
+ return __xe_force_wake_get(fw, domains, true);
+}
+
/**
* xe_force_wake_put - Decrement the refcount and put domain to sleep if refcount becomes 0
* @fw: Pointer to the force wake structure
@@ -281,10 +336,8 @@ unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
void xe_force_wake_put(struct xe_force_wake *fw, unsigned int fw_ref)
{
struct xe_gt *gt = fw->gt;
- struct xe_force_wake_domain *domain;
- unsigned int tmp, sleep = 0;
unsigned long flags;
- int ack_fail = 0;
+ unsigned int ack_fail = 0;
/*
* Avoid unnecessary lock and unlock when the function is called
@@ -297,20 +350,7 @@ void xe_force_wake_put(struct xe_force_wake *fw, unsigned int fw_ref)
fw_ref = fw->initialized_domains;
spin_lock_irqsave(&fw->lock, flags);
- for_each_fw_domain_masked(domain, fw_ref, fw, tmp) {
- xe_gt_assert(gt, domain->ref);
-
- if (!--domain->ref) {
- sleep |= BIT(domain->id);
- domain_sleep(gt, domain);
- }
- }
- for_each_fw_domain_masked(domain, sleep, fw, tmp) {
- if (domain_sleep_wait(gt, domain) == 0)
- fw->awake_domains &= ~BIT(domain->id);
- else
- ack_fail |= BIT(domain->id);
- }
+ __xe_force_wake_put_inner(fw, fw_ref, &ack_fail);
spin_unlock_irqrestore(&fw->lock, flags);
xe_gt_WARN(gt, ack_fail, "Forcewake domain%s %#x failed to acknowledge sleep request\n",
diff --git a/drivers/gpu/drm/xe/xe_force_wake.h b/drivers/gpu/drm/xe/xe_force_wake.h
index 0fb1baae0a3a3..7102547260f67 100644
--- a/drivers/gpu/drm/xe/xe_force_wake.h
+++ b/drivers/gpu/drm/xe/xe_force_wake.h
@@ -19,6 +19,8 @@ void xe_force_wake_init_engines(struct xe_gt *gt,
struct xe_force_wake *fw);
unsigned int __must_check xe_force_wake_get(struct xe_force_wake *fw,
enum xe_force_wake_domains domains);
+unsigned int __must_check xe_force_wake_get_all(struct xe_force_wake *fw,
+ enum xe_force_wake_domains domains);
void xe_force_wake_put(struct xe_force_wake *fw, unsigned int fw_ref);
static inline int
--
2.47.1
next prev parent reply other threads:[~2025-02-04 13:21 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-04 13:22 [PATCH-resent-to-correct-ml 0/8] drm/xe: Convert xe_force_wake calls to guard helpers Maarten Lankhorst
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 1/8] header/cleanup.h: Add _init_args to DEFINE_LOCK_GUARD_1(_COND) Maarten Lankhorst
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 2/8] drm/xe/gt: Unify xe_hw_fence_irq_finish() calls Maarten Lankhorst
2025-02-04 15:20 ` Lucas De Marchi
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 3/8] drm/xe: Add scoped guards for xe_force_wake Maarten Lankhorst
2025-02-04 15:28 ` Lucas De Marchi
2025-02-04 16:30 ` Michal Wajdeczko
2025-02-04 22:28 ` Maarten Lankhorst
2025-02-04 22:49 ` Rodrigo Vivi
2025-02-04 13:22 ` Maarten Lankhorst [this message]
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 5/8] drm/xe/coredump: Use guard helpers " Maarten Lankhorst
2025-02-04 15:40 ` Lucas De Marchi
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 6/8] drm/xe/gsc: Use guard helper for xe_gsc_print_info Maarten Lankhorst
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 7/8] drm/xe/vram: Use xe_force_wake guard helper Maarten Lankhorst
2025-02-04 13:22 ` [PATCH-resent-to-correct-ml 8/8] drm/xe/gt: Convert to xe_force_wake guard helpers Maarten Lankhorst
2025-02-04 15:21 ` ✓ CI.Patch_applied: success for drm/xe: Convert xe_force_wake calls to " Patchwork
2025-02-04 15:21 ` ✗ CI.checkpatch: warning " Patchwork
2025-02-04 15:22 ` ✓ CI.KUnit: success " Patchwork
2025-02-04 15:38 ` ✓ CI.Build: " Patchwork
2025-02-04 15:41 ` ✓ CI.Hooks: " Patchwork
2025-02-04 15:42 ` ✗ CI.checksparse: warning " Patchwork
2025-02-04 17:40 ` [PATCH-resent-to-correct-ml 0/8] " David Lechner
2025-02-05 20:11 ` Maarten Lankhorst
2025-02-05 6:12 ` ✓ Xe.CI.BAT: success for " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250204132238.162608-5-dev@lankhorst.se \
--to=dev@lankhorst.se \
--cc=boqun.feng@gmail.com \
--cc=dlechner@baylibre.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox