[PATCH v3 01/23] drm/xe: Error handling in xe_force_wake_get()

Himal Prasad Ghimiray himal.prasad.ghimiray at intel.com
Tue Sep 17 12:21:04 UTC 2024


If an acknowledgment timeout occurs for a domain awake request, do not
increment the reference count for the domain. This ensures that
subsequent _get calls do not incorrectly assume the domain is awake. The
return value is a mask of domains whose reference counts were
incremented, and these domains need to be released using
xe_force_wake_put.

The caller needs to compare the return value with the input domains to
determine the success or failure of the operation and decide whether to
continue or return accordingly.

While at it, add simple kernel-doc for xe_force_wake_get()

v3
- Use explicit type for mask (Michal/Badal)
- Improve kernel-doc (Michal)
- Use unsigned int instead of abusing enum (Michal)

Cc: Michal Wajdeczko <michal.wajdeczko at intel.com>
Cc: Badal Nilawar <badal.nilawar at intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
Cc: Lucas De Marchi <lucas.demarchi at intel.com>
Cc: Nirmoy Das <nirmoy.das at intel.com>
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray at intel.com>
---
 drivers/gpu/drm/xe/xe_force_wake.c       | 37 +++++++++++++++++++-----
 drivers/gpu/drm/xe/xe_force_wake.h       |  4 +--
 drivers/gpu/drm/xe/xe_force_wake_types.h |  2 ++
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_force_wake.c b/drivers/gpu/drm/xe/xe_force_wake.c
index a64c14757c84..bc0cb988e12f 100644
--- a/drivers/gpu/drm/xe/xe_force_wake.c
+++ b/drivers/gpu/drm/xe/xe_force_wake.c
@@ -150,26 +150,47 @@ static int domain_sleep_wait(struct xe_gt *gt,
 					 (ffs(tmp__) - 1))) && \
 					 domain__->reg_ctl.addr)
 
-int xe_force_wake_get(struct xe_force_wake *fw,
-		      enum xe_force_wake_domains domains)
+/**
+ * xe_force_wake_get() : Increase the domain refcount
+ * @fw: struct xe_force_wake
+ * @domains: forcewake domains to get refcount on
+ *
+ * This function takes references for the input @domains and wakes them if
+ * they are asleep.
+ *
+ * Return: mask of refcount increased domains. If the return value is
+ * equal to the input parameter @domains, the operation is considered
+ * successful. Otherwise, the operation is considered a failure, and
+ * the caller should handle the failure case, potentially returning
+ * -ETIMEDOUT.
+ */
+xe_wakeref_t xe_force_wake_get(struct xe_force_wake *fw,
+			       enum xe_force_wake_domains domains)
 {
 	struct xe_gt *gt = fw->gt;
 	struct xe_force_wake_domain *domain;
-	enum xe_force_wake_domains tmp, woken = 0;
+	unsigned int tmp, awake_rqst = 0, awake_ack = 0;
 	unsigned long flags;
-	int ret = 0;
+	xe_wakeref_t ret;
 
+	ret = domains;
 	spin_lock_irqsave(&fw->lock, flags);
 	for_each_fw_domain_masked(domain, domains, fw, tmp) {
 		if (!domain->ref++) {
-			woken |= BIT(domain->id);
+			awake_rqst |= BIT(domain->id);
 			domain_wake(gt, domain);
 		}
 	}
-	for_each_fw_domain_masked(domain, woken, fw, tmp) {
-		ret |= domain_wake_wait(gt, domain);
+	for_each_fw_domain_masked(domain, awake_rqst, fw, tmp) {
+		if (domain_wake_wait(gt, domain) == 0) {
+			awake_ack |= BIT(domain->id);
+		} else {
+			ret &= ~BIT(domain->id);
+			--domain->ref;
+		}
 	}
-	fw->awake_domains |= woken;
+
+	fw->awake_domains |= awake_ack;
 	spin_unlock_irqrestore(&fw->lock, flags);
 
 	return ret;
diff --git a/drivers/gpu/drm/xe/xe_force_wake.h b/drivers/gpu/drm/xe/xe_force_wake.h
index a2577672f4e3..3ac686519a4e 100644
--- a/drivers/gpu/drm/xe/xe_force_wake.h
+++ b/drivers/gpu/drm/xe/xe_force_wake.h
@@ -15,8 +15,8 @@ void xe_force_wake_init_gt(struct xe_gt *gt,
 			   struct xe_force_wake *fw);
 void xe_force_wake_init_engines(struct xe_gt *gt,
 				struct xe_force_wake *fw);
-int xe_force_wake_get(struct xe_force_wake *fw,
-		      enum xe_force_wake_domains domains);
+xe_wakeref_t xe_force_wake_get(struct xe_force_wake *fw,
+			       enum xe_force_wake_domains domains);
 int xe_force_wake_put(struct xe_force_wake *fw,
 		      enum xe_force_wake_domains domains);
 
diff --git a/drivers/gpu/drm/xe/xe_force_wake_types.h b/drivers/gpu/drm/xe/xe_force_wake_types.h
index ed0edc2cdf9f..7dc514ee9825 100644
--- a/drivers/gpu/drm/xe/xe_force_wake_types.h
+++ b/drivers/gpu/drm/xe/xe_force_wake_types.h
@@ -11,6 +11,8 @@
 
 #include "regs/xe_reg_defs.h"
 
+typedef unsigned int xe_wakeref_t;
+
 enum xe_force_wake_domain_id {
 	XE_FW_DOMAIN_ID_GT = 0,
 	XE_FW_DOMAIN_ID_RENDER,
-- 
2.34.1



More information about the Intel-xe mailing list