Thread (25 messages) 25 messages, 8 authors, 2013-04-02

[PATCH 1/5] clk: allow reentrant calls into the clk framework

From: Russell King - ARM Linux <hidden>
Date: 2013-03-18 21:00:28
Also in: lkml

On Mon, Mar 18, 2013 at 01:15:51PM -0700, Mike Turquette wrote:
Quoting Ulf Hansson (2013-02-28 01:54:34)
quoted
On 28 February 2013 05:49, Mike Turquette [off-list ref] wrote:
quoted
@@ -703,10 +744,29 @@ int clk_enable(struct clk *clk)
        unsigned long flags;
        int ret;

+       /* this call re-enters if it is from the same context */
+       if (spin_is_locked(&enable_lock) || mutex_is_locked(&prepare_lock)) {
+               if ((void *) atomic_read(&context) == get_current()) {
+                       ret = __clk_enable(clk);
+                       goto out;
+               }
+       }
I beleive the clk_enable|disable code will be racy. What do you think
about this scenario:

1. Thread 1, calls clk_prepare -> clk is not reentrant -> mutex_lock
-> set_context to thread1.
2. Thread 2, calls clk_enable -> above "if" will mean that get_current
returns thread 1 context and then clk_enable continues ->
spin_lock_irqsave -> set_context to thread 2.
3. Thread 1 continues and triggers a reentancy for clk_prepare -> clk
is not reentrant (since thread 2 has set a new context) -> mutex_lock
and we will hang forever.

Do you think above scenario could happen?

I think the solution would be to invent another "static atomic_t
context;" which is used only for fast path functions
(clk_enable|disable). That should do the trick I think.
Ulf,

You are correct.  In fact I have a branch that has two separate context
pointers, one for mutex-protected functions and one for
spinlock-protected functions.  Somehow I managed to discard that change
before settling on the final version that was published.
Err.

Do not forget one very important point.

Any clock which has clk_enable() called on it must have had clk_prepare()
already called _and_ completed.  A second clk_prepare() call on the same
clock should be a no-op other than to increase the prepare reference count
on it.

If you do anything else, you are going to get into sticky problems.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help