• Viresh Kumar's avatar
    PM / OPP: Protect updates to list_dev with mutex · 87b4115d
    Viresh Kumar authored
    dev_opp_list_lock is used everywhere to protect device and OPP lists,
    but dev_pm_opp_set_sharing_cpus() is missed somehow. And instead we used
    rcu-lock, which wouldn't help here as we are adding a new list_dev.
    
    This also fixes a problem where we have called kzalloc(..., GFP_KERNEL)
    from within rcu-lock, which isn't allowed as kzalloc can sleep when
    called with GFP_KERNEL.
    
    With CONFIG_DEBUG_ATOMIC_SLEEP set, we get following lockdep-splat:
    
    include/linux/rcupdate.h:578 Illegal context switch in RCU read-side critical section!
    
    other info that might help us debug this:
    
    rcu_scheduler_active = 1, debug_locks = 0
    5 locks held by swapper/0/1:
     #0:  (&dev->mutex){......}, at: [<c02f68f4>] __driver_attach+0x48/0x98
     #1:  (&dev->mutex){......}, at: [<c02f6904>] __driver_attach+0x58/0x98
     #2:  (cpu_hotplug.lock){++++++}, at: [<c00249d0>] get_online_cpus+0x40/0xb0
     #3:  (subsys mutex#5){+.+.+.}, at: [<c02f4f8c>] subsys_interface_register+0x44/0xdc
     #4:  (rcu_read_lock){......}, at: [<c0305c80>] dev_pm_opp_set_sharing_cpus+0x0/0x1e4
    
    stack backtrace:
    CPU: 1 PID: 1 Comm: swapper/0 Tainted: G        W       4.3.0-rc7-00047-g81f5932958a8 #59
    Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
    [<c0016874>] (unwind_backtrace) from [<c001355c>] (show_stack+0x10/0x14)
    [<c001355c>] (show_stack) from [<c022553c>] (dump_stack+0x94/0xbc)
    [<c022553c>] (dump_stack) from [<c004904c>] (___might_sleep+0x24c/0x298)
    [<c004904c>] (___might_sleep) from [<c00f07e4>] (kmem_cache_alloc+0xe8/0x164)
    [<c00f07e4>] (kmem_cache_alloc) from [<c0305354>] (_add_list_dev+0x30/0x58)
    [<c0305354>] (_add_list_dev) from [<c0305d50>] (dev_pm_opp_set_sharing_cpus+0xd0/0x1e4)
    [<c0305d50>] (dev_pm_opp_set_sharing_cpus) from [<c040eda4>] (cpufreq_init+0x4cc/0x62c)
    [<c040eda4>] (cpufreq_init) from [<c040a964>] (cpufreq_online+0xbc/0x73c)
    [<c040a964>] (cpufreq_online) from [<c02f4fe0>] (subsys_interface_register+0x98/0xdc)
    [<c02f4fe0>] (subsys_interface_register) from [<c040a640>] (cpufreq_register_driver+0x110/0x17c)
    [<c040a640>] (cpufreq_register_driver) from [<c040ef64>] (dt_cpufreq_probe+0x60/0x8c)
    [<c040ef64>] (dt_cpufreq_probe) from [<c02f8084>] (platform_drv_probe+0x44/0xa4)
    [<c02f8084>] (platform_drv_probe) from [<c02f67c0>] (driver_probe_device+0x208/0x2f4)
    [<c02f67c0>] (driver_probe_device) from [<c02f6940>] (__driver_attach+0x94/0x98)
    [<c02f6940>] (__driver_attach) from [<c02f4c1c>] (bus_for_each_dev+0x68/0x9c)
    Reported-by: default avatarMichael Turquette <mturquette@baylibre.com>
    Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
    Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
    Cc: 4.3 <stable@vger.kernel.org> # 4.3
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    87b4115d
opp.h 4.72 KB