From 1fbefb5219e1f872dca8b1b54eecb7f83452d6fd Mon Sep 17 00:00:00 2001 From: Veerabhadrarao Badiganti Date: Fri, 23 Jun 2017 19:18:45 +0530 Subject: [PATCH] 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 --- drivers/mmc/core/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 2cb0ea03a338..f199a525615a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -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; }