Message ID | 20171222013915.GC7997@codeaurora.org (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On 12/21/2017 07:39 PM, Stephen Boyd wrote: > On 12/20, Stephen Boyd wrote: >> On 12/20, David Lechner wrote: >>> On 12/20/2017 02:33 PM, David Lechner wrote: >>> >>> >>> So, the question I have is: what is the actual "correct" behavior of >>> spin_trylock_irqsave()? Is it really supposed to always return true >>> when CONFIG_DEBUG_SPINLOCK=n and CONFIG_SMP=n or is this a bug? >> >> Thanks for doing the analysis in this thread. >> >> When CONFIG_DEBUG_SPINLOCK=n and CONFIG_SMP=n, spinlocks are >> compiler barriers, that's it. So even if it is a bug to always >> return true, I fail to see how we can detect that a spinlock is >> already held in this configuration and return true or false. >> >> I suppose the best option is to make clk_enable_lock() and >> clk_enable_unlock() into nops or pure owner/refcount/barrier >> updates when CONFIG_SMP=n. We pretty much just need the barrier >> semantics when there's only a single CPU. >> > > How about this patch? It should make the trylock go away on UP > configs and then we keep everything else for refcount and > ownership. We would test enable_owner outside of any > irqs/preemption disabled section though. That needs a think. > > ---8<---- > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index 3526bc068f30..b6f61367aa8d 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -143,7 +143,8 @@ static unsigned long clk_enable_lock(void) > { > unsigned long flags; > > - if (!spin_trylock_irqsave(&enable_lock, flags)) { > + if (!IS_ENABLED(CONFIG_SMP) || > + !spin_trylock_irqsave(&enable_lock, flags)) { > if (enable_owner == current) { > enable_refcnt++; > __acquire(enable_lock); > > I came up with the exact same patch earlier today, but did not have a chance to send it. I've tested it and it fixes the problem for me. I'm afraid I don't know enough about how preemption works yet to be of much help to say what or if something else is needed to protect enable_owner/enable_refcnt. -- To unsubscribe from this list: send the line "unsubscribe linux-clk" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 3526bc068f30..b6f61367aa8d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -143,7 +143,8 @@ static unsigned long clk_enable_lock(void) { unsigned long flags; - if (!spin_trylock_irqsave(&enable_lock, flags)) { + if (!IS_ENABLED(CONFIG_SMP) || + !spin_trylock_irqsave(&enable_lock, flags)) { if (enable_owner == current) { enable_refcnt++; __acquire(enable_lock);