From d69edcbcaed2001b9c305a2b8668dc0599801f2a Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Wed, 16 Mar 2016 14:44:52 +0530 Subject: mmc: core: fix deadlock between runtime-suspend and devfreq There's a deadlock between runtime-suspend and devfreq monitor. runtime-suspend context: [] __switch_to+0x7c [] __schedule+0x53c [] schedule+0x74 [] schedule_preempt_disabled+0x14 [] __mutex_lock_slowpath+0x1dc [] mutex_lock+0x2c [] devfreq_monitor_suspend+0x1c [] devfreq_simple_ondemand_handler+0x4c [] devfreq_suspend_device+0x2c [] mmc_suspend_clk_scaling+0xac [] _mmc_suspend.isra.11+0x38 [] mmc_runtime_suspend+0x1cc [] mmc_runtime_suspend+0x18 [] __rpm_callback+0x40 [] rpm_callback+0x40 [] rpm_suspend+0x25c In the above stack, runtime-suspend is waiting on the devfreq mutex. In the below stack, the mutex has been acquired and since the device power state is DEV_SUSPENDING, devfreq is waiting for the device to resume, thus causing a deadlock. [] schedule+0x74 [] rpm_resume+0x264 [] __pm_runtime_resume+0x70 [] mmc_get_card+0x1c [] mmc_devfreq_set_target+0x154 [] update_devfreq+0xd0 [] devfreq_monitor+0x2c Fix this by not waiting for device to resume in devfreq. The suspend would ensure that this devfreq monitor thread is suspended before suspending the device. Change-Id: Ic0e89becbfded35c90c4061f0fe03d61125f66d5 Signed-off-by: Asutosh Das --- drivers/mmc/core/core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 65113800026c..749bb74cb3a6 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -511,7 +511,6 @@ static int mmc_devfreq_set_target(struct device *dev, clk_scaling->need_freq_change = false; mmc_host_clk_hold(host); - mmc_get_card(host->card); err = mmc_clk_update_freq(host, *freq, clk_scaling->state); if (err && err != -EAGAIN) pr_err("%s: clock scale to %lu failed with error %d\n", @@ -520,7 +519,6 @@ static int mmc_devfreq_set_target(struct device *dev, pr_debug("%s: clock change to %lu finished successfully (%s)\n", mmc_hostname(host), *freq, current->comm); - mmc_put_card(host->card); mmc_host_clk_release(host); mmc_release_host(host); -- cgit v1.2.3