Commit d9f1bb6ad7fc53c406706f47858dd5ff030b14a3

Authored by Paul E. McKenney
Committed by Ingo Molnar
1 parent 056ba4a9be

rcu: Make rcu_read_lock_sched_held() take boot time into account

Before the scheduler starts, all tasks are non-preemptible by
definition. So, during that time, rcu_read_lock_sched_held()
needs to always return "true".  This patch makes that be so.

Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: laijs@cn.fujitsu.com
Cc: dipankar@in.ibm.com
Cc: mathieu.desnoyers@polymtl.ca
Cc: josh@joshtriplett.org
Cc: dvhltc@us.ibm.com
Cc: niv@us.ibm.com
Cc: peterz@infradead.org
Cc: rostedt@goodmis.org
Cc: Valdis.Kletnieks@vt.edu
Cc: dhowells@redhat.com
LKML-Reference: <1267135607-7056-2-git-send-email-paulmck@linux.vnet.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 5 changed files with 21 additions and 25 deletions Side-by-side Diff

include/linux/rcupdate.h
... ... @@ -62,6 +62,8 @@
62 62  
63 63 /* Internal to kernel */
64 64 extern void rcu_init(void);
  65 +extern int rcu_scheduler_active;
  66 +extern void rcu_scheduler_starting(void);
65 67  
66 68 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
67 69 #include <linux/rcutree.h>
... ... @@ -140,7 +142,7 @@
140 142  
141 143 if (debug_locks)
142 144 lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
143   - return lockdep_opinion || preempt_count() != 0;
  145 + return lockdep_opinion || preempt_count() != 0 || !rcu_scheduler_active;
144 146 }
145 147  
146 148 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
include/linux/rcutiny.h
... ... @@ -105,10 +105,6 @@
105 105  
106 106 #endif /* #else #ifdef CONFIG_NO_HZ */
107 107  
108   -static inline void rcu_scheduler_starting(void)
109   -{
110   -}
111   -
112 108 static inline void exit_rcu(void)
113 109 {
114 110 }
include/linux/rcutree.h
... ... @@ -35,7 +35,6 @@
35 35 extern void rcu_sched_qs(int cpu);
36 36 extern void rcu_bh_qs(int cpu);
37 37 extern int rcu_needs_cpu(int cpu);
38   -extern void rcu_scheduler_starting(void);
39 38 extern int rcu_expedited_torture_stats(char *page);
40 39  
41 40 #ifdef CONFIG_TREE_PREEMPT_RCU
... ... @@ -44,6 +44,7 @@
44 44 #include <linux/cpu.h>
45 45 #include <linux/mutex.h>
46 46 #include <linux/module.h>
  47 +#include <linux/kernel_stat.h>
47 48  
48 49 #ifdef CONFIG_DEBUG_LOCK_ALLOC
49 50 static struct lock_class_key rcu_lock_key;
... ... @@ -61,6 +62,23 @@
61 62 STATIC_LOCKDEP_MAP_INIT("rcu_read_lock_sched", &rcu_sched_lock_key);
62 63 EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
63 64 #endif
  65 +
  66 +int rcu_scheduler_active __read_mostly;
  67 +
  68 +/*
  69 + * This function is invoked towards the end of the scheduler's initialization
  70 + * process. Before this is called, the idle task might contain
  71 + * RCU read-side critical sections (during which time, this idle
  72 + * task is booting the system). After this function is called, the
  73 + * idle tasks are prohibited from containing RCU read-side critical
  74 + * sections.
  75 + */
  76 +void rcu_scheduler_starting(void)
  77 +{
  78 + WARN_ON(num_online_cpus() != 1);
  79 + WARN_ON(nr_context_switches() > 0);
  80 + rcu_scheduler_active = 1;
  81 +}
64 82  
65 83 /*
66 84 * Awaken the corresponding synchronize_rcu() instance now that a
... ... @@ -46,7 +46,6 @@
46 46 #include <linux/cpu.h>
47 47 #include <linux/mutex.h>
48 48 #include <linux/time.h>
49   -#include <linux/kernel_stat.h>
50 49  
51 50 #include "rcutree.h"
52 51  
... ... @@ -81,9 +80,6 @@
81 80 struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
82 81 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
83 82  
84   -static int rcu_scheduler_active __read_mostly;
85   -
86   -
87 83 /*
88 84 * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s
89 85 * permit this function to be invoked without holding the root rcu_node
... ... @@ -1563,21 +1559,6 @@
1563 1559 return per_cpu(rcu_sched_data, cpu).nxtlist ||
1564 1560 per_cpu(rcu_bh_data, cpu).nxtlist ||
1565 1561 rcu_preempt_needs_cpu(cpu);
1566   -}
1567   -
1568   -/*
1569   - * This function is invoked towards the end of the scheduler's initialization
1570   - * process. Before this is called, the idle task might contain
1571   - * RCU read-side critical sections (during which time, this idle
1572   - * task is booting the system). After this function is called, the
1573   - * idle tasks are prohibited from containing RCU read-side critical
1574   - * sections.
1575   - */
1576   -void rcu_scheduler_starting(void)
1577   -{
1578   - WARN_ON(num_online_cpus() != 1);
1579   - WARN_ON(nr_context_switches() > 0);
1580   - rcu_scheduler_active = 1;
1581 1562 }
1582 1563  
1583 1564 static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};