mmc: core: Use PF_MEMALLOC flag for clock scaling context
Memory allocations with GFP_KERNEL flag in clock scaling path might trigger IO transfer. This can cause deadlock since the claim_host lock which is needed by mmc driver to perform IO is held by clock scaling context. Below is the exact call sequence: mmc_devfreq_set_target() -> mmc_clk_update_freq () -> mmc_change_bus_speed() -> mmc_select_hs400() -> mmc_select_bus_width() -> mmc_get_ext_csd() -> kzalloc(512, GFP_KERNEL) -> try_to_free_pages() -> evict() -> ext4_evict_inode(). To avoid this scenario, use PF_MEMALLOC flag for clock scaling context so that it can have access to the more reserves of memory. And since devfreq workitem would run in different kworker threads, restore to original flags once done with setting clock frequency. Change-Id: If52f83f6ecae982d8ed709b08fd84545c7ecbc43 Signed-off-by: Veerabhadrarao Badiganti <vbadigan@codeaurora.org>
This commit is contained in:
parent
e5b8aadd07
commit
1fbefb5219
1 changed files with 6 additions and 0 deletions
|
@ -487,12 +487,17 @@ static int mmc_devfreq_set_target(struct device *dev,
|
|||
struct mmc_devfeq_clk_scaling *clk_scaling;
|
||||
int err = 0;
|
||||
int abort;
|
||||
unsigned long pflags = current->flags;
|
||||
|
||||
/* Ensure scaling would happen even in memory pressure conditions */
|
||||
current->flags |= PF_MEMALLOC;
|
||||
|
||||
if (!(host && freq)) {
|
||||
pr_err("%s: unexpected host/freq parameter\n", __func__);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
clk_scaling = &host->clk_scaling;
|
||||
|
||||
if (!clk_scaling->enable)
|
||||
|
@ -551,6 +556,7 @@ static int mmc_devfreq_set_target(struct device *dev,
|
|||
rel_host:
|
||||
mmc_release_host(host);
|
||||
out:
|
||||
tsk_restore_flags(current, pflags, PF_MEMALLOC);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue