* [PATCH RFC tip/core/rcu 2/7] rcu: Wire ->rda pointers at compile time
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 3/7] rcu: Prevent early-boot RCU callbacks from splatting Paul E. McKenney
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
This commit wires up the rcu_state structures' ->rda pointers to the
per-CPU rcu_data structures at compile time, thus ensuring that this
linkage is present at early boot, in turn allowing posting of callbacks
before rcu_init() is executed.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 9b5ed5333c9a..37193daf2b62 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -91,8 +91,10 @@ static const char *tp_##sname##_varname __used __tracepoint_string = sname##_var
#define RCU_STATE_INITIALIZER(sname, sabbr, cr) \
DEFINE_RCU_TPS(sname) \
+DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, sname##_data); \
struct rcu_state sname##_state = { \
.level = { &sname##_state.node[0] }, \
+ .rda = &sname##_data, \
.call = cr, \
.fqs_state = RCU_GP_IDLE, \
.gpnum = 0UL - 300UL, \
@@ -104,8 +106,7 @@ struct rcu_state sname##_state = { \
.onoff_mutex = __MUTEX_INITIALIZER(sname##_state.onoff_mutex), \
.name = RCU_STATE_NAME(sname), \
.abbr = sabbr, \
-}; \
-DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, sname##_data)
+}
RCU_STATE_INITIALIZER(rcu_sched, 's', call_rcu_sched);
RCU_STATE_INITIALIZER(rcu_bh, 'b', call_rcu_bh);
@@ -3815,7 +3816,6 @@ static void __init rcu_init_one(struct rcu_state *rsp,
}
}
- rsp->rda = rda;
init_waitqueue_head(&rsp->gp_wq);
rnp = rsp->level[rcu_num_lvls - 1];
for_each_possible_cpu(i) {
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH RFC tip/core/rcu 3/7] rcu: Prevent early-boot RCU callbacks from splatting
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 2/7] rcu: Wire ->rda pointers at compile time Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 4/7] rcu: Refine diagnostics for lacking kthread for no-CBs callbacks Paul E. McKenney
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Currently, a call_rcu() that precedes rcu_init() will splat due to the
callback lists not having yet been initialized. This commit causes the
first such callback to initialize the boot CPU's RCU callback list.
Note that this commit does not change rcu_init()-time initialization,
which means that the callback will be discarded at rcu_init() time.
Fixing this is the job of later commits.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 37193daf2b62..ff2e42ebb64b 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2839,11 +2839,21 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
if (cpu != -1)
rdp = per_cpu_ptr(rsp->rda, cpu);
- offline = !__call_rcu_nocb(rdp, head, lazy, flags);
- WARN_ON_ONCE(offline);
- /* _call_rcu() is illegal on offline CPU; leak the callback. */
- local_irq_restore(flags);
- return;
+ if (likely(rdp->mynode)) {
+ /* Post-boot, so this should be for a no-CBs CPU. */
+ offline = !__call_rcu_nocb(rdp, head, lazy, flags);
+ WARN_ON_ONCE(offline);
+ /* Offline CPU, _call_rcu() illegal, leak callback. */
+ local_irq_restore(flags);
+ return;
+ }
+ /*
+ * Very early boot, before rcu_init(). Initialize if needed
+ * and then drop through to queue the callback.
+ */
+ BUG_ON(cpu != -1);
+ if (!likely(rdp->nxtlist))
+ init_default_callback_list(rdp);
}
ACCESS_ONCE(rdp->qlen) = rdp->qlen + 1;
if (lazy)
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH RFC tip/core/rcu 4/7] rcu: Refine diagnostics for lacking kthread for no-CBs callbacks
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 2/7] rcu: Wire ->rda pointers at compile time Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 3/7] rcu: Prevent early-boot RCU callbacks from splatting Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 5/7] rcu: Avoid clobbering early boot callbacks Paul E. McKenney
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Some diagnostics under CONFIG_PROVE_RCU in rcu_nocb_cpu_needs_barrier()
assume that there can be no early-boot callbacks. This commit therefore
qualifies the diagnostic with rcu_scheduler_fully_active to permit
early boot callbacks to avoid this splat.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree_plugin.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 371c5538c789..9b7f8c8ca355 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -1938,7 +1938,8 @@ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu)
rhp = ACCESS_ONCE(rdp->nocb_follower_head);
/* Having no rcuo kthread but CBs after scheduler starts is bad! */
- if (!ACCESS_ONCE(rdp->nocb_kthread) && rhp) {
+ if (!ACCESS_ONCE(rdp->nocb_kthread) && rhp &&
+ rcu_scheduler_fully_active) {
/* RCU callback enqueued before CPU first came online??? */
pr_err("RCU: Never-onlined no-CBs CPU %d has CB %p\n",
cpu, rhp->func);
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH RFC tip/core/rcu 5/7] rcu: Avoid clobbering early boot callbacks
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
` (2 preceding siblings ...)
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 4/7] rcu: Refine diagnostics for lacking kthread for no-CBs callbacks Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 6/7] rcu: Move early-boot callbacks to no-CBs lists for no-CBs CPUs Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 7/7] rcu: Move early boot callback tests earlier Paul E. McKenney
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
When a CPU comes online, it initializes its callback list. This
is a bad thing if this is the first time that the CPU has come
online and if that CPU has early boot callbacks. This commit therefore
avoid initializing the callback list if there are callbacks present,
in which case the initial call_rcu() did the initialization for us.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index ff2e42ebb64b..02fa29a4d104 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3584,7 +3584,8 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp)
rdp->qlen_last_fqs_check = 0;
rdp->n_force_qs_snap = rsp->n_force_qs;
rdp->blimit = blimit;
- init_callback_list(rdp); /* Re-enable callbacks on this CPU. */
+ if (!rdp->nxtlist)
+ init_callback_list(rdp); /* Re-enable callbacks on this CPU. */
rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
rcu_sysidle_init_percpu_data(rdp->dynticks);
atomic_set(&rdp->dynticks->dynticks,
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH RFC tip/core/rcu 6/7] rcu: Move early-boot callbacks to no-CBs lists for no-CBs CPUs
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
` (3 preceding siblings ...)
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 5/7] rcu: Avoid clobbering early boot callbacks Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 7/7] rcu: Move early boot callback tests earlier Paul E. McKenney
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
When a CPU is first determined to be a no-CBs CPUs, this commit causes
any early boot callbacks to be moved to the no-CBs callback list,
allowing them t obe invoked.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 1 +
kernel/rcu/tree_plugin.h | 24 ++++++++++++------------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 02fa29a4d104..c5241cdd4daf 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2852,6 +2852,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
* and then drop through to queue the callback.
*/
BUG_ON(cpu != -1);
+ WARN_ON_ONCE(!rcu_is_watching());
if (!likely(rdp->nxtlist))
init_default_callback_list(rdp);
}
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 9b7f8c8ca355..bb947ef1a2a4 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2386,18 +2386,8 @@ void __init rcu_init_nohz(void)
pr_info("\tPoll for callbacks from no-CBs CPUs.\n");
for_each_rcu_flavor(rsp) {
- for_each_cpu(cpu, rcu_nocb_mask) {
- struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-
- /*
- * If there are early callbacks, they will need
- * to be moved to the nocb lists.
- */
- WARN_ON_ONCE(rdp->nxttail[RCU_NEXT_TAIL] !=
- &rdp->nxtlist &&
- rdp->nxttail[RCU_NEXT_TAIL] != NULL);
- init_nocb_callback_list(rdp);
- }
+ for_each_cpu(cpu, rcu_nocb_mask)
+ init_nocb_callback_list(per_cpu_ptr(rsp->rda, cpu));
rcu_organize_nocb_kthreads(rsp);
}
}
@@ -2534,6 +2524,16 @@ static bool init_nocb_callback_list(struct rcu_data *rdp)
if (!rcu_is_nocb_cpu(rdp->cpu))
return false;
+ /* If there are early-boot callbacks, move them to nocb lists. */
+ if (rdp->nxtlist) {
+ rdp->nocb_head = rdp->nxtlist;
+ rdp->nocb_tail = rdp->nxttail[RCU_NEXT_TAIL];
+ atomic_long_set(&rdp->nocb_q_count, rdp->qlen);
+ atomic_long_set(&rdp->nocb_q_count_lazy, rdp->qlen_lazy);
+ rdp->nxtlist = NULL;
+ rdp->qlen = 0;
+ rdp->qlen_lazy = 0;
+ }
rdp->nxttail[RCU_NEXT_TAIL] = NULL;
return true;
}
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH RFC tip/core/rcu 7/7] rcu: Move early boot callback tests earlier
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 1/7] rcu: Abstract default callback-list initialization from init_callback_list() Paul E. McKenney
` (4 preceding siblings ...)
2015-01-21 10:08 ` [PATCH RFC tip/core/rcu 6/7] rcu: Move early-boot callbacks to no-CBs lists for no-CBs CPUs Paul E. McKenney
@ 2015-01-21 10:08 ` Paul E. McKenney
5 siblings, 0 replies; 8+ messages in thread
From: Paul E. McKenney @ 2015-01-21 10:08 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, tglx,
peterz, rostedt, dhowells, edumazet, dvhart, fweisbec, oleg,
bobby.prani, Paul E. McKenney
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Because callbacks can now be posted quite early in boot, move the
early boot callback tests to precede RCU initialization.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index c5241cdd4daf..21f3d5007d77 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3920,6 +3920,8 @@ void __init rcu_init(void)
{
int cpu;
+ rcu_early_boot_tests();
+
rcu_bootup_announce();
rcu_init_geometry();
rcu_init_one(&rcu_bh_state, &rcu_bh_data);
@@ -3936,8 +3938,6 @@ void __init rcu_init(void)
pm_notifier(rcu_pm_notify, 0);
for_each_online_cpu(cpu)
rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
-
- rcu_early_boot_tests();
}
#include "tree_plugin.h"
--
1.8.1.5
^ permalink raw reply related [flat|nested] 8+ messages in thread