diff options
author | kirdev01 <kiran.devrajegowda@arm.com> | 2023-05-05 14:20:35 +0200 |
---|---|---|
committer | Guus Sliepen <gsliepen@google.com> | 2023-05-30 15:52:15 +0000 |
commit | 742b99a55c83b81619437f28bc4dee4702a5c768 (patch) | |
tree | f813c7960ce51c3c30b71aba2b35b5c252298241 /mali_kbase | |
parent | 37584753704e12d68043af1abd7e9c33c919c29b (diff) | |
download | gpu-742b99a55c83b81619437f28bc4dee4702a5c768.tar.gz |
GPUCORE-37961 Deadlock issue due to lock ordering issue
This patch addresses the dead lock condition due to circular locking
dependency between hwaccess_lock and clk_rtm->lock.Hwaccess_lock needs
to be taken before clk_rtm->lock to avoid locking dependency.
Change-Id: I1064dbbac7800282bf3a1ac167c9c476177aefd8
(cherry picked from commit e0dfe9669c3456ada4b860f6ba9859c59ffec9a7)
Bug: 274687461
Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/5258
Diffstat (limited to 'mali_kbase')
-rw-r--r-- | mali_kbase/backend/gpu/mali_kbase_clk_rate_trace_mgr.c | 8 | ||||
-rw-r--r-- | mali_kbase/csf/ipa_control/mali_kbase_csf_ipa_control.c | 19 |
2 files changed, 13 insertions, 14 deletions
diff --git a/mali_kbase/backend/gpu/mali_kbase_clk_rate_trace_mgr.c b/mali_kbase/backend/gpu/mali_kbase_clk_rate_trace_mgr.c index ddd03ca..8d09347 100644 --- a/mali_kbase/backend/gpu/mali_kbase_clk_rate_trace_mgr.c +++ b/mali_kbase/backend/gpu/mali_kbase_clk_rate_trace_mgr.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note /* * - * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved. + * (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software @@ -241,7 +241,8 @@ void kbase_clk_rate_trace_manager_gpu_active(struct kbase_device *kbdev) if (!clk_rtm->clk_rate_trace_ops) return; - spin_lock_irqsave(&clk_rtm->lock, flags); + spin_lock_irqsave(&kbdev->hwaccess_lock, flags); + spin_lock(&clk_rtm->lock); for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) { struct kbase_clk_data *clk_data = clk_rtm->clks[i]; @@ -257,7 +258,8 @@ void kbase_clk_rate_trace_manager_gpu_active(struct kbase_device *kbdev) } clk_rtm->gpu_idle = false; - spin_unlock_irqrestore(&clk_rtm->lock, flags); + spin_unlock(&clk_rtm->lock); + spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); } void kbase_clk_rate_trace_manager_gpu_idle(struct kbase_device *kbdev) diff --git a/mali_kbase/csf/ipa_control/mali_kbase_csf_ipa_control.c b/mali_kbase/csf/ipa_control/mali_kbase_csf_ipa_control.c index ccdc48c..2772cfa 100644 --- a/mali_kbase/csf/ipa_control/mali_kbase_csf_ipa_control.c +++ b/mali_kbase/csf/ipa_control/mali_kbase_csf_ipa_control.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note /* * - * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved. + * (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software @@ -276,7 +276,6 @@ kbase_ipa_control_rate_change_notify(struct kbase_clk_rate_listener *listener, { if ((clk_index == KBASE_CLOCK_DOMAIN_TOP) && (clk_rate_hz != 0)) { size_t i; - unsigned long flags; struct kbase_ipa_control_listener_data *listener_data = container_of(listener, struct kbase_ipa_control_listener_data, @@ -284,13 +283,11 @@ kbase_ipa_control_rate_change_notify(struct kbase_clk_rate_listener *listener, struct kbase_device *kbdev = listener_data->kbdev; struct kbase_ipa_control *ipa_ctrl = &kbdev->csf.ipa_control; - spin_lock_irqsave(&kbdev->hwaccess_lock, flags); - + lockdep_assert_held(&kbdev->hwaccess_lock); if (!kbdev->pm.backend.gpu_ready) { dev_err(kbdev->dev, "%s: GPU frequency cannot change while GPU is off", __func__); - spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); return; } @@ -322,10 +319,7 @@ kbase_ipa_control_rate_change_notify(struct kbase_clk_rate_listener *listener, kbase_reg_write(kbdev, IPA_CONTROL_REG(TIMER), timer_value(ipa_ctrl->cur_gpu_rate)); } - spin_unlock(&ipa_ctrl->lock); - - spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); } } @@ -335,6 +329,7 @@ void kbase_ipa_control_init(struct kbase_device *kbdev) struct kbase_clk_rate_trace_manager *clk_rtm = &kbdev->pm.clk_rtm; struct kbase_ipa_control_listener_data *listener_data; size_t i, j; + unsigned long flags; for (i = 0; i < KBASE_IPA_CORE_TYPE_NUM; i++) { for (j = 0; j < KBASE_IPA_CONTROL_NUM_BLOCK_COUNTERS; j++) { @@ -358,15 +353,14 @@ void kbase_ipa_control_init(struct kbase_device *kbdev) listener_data->kbdev = kbdev; ipa_ctrl->rtm_listener_data = listener_data; } - - spin_lock(&clk_rtm->lock); + spin_lock_irqsave(&clk_rtm->lock, flags); if (clk_rtm->clks[KBASE_CLOCK_DOMAIN_TOP]) ipa_ctrl->cur_gpu_rate = clk_rtm->clks[KBASE_CLOCK_DOMAIN_TOP]->clock_val; if (listener_data) kbase_clk_rate_trace_manager_subscribe_no_lock( clk_rtm, &listener_data->listener); - spin_unlock(&clk_rtm->lock); + spin_unlock_irqrestore(&clk_rtm->lock, flags); } KBASE_EXPORT_TEST_API(kbase_ipa_control_init); @@ -1009,9 +1003,12 @@ void kbase_ipa_control_rate_change_notify_test(struct kbase_device *kbdev, struct kbase_ipa_control *ipa_ctrl = &kbdev->csf.ipa_control; struct kbase_ipa_control_listener_data *listener_data = ipa_ctrl->rtm_listener_data; + unsigned long flags; + spin_lock_irqsave(&kbdev->hwaccess_lock, flags); kbase_ipa_control_rate_change_notify(&listener_data->listener, clk_index, clk_rate_hz); + spin_lock_irqrestore(&kbdev->hwaccess_lock, flags); } KBASE_EXPORT_TEST_API(kbase_ipa_control_rate_change_notify_test); #endif |