lkml.org 
[lkml]   [2011]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH tip/core/urgent 1/7] rcu: decrease rcu_report_exp_rnp coupling with scheduler
    On Wed, Jul 20, 2011 at 04:40:18AM +0200, Peter Zijlstra wrote:
    > On Tue, 2011-07-19 at 17:18 -0700, Paul E. McKenney wrote:
    > > +++ b/kernel/rcutree_plugin.h
    > > @@ -696,8 +696,10 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
    > > raw_spin_lock_irqsave(&rnp->lock, flags);
    > > for (;;) {
    > > if (!sync_rcu_preempt_exp_done(rnp))
    > > + raw_spin_unlock_irqrestore(&rnp->lock, flags);
    > > break;
    >
    > I bet that'll all work much better if you wrap it in curly braces like:
    >
    > if (!sync_rcu_preempt_exp_done(rnp)) {
    > raw_spin_unlock_irqrestore(&rnp->lock, flags);
    > break;
    > }
    >
    > That might also explain those explosions Ed and Ben have been seeing.

    Indeed. Must be the call of the snake. :-(

    Thank you for catching this!

    > > if (rnp->parent == NULL) {
    > > + raw_spin_unlock_irqrestore(&rnp->lock, flags);
    > > wake_up(&sync_rcu_preempt_exp_wq);
    > > break;
    > > }
    > > @@ -707,7 +709,6 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
    > > raw_spin_lock(&rnp->lock); /* irqs already disabled */
    > > rnp->expmask &= ~mask;
    > > }
    > > - raw_spin_unlock_irqrestore(&rnp->lock, flags);
    > > }

    So this time I am testing the exact patch series before resending.
    In the meantime, here is the updated version of this patch.

    Thanx, Paul

    ------------------------------------------------------------------------
    rcu: decrease rcu_report_exp_rnp coupling with scheduler

    PREEMPT_RCU read-side critical sections blocking an expedited grace
    period invoke rcu_report_exp_rnp(). When the last such critical section
    has completed, rcu_report_exp_rnp() invokes the scheduler to wake up the
    task that invoked synchronize_rcu_expedited() -- needlessly holding the
    root rcu_node structure's lock while doing so, thus needlessly providing
    a way for RCU and the scheduler to deadlock.

    This commit therefore releases the root rcu_node structure's lock before
    calling wake_up().

    Reported-by: Ed Tomlinson <edt@aei.ca>
    Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

    diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
    index 75113cb..6abef3c 100644
    --- a/kernel/rcutree_plugin.h
    +++ b/kernel/rcutree_plugin.h
    @@ -695,9 +695,12 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)

    raw_spin_lock_irqsave(&rnp->lock, flags);
    for (;;) {
    - if (!sync_rcu_preempt_exp_done(rnp))
    + if (!sync_rcu_preempt_exp_done(rnp)) {
    + raw_spin_unlock_irqrestore(&rnp->lock, flags);
    break;
    + }
    if (rnp->parent == NULL) {
    + raw_spin_unlock_irqrestore(&rnp->lock, flags);
    wake_up(&sync_rcu_preempt_exp_wq);
    break;
    }
    @@ -707,7 +710,6 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
    raw_spin_lock(&rnp->lock); /* irqs already disabled */
    rnp->expmask &= ~mask;
    }
    - raw_spin_unlock_irqrestore(&rnp->lock, flags);
    }

    /*

    \
     
     \ /
      Last update: 2011-07-20 06:57    [from the cache]
    ©2003-2014 Jasper Spaans. hosted at Digital Ocean