* [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19
@ 2018-06-25 23:04 Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 1/5] rcu: Add debugging info to assertion Paul E. McKenney
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel
Hello!
The following miscellaneous fixes come before the infamous ->gp_seq
conversion:
1. Add debugging info to the assertion detecting tasks queued on
the ->blkd_tasks list at unexpected times.
2. Use the proper lockdep annotation in dump_blkd_tasks(), courtesy
of Boqun Feng.
3. Exclude near-simultaneous RCU CPU stall warnings, thus reducing
the probability of interleaved (and thus inscrutable) warnings.
4. Add diagnostics for failure to respond to a request for a new
grace period.
5. Make rcu_gp_cleanup() write only once to ->gp_flags.
Thanx, Paul
------------------------------------------------------------------------
tree.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++------------
tree.h | 4 ++
tree_plugin.h | 40 ++++++++++++++++++++++-
3 files changed, 119 insertions(+), 22 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH tip/core/rcu 1/5] rcu: Add debugging info to assertion
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
@ 2018-06-25 23:04 ` Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 2/5] rcu: Use the proper lockdep annotation in dump_blkd_tasks() Paul E. McKenney
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel,
Paul E. McKenney
The WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp()) in
rcu_gp_cleanup() triggers (inexplicably, of course) every so often.
This commit therefore extracts more information.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 5 ++++-
kernel/rcu/tree.h | 2 ++
kernel/rcu/tree_plugin.h | 38 ++++++++++++++++++++++++++++++++++++--
3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index aa7cade1b9f3..79c7fe978b17 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2084,7 +2084,8 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
*/
rcu_for_each_node_breadth_first(rsp, rnp) {
raw_spin_lock_irq_rcu_node(rnp);
- WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp));
+ if (WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp)))
+ dump_blkd_tasks(rnp, 10);
WARN_ON_ONCE(rnp->qsmask);
WRITE_ONCE(rnp->completed, rsp->gpnum);
rdp = this_cpu_ptr(rsp->rda);
@@ -2294,6 +2295,7 @@ rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
return;
}
+ rnp->completedqs = rnp->gpnum;
mask = rnp->grpmask;
if (rnp->parent == NULL) {
@@ -3930,6 +3932,7 @@ static void __init rcu_init_one(struct rcu_state *rsp)
&rcu_fqs_class[i], fqs[i]);
rnp->gpnum = rsp->gpnum;
rnp->completed = rsp->completed;
+ rnp->completedqs = rsp->completed;
rnp->qsmask = 0;
rnp->qsmaskinit = 0;
rnp->grplo = j * cpustride;
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 78e051dffc5b..7365ac53fdd9 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -87,6 +87,7 @@ struct rcu_node {
unsigned long completed; /* Last GP completed for this node. */
/* This will either be equal to or one */
/* behind the root rcu_node's gpnum. */
+ unsigned long completedqs; /* All QSes done for this node. */
unsigned long qsmask; /* CPUs or groups that need to switch in */
/* order for current grace period to proceed.*/
/* In leaf rcu_node, each bit corresponds to */
@@ -453,6 +454,7 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
static void rcu_preempt_check_callbacks(void);
void call_rcu(struct rcu_head *head, rcu_callback_t func);
static void __init __rcu_init_preempt(void);
+static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck);
static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);
static void invoke_rcu_callbacks_kthread(void);
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 7fd12039e512..17b67ecf7dff 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -260,8 +260,10 @@ static void rcu_preempt_ctxt_queue(struct rcu_node *rnp, struct rcu_data *rdp)
* ->exp_tasks pointers, respectively, to reference the newly
* blocked tasks.
*/
- if (!rnp->gp_tasks && (blkd_state & RCU_GP_BLKD))
+ if (!rnp->gp_tasks && (blkd_state & RCU_GP_BLKD)) {
rnp->gp_tasks = &t->rcu_node_entry;
+ WARN_ON_ONCE(rnp->completedqs == rnp->gpnum);
+ }
if (!rnp->exp_tasks && (blkd_state & RCU_EXP_BLKD))
rnp->exp_tasks = &t->rcu_node_entry;
WARN_ON_ONCE(!(blkd_state & RCU_GP_BLKD) !=
@@ -535,6 +537,8 @@ void rcu_read_unlock_special(struct task_struct *t)
WARN_ON_ONCE(rnp != t->rcu_blocked_node);
WARN_ON_ONCE(!rcu_is_leaf_node(rnp));
empty_norm = !rcu_preempt_blocked_readers_cgp(rnp);
+ WARN_ON_ONCE(rnp->completedqs == rnp->gpnum &&
+ (!empty_norm || rnp->qsmask));
empty_exp = sync_rcu_preempt_exp_done(rnp);
smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
np = rcu_next_node_entry(t, rnp);
@@ -697,7 +701,8 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
struct task_struct *t;
RCU_LOCKDEP_WARN(preemptible(), "rcu_preempt_check_blocked_tasks() invoked with preemption enabled!!!\n");
- WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp));
+ if (WARN_ON_ONCE(rcu_preempt_blocked_readers_cgp(rnp)))
+ dump_blkd_tasks(rnp, 10);
if (rcu_preempt_has_tasks(rnp)) {
rnp->gp_tasks = rnp->blkd_tasks.next;
t = container_of(rnp->gp_tasks, struct task_struct,
@@ -841,6 +846,27 @@ void exit_rcu(void)
__rcu_read_unlock();
}
+/*
+ * Dump the blocked-tasks state, but limit the list dump to the
+ * specified number of elements.
+ */
+static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
+{
+ int i;
+ struct list_head *lhp;
+
+ lockdep_assert_held(&rnp->lock);
+ pr_info("%s: grp: %d-%d level: %d ->qamask %#lx ->gp_tasks %p ->boost_tasks %p ->exp_tasks %p &->blkd_tasks: %p offset: %u\n", __func__, rnp->grplo, rnp->grphi, rnp->level, rnp->qsmask, rnp->gp_tasks, rnp->boost_tasks, rnp->exp_tasks, &rnp->blkd_tasks, (unsigned int)offsetof(typeof(*rnp), blkd_tasks));
+ pr_cont("\t->blkd_tasks");
+ i = 0;
+ list_for_each(lhp, &rnp->blkd_tasks) {
+ pr_cont(" %p", lhp);
+ if (++i >= 10)
+ break;
+ }
+ pr_cont("\n");
+}
+
#else /* #ifdef CONFIG_PREEMPT_RCU */
static struct rcu_state *const rcu_state_p = &rcu_sched_state;
@@ -949,6 +975,14 @@ void exit_rcu(void)
{
}
+/*
+ * Dump the guaranteed-empty blocked-tasks state. Trust but verify.
+ */
+static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
+{
+ WARN_ON_ONCE(!list_empty(&rnp->blkd_tasks));
+}
+
#endif /* #else #ifdef CONFIG_PREEMPT_RCU */
#ifdef CONFIG_RCU_BOOST
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH tip/core/rcu 2/5] rcu: Use the proper lockdep annotation in dump_blkd_tasks()
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 1/5] rcu: Add debugging info to assertion Paul E. McKenney
@ 2018-06-25 23:04 ` Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 3/5] rcu: Exclude near-simultaneous RCU CPU stall warnings Paul E. McKenney
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel,
Boqun Feng, Paul E . McKenney
From: Boqun Feng <boqun.feng@gmail.com>
Sparse reported this:
| kernel/rcu/tree_plugin.h:814:9: warning: incorrect type in argument 1 (different modifiers)
| kernel/rcu/tree_plugin.h:814:9: expected struct lockdep_map const *lock
| kernel/rcu/tree_plugin.h:814:9: got struct lockdep_map [noderef] *<noident>
This is caused by using vanilla lockdep annotations on rcu_node::lock,
and that requires accessing ->lock of rcu_node directly. However we need
to keep rcu_node::lock __private to avoid breaking its extra ordering
guarantee. And we have a dedicated lockdep annotation for
rcu_node::lock, so use it.
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree_plugin.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 17b67ecf7dff..e387ea712758 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -855,7 +855,7 @@ static void dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
int i;
struct list_head *lhp;
- lockdep_assert_held(&rnp->lock);
+ raw_lockdep_assert_held_rcu_node(rnp);
pr_info("%s: grp: %d-%d level: %d ->qamask %#lx ->gp_tasks %p ->boost_tasks %p ->exp_tasks %p &->blkd_tasks: %p offset: %u\n", __func__, rnp->grplo, rnp->grphi, rnp->level, rnp->qsmask, rnp->gp_tasks, rnp->boost_tasks, rnp->exp_tasks, &rnp->blkd_tasks, (unsigned int)offsetof(typeof(*rnp), blkd_tasks));
pr_cont("\t->blkd_tasks");
i = 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH tip/core/rcu 3/5] rcu: Exclude near-simultaneous RCU CPU stall warnings
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 1/5] rcu: Add debugging info to assertion Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 2/5] rcu: Use the proper lockdep annotation in dump_blkd_tasks() Paul E. McKenney
@ 2018-06-25 23:04 ` Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 4/5] rcu: Diagnostics for grace-period hangs Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 5/5] rcu: Make rcu_gp_cleanup() write only once to ->gp_flags Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel,
Paul E. McKenney
There is a two-jiffy delay between the time that a CPU will self-report
an RCU CPU stall warning and the time that some other CPU will report a
warning on behalf of the first CPU. This has worked well in the past,
but on busy systems, it is possible for the two warnings to overlap,
which makes interpreting them extremely difficult.
This commit therefore uses a cmpxchg-based timing decision that
allows only one report in a given one-minute period (assuming default
stall-warning Kconfig parameters). This approach will of course fail
if you are seeing minute-long vCPU preemption, but in that case the
overlapping RCU CPU stall warnings are the least of your worries.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
---
kernel/rcu/tree.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 79c7fe978b17..b1fffa21b9e4 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1368,7 +1368,6 @@ static inline void panic_on_rcu_stall(void)
static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
{
int cpu;
- long delta;
unsigned long flags;
unsigned long gpa;
unsigned long j;
@@ -1381,18 +1380,6 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
if (rcu_cpu_stall_suppress)
return;
- /* Only let one CPU complain about others per time interval. */
-
- raw_spin_lock_irqsave_rcu_node(rnp, flags);
- delta = jiffies - READ_ONCE(rsp->jiffies_stall);
- if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
- raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
- return;
- }
- WRITE_ONCE(rsp->jiffies_stall,
- jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
- raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
-
/*
* OK, time to rat on our buddy...
* See Documentation/RCU/stallwarn.txt for info on how to debug
@@ -1441,6 +1428,10 @@ static void print_other_cpu_stall(struct rcu_state *rsp, unsigned long gpnum)
sched_show_task(current);
}
}
+ /* Rewrite if needed in case of slow consoles. */
+ if (ULONG_CMP_GE(jiffies, READ_ONCE(rsp->jiffies_stall)))
+ WRITE_ONCE(rsp->jiffies_stall,
+ jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
rcu_check_gp_kthread_starvation(rsp);
@@ -1485,6 +1476,7 @@ static void print_cpu_stall(struct rcu_state *rsp)
rcu_dump_cpu_stacks(rsp);
raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ /* Rewrite if needed in case of slow consoles. */
if (ULONG_CMP_GE(jiffies, READ_ONCE(rsp->jiffies_stall)))
WRITE_ONCE(rsp->jiffies_stall,
jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
@@ -1508,6 +1500,7 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
unsigned long gpnum;
unsigned long gps;
unsigned long j;
+ unsigned long jn;
unsigned long js;
struct rcu_node *rnp;
@@ -1546,14 +1539,17 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
ULONG_CMP_GE(gps, js))
return; /* No stall or GP completed since entering function. */
rnp = rdp->mynode;
+ jn = jiffies + 3 * rcu_jiffies_till_stall_check() + 3;
if (rcu_gp_in_progress(rsp) &&
- (READ_ONCE(rnp->qsmask) & rdp->grpmask)) {
+ (READ_ONCE(rnp->qsmask) & rdp->grpmask) &&
+ cmpxchg(&rsp->jiffies_stall, js, jn) == js) {
/* We haven't checked in, so go dump stack. */
print_cpu_stall(rsp);
} else if (rcu_gp_in_progress(rsp) &&
- ULONG_CMP_GE(j, js + RCU_STALL_RAT_DELAY)) {
+ ULONG_CMP_GE(j, js + RCU_STALL_RAT_DELAY) &&
+ cmpxchg(&rsp->jiffies_stall, js, jn) == js) {
/* They had a few time units to dump stack, so complain. */
print_other_cpu_stall(rsp, gpnum);
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH tip/core/rcu 4/5] rcu: Diagnostics for grace-period hangs
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
` (2 preceding siblings ...)
2018-06-25 23:04 ` [PATCH tip/core/rcu 3/5] rcu: Exclude near-simultaneous RCU CPU stall warnings Paul E. McKenney
@ 2018-06-25 23:04 ` Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 5/5] rcu: Make rcu_gp_cleanup() write only once to ->gp_flags Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel,
Paul E. McKenney
This commit causes a splat if RCU is idle and a request for a new grace
period is ignored for more than one second. This splat normally indicates
that some code path asked for a new grace period, but failed to wake up
the RCU grace-period kthread.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
[ paulmck: Fix bug located by Dan Carpenter and his static checker. ]
---
kernel/rcu/tree.c | 63 +++++++++++++++++++++++++++++++++++++++++++++--
kernel/rcu/tree.h | 2 ++
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index b1fffa21b9e4..fae4df831e52 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1681,6 +1681,7 @@ static bool rcu_start_this_gp(struct rcu_node *rnp, struct rcu_data *rdp,
}
trace_rcu_this_gp(rnp_root, rdp, c, TPS("Startedroot"));
WRITE_ONCE(rsp->gp_flags, rsp->gp_flags | RCU_GP_FLAG_INIT);
+ rsp->gp_req_activity = jiffies;
if (!rsp->gp_kthread) {
trace_rcu_this_gp(rnp_root, rdp, c, TPS("NoGPkthread"));
goto unlock_out;
@@ -2113,6 +2114,7 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
/* Advance CBs to reduce false positives below. */
if (!rcu_accelerate_cbs(rsp, rnp, rdp) && needgp) {
WRITE_ONCE(rsp->gp_flags, RCU_GP_FLAG_INIT);
+ rsp->gp_req_activity = jiffies;
trace_rcu_grace_period(rsp->name, READ_ONCE(rsp->gpnum),
TPS("newreq"));
}
@@ -2744,6 +2746,62 @@ static void force_quiescent_state(struct rcu_state *rsp)
rcu_gp_kthread_wake(rsp);
}
+/*
+ * This function checks for grace-period requests that fail to motivate
+ * RCU to come out of its idle mode.
+ */
+static void
+rcu_check_gp_start_stall(struct rcu_state *rsp, struct rcu_node *rnp,
+ struct rcu_data *rdp)
+{
+ unsigned long flags;
+ unsigned long j;
+ struct rcu_node *rnp_root = rcu_get_root(rsp);
+ static atomic_t warned = ATOMIC_INIT(0);
+
+ if (rcu_gp_in_progress(rsp) || !need_any_future_gp(rcu_get_root(rsp)))
+ return;
+ j = jiffies; /* Expensive access, and in common case don't get here. */
+ if (time_before(j, READ_ONCE(rsp->gp_req_activity) + HZ) ||
+ time_before(j, READ_ONCE(rsp->gp_activity) + HZ) ||
+ atomic_read(&warned))
+ return;
+
+ raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ j = jiffies;
+ if (rcu_gp_in_progress(rsp) || !need_any_future_gp(rcu_get_root(rsp)) ||
+ time_before(j, READ_ONCE(rsp->gp_req_activity) + HZ) ||
+ time_before(j, READ_ONCE(rsp->gp_activity) + HZ) ||
+ atomic_read(&warned)) {
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ return;
+ }
+ /* Hold onto the leaf lock to make others see warned==1. */
+
+ raw_spin_lock_rcu_node(rnp_root); /* irqs already disabled. */
+ j = jiffies;
+ if (rcu_gp_in_progress(rsp) || !need_any_future_gp(rcu_get_root(rsp)) ||
+ time_before(j, rsp->gp_req_activity + HZ) ||
+ time_before(j, rsp->gp_activity + HZ) ||
+ atomic_xchg(&warned, 1)) {
+ raw_spin_unlock_rcu_node(rnp_root); /* irqs remain disabled. */
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ return;
+ }
+ pr_alert("%s: g%lu %d%d%d%d gar:%lu ga:%lu f%#x %s->state:%#lx\n",
+ __func__, READ_ONCE(rsp->gpnum),
+ need_future_gp_element(rcu_get_root(rsp), 0),
+ need_future_gp_element(rcu_get_root(rsp), 1),
+ need_future_gp_element(rcu_get_root(rsp), 2),
+ need_future_gp_element(rcu_get_root(rsp), 3),
+ j - rsp->gp_req_activity, j - rsp->gp_activity,
+ rsp->gp_flags, rsp->name,
+ rsp->gp_kthread ? rsp->gp_kthread->state : 0x1ffffL);
+ WARN_ON(1);
+ raw_spin_unlock_rcu_node(rnp_root);
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+}
+
/*
* This does the RCU core processing work for the specified rcu_state
* and rcu_data structures. This may be called only from the CPU to
@@ -2755,7 +2813,7 @@ __rcu_process_callbacks(struct rcu_state *rsp)
unsigned long flags;
bool needwake;
struct rcu_data *rdp = raw_cpu_ptr(rsp->rda);
- struct rcu_node *rnp;
+ struct rcu_node *rnp = rdp->mynode;
WARN_ON_ONCE(!rdp->beenonline);
@@ -2769,7 +2827,6 @@ __rcu_process_callbacks(struct rcu_state *rsp)
if (rcu_segcblist_restempty(&rdp->cblist, RCU_NEXT_READY_TAIL)) {
local_irq_restore(flags);
} else {
- rnp = rdp->mynode;
raw_spin_lock_rcu_node(rnp); /* irqs disabled. */
needwake = rcu_accelerate_cbs(rsp, rnp, rdp);
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
@@ -2778,6 +2835,8 @@ __rcu_process_callbacks(struct rcu_state *rsp)
}
}
+ rcu_check_gp_start_stall(rsp, rnp, rdp);
+
/* If there are callbacks ready, invoke them. */
if (rcu_segcblist_ready_cbs(&rdp->cblist))
invoke_rcu_callbacks(rsp, rdp);
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 7365ac53fdd9..3c1942174c56 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -374,6 +374,8 @@ struct rcu_state {
/* but in jiffies. */
unsigned long gp_activity; /* Time of last GP kthread */
/* activity in jiffies. */
+ unsigned long gp_req_activity; /* Time of last GP request */
+ /* in jiffies. */
unsigned long jiffies_stall; /* Time at which to check */
/* for CPU stalls. */
unsigned long jiffies_resched; /* Time at which to resched */
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH tip/core/rcu 5/5] rcu: Make rcu_gp_cleanup() write only once to ->gp_flags
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
` (3 preceding siblings ...)
2018-06-25 23:04 ` [PATCH tip/core/rcu 4/5] rcu: Diagnostics for grace-period hangs Paul E. McKenney
@ 2018-06-25 23:04 ` Paul E. McKenney
4 siblings, 0 replies; 6+ messages in thread
From: Paul E. McKenney @ 2018-06-25 23:04 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, jiangshanlai, dipankar, akpm, mathieu.desnoyers, josh,
tglx, peterz, rostedt, dhowells, edumazet, fweisbec, oleg, joel,
Paul E. McKenney
At the end of rcu_gp_cleanup(), if another grace period is needed, but
not via rcu_accelerate_cbs(), the ->gp_flags field is written twice,
once when making the new grace-period request, and once when clearing
all other types of requests. This commit therefore adds an else-clause
to avoid this double write.
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 fae4df831e52..2db3475c2924 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2117,8 +2117,9 @@ static void rcu_gp_cleanup(struct rcu_state *rsp)
rsp->gp_req_activity = jiffies;
trace_rcu_grace_period(rsp->name, READ_ONCE(rsp->gpnum),
TPS("newreq"));
+ } else {
+ WRITE_ONCE(rsp->gp_flags, rsp->gp_flags & RCU_GP_FLAG_INIT);
}
- WRITE_ONCE(rsp->gp_flags, rsp->gp_flags & RCU_GP_FLAG_INIT);
raw_spin_unlock_irq_rcu_node(rnp);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-06-25 23:03 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-25 23:04 [PATCH tip/core/rcu 0/5] Pre-gp_seq miscellaneous fixes for v4.19 Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 1/5] rcu: Add debugging info to assertion Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 2/5] rcu: Use the proper lockdep annotation in dump_blkd_tasks() Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 3/5] rcu: Exclude near-simultaneous RCU CPU stall warnings Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 4/5] rcu: Diagnostics for grace-period hangs Paul E. McKenney
2018-06-25 23:04 ` [PATCH tip/core/rcu 5/5] rcu: Make rcu_gp_cleanup() write only once to ->gp_flags Paul E. McKenney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox