From: Rocky Hao Date: Mon, 24 Apr 2017 02:26:38 +0000 (+0800) Subject: thermal: rockchip: rk3368: fix bad unlock balance issue X-Git-Tag: release-20171130_firefly~4^2~754 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=63a75ae9ee9d8927212f5ea69642f7acdadb3741;p=firefly-linux-kernel-4.4.55.git thermal: rockchip: rk3368: fix bad unlock balance issue We WRONGLY supposed both REGULATOR_EVENT_PRE_VOLTAGE_CHANGE and REGULATOR_EVENT_VOLTAGE_CHANGE were used in pairs. If volts are not changed in volts setting process, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE is NOT sent,but REGULATOR_EVENT_VOLTAGE_CHANGE is sent. So we check the lock status before we release the lock. [ 3.535657] ===================================== [ 3.535703] [ BUG: bad unlock balance detected! ] [ 3.535757] 4.4.55 #2 Not tainted [ 3.535800] ------------------------------------- [ 3.535847] cfinteractive/65 is trying to release lock (thermal_reg_mutex) at: [ 3.535969] [] mutex_unlock+0xc/0x14 [ 3.536015] but there are no more locks to release! [ 3.536058] wifi_platform_bus_enumerate device present 1 [ 3.536076] [ 3.536076] other info that might help us debug this: [ 3.536088] ======== Card detection to detect SDIO card! ======== [ 3.536104] 4 locks held by cfinteractive/65: [ 3.536115] mmc2:mmc host rescan start! [ 3.536123] #0: (&policy->rwsem){+.+.+.}, at: [] cpufreq_interactive_speedchange_task+0x138/0x48c [ 3.536323] #1: (&pcpu->enable_sem){++++..}, at: [] cpufreq_interactive_speedchange_task+0x144/0x48c [ 3.536510] #2: (&rdev->mutex){+.+.+.}, at: [] regulator_set_voltage+0x34/0x90 [ 3.536700] #3: (&(&rdev->notifier)->rwsem){.+.+..}, at: [] __blocking_notifier_call_chain+0x30/0x64 [ 3.536892] [ 3.536892] stack backtrace: [ 3.536962] CPU: 2 PID: 65 Comm: cfinteractive Not tainted 4.4.55 #2 [ 3.537011] Hardware name: Rockchip rk3368 p9 board (DT) [ 3.537056] Call trace: [ 3.537118] [] dump_backtrace+0x0/0x1c4 [ 3.537182] [] show_stack+0x14/0x1c [ 3.537249] [] dump_stack+0xa8/0xe0 [ 3.537317] [] print_unlock_imbalance_bug.part.25+0xbc/0xcc [ 3.537386] [] lock_release+0x218/0x464 [ 3.537448] [] __mutex_unlock_slowpath+0xf4/0x170 [ 3.537507] [] mutex_unlock+0xc/0x14 [ 3.537573] [] rk3368_thermal_notify+0x5c/0x68 [ 3.537637] [] notifier_call_chain+0x54/0x88 [ 3.537702] [] __blocking_notifier_call_chain+0x48/0x64 [ 3.537768] [] blocking_notifier_call_chain+0x14/0x1c [ 3.537837] [] _regulator_do_set_voltage+0x3dc/0x61c [ 3.537904] [] regulator_set_voltage_unlocked+0x1a8/0x208 [ 3.537971] [] regulator_set_voltage+0x5c/0x90 [ 3.538039] [] _set_opp_voltage+0x44/0xa4 [ 3.538104] [] dev_pm_opp_set_rate+0x47c/0x540 [ 3.538168] [] set_target+0x30/0x38 [ 3.538234] [] __cpufreq_driver_target+0x1d8/0x298 [ 3.538298] [] cpufreq_interactive_speedchange_task+0x270/0x48c [ 3.538360] [] kthread+0xf4/0xfc [ 3.538419] [] ret_from_fork+0x10/0x40 Change-Id: I8a89bde9ff6ec83255b8a4c017e6ff792535ebb8 Signed-off-by: Rocky Hao --- diff --git a/drivers/thermal/rk3368_thermal.c b/drivers/thermal/rk3368_thermal.c index 937c0b67f104..d47bd1f001f8 100644 --- a/drivers/thermal/rk3368_thermal.c +++ b/drivers/thermal/rk3368_thermal.c @@ -853,7 +853,8 @@ static int rk3368_thermal_notify(struct notifier_block *nb, } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE | REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) { ctx->regulator_uv = (unsigned long)data; - mutex_unlock(&thermal_reg_mutex); + if (mutex_is_locked(&thermal_reg_mutex)) + mutex_unlock(&thermal_reg_mutex); } else { return NOTIFY_OK; }