From: Himal Prasad Ghimiray Date: Mon, 14 Oct 2024 07:55:40 +0000 (+0530) Subject: drm/xe: Modify xe_force_wake_put to handle _get returned mask X-Git-Tag: v6.13-rc1~122^2~10^2~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=79f716bbfa2c7c2639d161a4294ed0416a1c6efe;p=thirdparty%2Fkernel%2Flinux.git drm/xe: Modify xe_force_wake_put to handle _get returned mask Instead of calling xe_force_wake_put on all domains that were input to xe_force_wake_get, call _put only on the domains whose reference counts were successfully incremented by the _get call. Since the return value of _get can be a mask that does not match any specific value in the enum xe_force_wake_domains, change the input parameter of _put to unsigned int. v3 - Move WARN to this patch (Badal) - use xe_gt_WARN instead of XE_WARN (Michal) - Stop using xe_force_wake_domains for non enum values. - Remove kernel-doc from this patch (Badal) -v5 - Fix global awake_domain -v6 - put all initialized domains in case of FORCEWAKE_ALL. - Modify ret variable name (Michal) - Modify input var name (Michal) - Modify commit message and warn (Badal) -v9 - Add assert condition. Cc: Michal Wajdeczko Cc: Badal Nilawar Cc: Rodrigo Vivi Cc: Lucas De Marchi Cc: Nirmoy Das Reviewed-by: Badal Nilawar Signed-off-by: Himal Prasad Ghimiray Reviewed-by: Michal Wajdeczko Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/20241014075601.2324382-6-himal.prasad.ghimiray@intel.com Signed-off-by: Rodrigo Vivi --- diff --git a/drivers/gpu/drm/xe/xe_force_wake.c b/drivers/gpu/drm/xe/xe_force_wake.c index d36ed4f8bdbe9..7f285dbe6e2c4 100644 --- a/drivers/gpu/drm/xe/xe_force_wake.c +++ b/drivers/gpu/drm/xe/xe_force_wake.c @@ -212,26 +212,42 @@ unsigned int xe_force_wake_get(struct xe_force_wake *fw, } int xe_force_wake_put(struct xe_force_wake *fw, - enum xe_force_wake_domains domains) + unsigned int fw_ref) { struct xe_gt *gt = fw->gt; struct xe_force_wake_domain *domain; - enum xe_force_wake_domains tmp, sleep = 0; + unsigned int tmp, sleep = 0; unsigned long flags; - int ret = 0; + int ack_fail = 0; + + /* + * Avoid unnecessary lock and unlock when the function is called + * in error path of individual domains. + */ + if (!fw_ref) + return 0; + + if (xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) + fw_ref = fw->initialized_domains; spin_lock_irqsave(&fw->lock, flags); - for_each_fw_domain_masked(domain, domains, fw, tmp) { + 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) { - ret |= domain_sleep_wait(gt, domain); + if (domain_sleep_wait(gt, domain) == 0) + fw->awake_domains &= ~BIT(domain->id); + else + ack_fail |= BIT(domain->id); } - fw->awake_domains &= ~sleep; spin_unlock_irqrestore(&fw->lock, flags); - return ret; + xe_gt_WARN(gt, ack_fail, "Forcewake domain%s %#x failed to acknowledge sleep request\n", + str_plural(hweight_long(ack_fail)), ack_fail); + return ack_fail; } diff --git a/drivers/gpu/drm/xe/xe_force_wake.h b/drivers/gpu/drm/xe/xe_force_wake.h index 75fa1a19797c0..f0b27dbe75811 100644 --- a/drivers/gpu/drm/xe/xe_force_wake.h +++ b/drivers/gpu/drm/xe/xe_force_wake.h @@ -18,7 +18,7 @@ void xe_force_wake_init_engines(struct xe_gt *gt, unsigned int 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); + unsigned int fw_ref); static inline int xe_force_wake_ref(struct xe_force_wake *fw,