summaryrefslogtreecommitdiffstats
path: root/kernel/rcu/tree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-03-10 18:55:52 +0100
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-04-29 17:43:32 +0200
commit365187fbc04fd55766bf6a94e37e558505bf480a (patch)
tree6249491e31d2c9e6e1fdb62048694b28f0974d97 /kernel/rcu/tree.c
parentrcu: Print negatives for stall-warning counter wraparound (diff)
downloadlinux-365187fbc04fd55766bf6a94e37e558505bf480a.tar.xz
linux-365187fbc04fd55766bf6a94e37e558505bf480a.zip
rcu: Update cpu_needs_another_gp() for futures from non-NOCB CPUs
In the old days, the only source of requests for future grace periods was NOCB CPUs. This has changed: CPUs routinely post requests for future grace periods in order to promote power efficiency and reduce OS jitter with minimal impact on grace-period latency. This commit therefore updates cpu_needs_another_gp() to invoke rcu_future_needs_gp() instead of rcu_nocb_needs_gp(). The latter is no longer used, so is now removed. This commit also adds tracing for the irq_work_queue() wakeup case. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r--kernel/rcu/tree.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index b33c29a99df3..b4688993e956 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -324,6 +324,28 @@ cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
}
/*
+ * Return the root node of the specified rcu_state structure.
+ */
+static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
+{
+ return &rsp->node[0];
+}
+
+/*
+ * Is there any need for future grace periods?
+ * Interrupts must be disabled. If the caller does not hold the root
+ * rnp_node structure's ->lock, the results are advisory only.
+ */
+static int rcu_future_needs_gp(struct rcu_state *rsp)
+{
+ struct rcu_node *rnp = rcu_get_root(rsp);
+ int idx = (ACCESS_ONCE(rnp->completed) + 1) & 0x1;
+ int *fp = &rnp->need_future_gp[idx];
+
+ return ACCESS_ONCE(*fp);
+}
+
+/*
* Does the current CPU require a not-yet-started grace period?
* The caller must have disabled interrupts to prevent races with
* normal callback registry.
@@ -335,7 +357,7 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
if (rcu_gp_in_progress(rsp))
return 0; /* No, a grace period is already in progress. */
- if (rcu_nocb_needs_gp(rsp))
+ if (rcu_future_needs_gp(rsp))
return 1; /* Yes, a no-CBs CPU needs one. */
if (!rdp->nxttail[RCU_NEXT_TAIL])
return 0; /* No, this is a no-CBs (or offline) CPU. */
@@ -350,14 +372,6 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
}
/*
- * Return the root node of the specified rcu_state structure.
- */
-static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
-{
- return &rsp->node[0];
-}
-
-/*
* rcu_eqs_enter_common - current CPU is moving towards extended quiescent state
*
* If the new value of the ->dynticks_nesting counter now is zero,
@@ -1672,6 +1686,8 @@ static void rsp_wakeup(struct irq_work *work)
/* Wake up rcu_gp_kthread() to start the grace period. */
wake_up(&rsp->gp_wq);
+ trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum),
+ "Workqueuewoken");
}
/*
@@ -1706,8 +1722,11 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp,
* the wakeup to interrupt context. And don't bother waking
* up the running kthread.
*/
- if (current != rsp->gp_kthread)
+ if (current != rsp->gp_kthread) {
+ trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum),
+ "Workqueuewake");
irq_work_queue(&rsp->wakeup_work);
+ }
}
/*