From: Matt Roper <matthew.d.roper@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: matthew.d.roper@intel.com
Subject: [PATCH 20/33] drm/xe: Create scoped cleanup class for force_wake_get_any_engine()
Date: Fri, 7 Nov 2025 10:13:36 -0800 [thread overview]
Message-ID: <20251107181315.631642-55-matthew.d.roper@intel.com> (raw)
In-Reply-To: <20251107181315.631642-35-matthew.d.roper@intel.com>
force_wake_get_any_engine() is a single-use function to pick any engine
present on the platform and grab its forcewake. The signature
(returning a boolean success and both the engine pointer and a forcewake
ref by reference) is a bit awkward. Rewrite it such that the
forcewake ref is the function's return value and the caller can
determine success/failure by checking the engine pointer against NULL.
With this new signature, the function can serve as a scoped cleanup
class constructor, so define the corresponding class. Note that if we
fail to obtain forcewake (or if the platform somehow has no engines),
the constructor can fail, returning an invalid fw_ref. In such cases,
fw_ref.fw will be NULL, making it clear that the reference is invalid;
this fact can be used to create a thin wrapper around xe_force_wake_put
that can be used as a destructor for this class.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
drivers/gpu/drm/xe/xe_drm_client.c | 45 ++++++++++++++++++++----------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c
index 182526864286..6e0a05eeb587 100644
--- a/drivers/gpu/drm/xe/xe_drm_client.c
+++ b/drivers/gpu/drm/xe/xe_drm_client.c
@@ -6,6 +6,7 @@
#include <drm/drm_print.h>
#include <uapi/drm/xe_drm.h>
+#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
@@ -285,34 +286,49 @@ static struct xe_hw_engine *any_engine(struct xe_device *xe)
return NULL;
}
-static bool force_wake_get_any_engine(struct xe_device *xe,
- struct xe_hw_engine **phwe,
- struct xe_force_wake_ref *pfw_ref)
+/*
+ * Pick any engine and grab its forcewake. On error phwe will be NULL and
+ * the returned forcewake reference will be invalid. Callers should check
+ * phwe against NULL.
+ */
+static struct xe_force_wake_ref force_wake_get_any_engine(struct xe_device *xe,
+ struct xe_hw_engine **phwe)
{
enum xe_force_wake_domains domain;
- struct xe_force_wake_ref fw_ref;
+ struct xe_force_wake_ref fw_ref = {};
struct xe_hw_engine *hwe;
struct xe_force_wake *fw;
+ *phwe = NULL;
+
hwe = any_engine(xe);
if (!hwe)
- return false;
+ return fw_ref; /* will be invalid */
domain = xe_hw_engine_to_fw_domain(hwe);
fw = gt_to_fw(hwe->gt);
fw_ref = xe_force_wake_get(fw, domain);
- if (!xe_force_wake_ref_has_domain(fw_ref, domain)) {
+ if (xe_force_wake_ref_has_domain(fw_ref, domain))
+ *phwe = hwe; /* valid forcewake */
+
+ return fw_ref;
+}
+
+static void drop_fw_if_valid(struct xe_force_wake_ref fw_ref)
+{
+ /*
+ * If force_wake_get_any_engine() fails, there's no real forcewake
+ * reference to drop, and fw_ref.fw will be NULL.
+ */
+ if (fw_ref.fw)
xe_force_wake_put(fw_ref);
- return false;
- }
-
- *phwe = hwe;
- *pfw_ref = fw_ref;
-
- return true;
}
+DEFINE_CLASS(xe_force_wake_any_engine, struct xe_force_wake_ref,
+ drop_fw_if_valid(_T), force_wake_get_any_engine(xe, phwe),
+ struct xe_device *xe, struct xe_hw_engine **phwe);
+
static void show_run_ticks(struct drm_printer *p, struct drm_file *file)
{
unsigned long class, i, gt_id, capacity[XE_ENGINE_CLASS_MAX] = { };
@@ -340,7 +356,8 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file)
!atomic_read(&xef->exec_queue.pending_removal));
xe_pm_runtime_get(xe);
- if (!force_wake_get_any_engine(xe, &hwe, &fw_ref)) {
+ fw_ref = force_wake_get_any_engine(xe, &hwe);
+ if (!hwe) {
xe_pm_runtime_put(xe);
return;
}
--
2.51.1
next prev parent reply other threads:[~2025-11-07 18:13 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 18:13 [PATCH 00/33] Scope-based forcewake and runtime PM Matt Roper
2025-11-07 18:13 ` [PATCH 01/33] drm/xe/forcewake: Improve kerneldoc Matt Roper
2025-11-10 23:33 ` Summers, Stuart
2025-11-07 18:13 ` [PATCH 02/33] drm/xe/eustall: Store forcewake reference in stream structure Matt Roper
2025-11-07 19:52 ` Harish Chegondi
2025-11-07 18:13 ` [PATCH 03/33] drm/xe/oa: " Matt Roper
2025-11-07 18:13 ` [PATCH 04/33] drm/xe/forcewake: Create dedicated type for forcewake references Matt Roper
2025-11-07 19:27 ` Michal Wajdeczko
2025-11-07 21:17 ` Matt Roper
2025-11-07 18:13 ` [PATCH 05/33] squash! " Matt Roper
2025-11-07 18:13 ` [PATCH 06/33] squash! " Matt Roper
2025-11-07 18:13 ` [PATCH 07/33] drm/xe/forcewake: Add scope-based cleanup for forcewake Matt Roper
2025-11-07 18:13 ` [PATCH 08/33] drm/xe/pm: Add scope-based cleanup helper for runtime PM Matt Roper
2025-11-10 21:59 ` Matt Roper
2025-11-07 18:13 ` [PATCH 09/33] drm/xe/gt: Use scope-based cleanup Matt Roper
2025-11-07 18:13 ` [PATCH 10/33] drm/xe/gt_idle: " Matt Roper
2025-11-07 18:13 ` [PATCH 11/33] drm/xe/guc: " Matt Roper
2025-11-07 18:13 ` [PATCH 12/33] drm/xe/guc_pc: " Matt Roper
2025-11-07 18:13 ` [PATCH 13/33] drm/xe/mocs: " Matt Roper
2025-11-07 18:13 ` [PATCH 14/33] drm/xe/pat: Use scope-based forcewake Matt Roper
2025-11-07 18:13 ` [PATCH 15/33] drm/xe/pxp: Use scope-based cleanup Matt Roper
2025-11-07 18:13 ` [PATCH 16/33] drm/xe/gsc: " Matt Roper
2025-11-07 18:13 ` [PATCH 17/33] drm/xe/device: " Matt Roper
2025-11-07 18:13 ` [PATCH 18/33] drm/xe/devcoredump: " Matt Roper
2025-11-07 18:13 ` [PATCH 19/33] drm/xe/display: Use scoped-cleanup Matt Roper
2025-11-07 18:13 ` Matt Roper [this message]
2025-11-07 18:13 ` [PATCH 21/33] drm/xe/drm_client: Use scope-based cleanup Matt Roper
2025-11-07 18:13 ` [PATCH 22/33] drm/xe/gt_debugfs: " Matt Roper
2025-11-07 18:13 ` [PATCH 23/33] drm/xe/huc: Use scope-based forcewake Matt Roper
2025-11-07 18:13 ` [PATCH 24/33] drm/xe/query: " Matt Roper
2025-11-07 18:13 ` [PATCH 25/33] drm/xe/reg_sr: " Matt Roper
2025-11-07 18:13 ` [PATCH 26/33] drm/xe/vram: " Matt Roper
2025-11-07 18:13 ` [PATCH 27/33] drm/xe/bo: Use scope-based runtime PM Matt Roper
2025-11-07 18:13 ` [PATCH 28/33] drm/xe/ggtt: Use scope-based runtime pm Matt Roper
2025-11-07 18:13 ` [PATCH 29/33] drm/xe/hwmon: Use scope-based runtime PM Matt Roper
2025-11-07 18:13 ` [PATCH 30/33] drm/xe/sriov: " Matt Roper
2025-11-07 18:13 ` [PATCH 31/33] drm/xe/tests: " Matt Roper
2025-11-07 18:13 ` [PATCH 32/33] drm/xe/sysfs: Use scope-based runtime power management Matt Roper
2025-11-07 18:13 ` [PATCH 33/33] drm/xe/debugfs: Use scope-based runtime PM Matt Roper
2025-11-07 18:18 ` [PATCH 00/33] Scope-based forcewake and " Matt Roper
2025-11-07 20:43 ` ✗ CI.checkpatch: warning for " Patchwork
2025-11-07 20:45 ` ✓ CI.KUnit: success " Patchwork
2025-11-07 21:21 ` ✓ Xe.CI.BAT: " Patchwork
2025-11-09 3:59 ` ✗ Xe.CI.Full: failure " 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=20251107181315.631642-55-matthew.d.roper@intel.com \
--to=matthew.d.roper@intel.com \
--cc=intel-xe@lists.freedesktop.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