lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.14 78/97] clk: fix reentrancy of clk_enable() on UP systems
    Date
    From: David Lechner <david@lechnology.com>

    [ Upstream commit a12aa8a68dfef5de181f2e555aa950a0ab05411f ]

    Reentrant calls to clk_enable() are not working on UP systems. This is
    caused by the fact spin_trylock_irqsave() always returns true when
    CONFIG_SMP=n (and CONFIG_DEBUG_SPINLOCK=n) which causes the reference
    counting to not work correctly when clk_enable_lock() is called twice
    before clk_enable_unlock() is called (this happens when clk_enable()
    is called from within another clk_enable()).

    This fixes the problem by skipping the call to spin_trylock_irqsave() on UP
    systems and relying solely on reference counting. We also make sure to set
    flags in this case so that we are not returning an uninitialized value.

    Suggested-by: Stephen Boyd <sboyd@codeaurora.org>
    Signed-off-by: David Lechner <david@lechnology.com>
    Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/clk/clk.c | 10 +++++++++-
    1 file changed, 9 insertions(+), 1 deletion(-)

    diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
    index c8d83acda006..f6c9d6205d85 100644
    --- a/drivers/clk/clk.c
    +++ b/drivers/clk/clk.c
    @@ -119,10 +119,18 @@ static unsigned long clk_enable_lock(void)
    {
    unsigned long flags;

    - if (!spin_trylock_irqsave(&enable_lock, flags)) {
    + /*
    + * On UP systems, spin_trylock_irqsave() always returns true, even if
    + * we already hold the lock. So, in that case, we rely only on
    + * reference counting.
    + */
    + if (!IS_ENABLED(CONFIG_SMP) ||
    + !spin_trylock_irqsave(&enable_lock, flags)) {
    if (enable_owner == current) {
    enable_refcnt++;
    __acquire(enable_lock);
    + if (!IS_ENABLED(CONFIG_SMP))
    + local_save_flags(flags);
    return flags;
    }
    spin_lock_irqsave(&enable_lock, flags);
    --
    2.14.1
    \
     
     \ /
      Last update: 2018-03-19 17:00    [W:4.074 / U:0.224 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site