Commit d9f1bb6ad7fc53c406706f47858dd5ff030b14a3
Committed by
Ingo Molnar
1 parent
056ba4a9be
Exists in
master
and in
4 other branches
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
include/linux/rcutree.h
kernel/rcupdate.c
... | ... | @@ -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 |
kernel/rcutree.c
... | ... | @@ -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}; |