lkml.org 
[lkml]   [2011]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: INFO: possible circular locking dependency detected
    From
    Date
    On Fri, 2011-07-15 at 10:24 -0700, Paul E. McKenney wrote:

    > But the rcu_read_unlock() called from within the irq handler would
    > take a second snapshot of ->special. It could then enter
    > rcu_read_unlock_special().

    You agree that an interrupt preempting the rcu_read_unlock() is causing
    the issues correct? But it is also contained within rcu_read_unlock().
    That is, we just don't want interrupts or softirqs from calling the
    special function when it preempted rcu_read_unlock().

    How about this patch? (again totally untested and not even compiled)

    -- Steve

    diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
    index 7784bd2..0bdf0ea 100644
    --- a/kernel/rcupdate.c
    +++ b/kernel/rcupdate.c
    @@ -46,6 +46,8 @@
    #include <linux/module.h>
    #include <linux/hardirq.h>

    +DEFINE_PER_CPU(int, in_rcu_read_unlock);
    +
    #ifdef CONFIG_DEBUG_LOCK_ALLOC
    static struct lock_class_key rcu_lock_key;
    struct lockdep_map rcu_lock_map =
    diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
    index 14dc7dd..a4adbb7 100644
    --- a/kernel/rcutree_plugin.h
    +++ b/kernel/rcutree_plugin.h
    @@ -375,6 +375,8 @@ static void rcu_read_unlock_special(struct task_struct *t)
    }
    }

    +DECLARE_PER_CPU(int, in_rcu_read_unlock);
    +
    /*
    * Tree-preemptible RCU implementation for rcu_read_unlock().
    * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost
    @@ -386,12 +388,16 @@ void __rcu_read_unlock(void)
    {
    struct task_struct *t = current;

    + get_cpu_var(in_rcu_read_unlock)++;
    barrier(); /* needed if we ever invoke rcu_read_unlock in rcutree.c */
    --t->rcu_read_lock_nesting;
    barrier(); /* decrement before load of ->rcu_read_unlock_special */
    if (t->rcu_read_lock_nesting == 0 &&
    + __get_cpu_var(in_rcu_read_unlock) == 1 &&
    unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
    rcu_read_unlock_special(t);
    + __get_cpu_var(in_rcu_read_unlock)--;
    + put_cpu_var(in_rcu_read_unlock);
    #ifdef CONFIG_PROVE_LOCKING
    WARN_ON_ONCE(ACCESS_ONCE(t->rcu_read_lock_nesting) < 0);
    #endif /* #ifdef CONFIG_PROVE_LOCKING */



    \
     
     \ /
      Last update: 2011-07-15 19:45    [from the cache]
    ©2003-2014 Jasper Spaans. Advertise on this site