diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-03-10 13:55:52 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-04-29 11:43:32 -0400 |
commit | 365187fbc04fd55766bf6a94e37e558505bf480a (patch) | |
tree | 6249491e31d2c9e6e1fdb62048694b28f0974d97 /kernel/rcu/tree.c | |
parent | 83ebe63ead0fe60e4b548730800cb68293ce098b (diff) |
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.c | 39 |
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) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * Return the root node of the specified rcu_state structure. | ||
328 | */ | ||
329 | static struct rcu_node *rcu_get_root(struct rcu_state *rsp) | ||
330 | { | ||
331 | return &rsp->node[0]; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * Is there any need for future grace periods? | ||
336 | * Interrupts must be disabled. If the caller does not hold the root | ||
337 | * rnp_node structure's ->lock, the results are advisory only. | ||
338 | */ | ||
339 | static int rcu_future_needs_gp(struct rcu_state *rsp) | ||
340 | { | ||
341 | struct rcu_node *rnp = rcu_get_root(rsp); | ||
342 | int idx = (ACCESS_ONCE(rnp->completed) + 1) & 0x1; | ||
343 | int *fp = &rnp->need_future_gp[idx]; | ||
344 | |||
345 | return ACCESS_ONCE(*fp); | ||
346 | } | ||
347 | |||
348 | /* | ||
327 | * Does the current CPU require a not-yet-started grace period? | 349 | * Does the current CPU require a not-yet-started grace period? |
328 | * The caller must have disabled interrupts to prevent races with | 350 | * The caller must have disabled interrupts to prevent races with |
329 | * normal callback registry. | 351 | * normal callback registry. |
@@ -335,7 +357,7 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) | |||
335 | 357 | ||
336 | if (rcu_gp_in_progress(rsp)) | 358 | if (rcu_gp_in_progress(rsp)) |
337 | return 0; /* No, a grace period is already in progress. */ | 359 | return 0; /* No, a grace period is already in progress. */ |
338 | if (rcu_nocb_needs_gp(rsp)) | 360 | if (rcu_future_needs_gp(rsp)) |
339 | return 1; /* Yes, a no-CBs CPU needs one. */ | 361 | return 1; /* Yes, a no-CBs CPU needs one. */ |
340 | if (!rdp->nxttail[RCU_NEXT_TAIL]) | 362 | if (!rdp->nxttail[RCU_NEXT_TAIL]) |
341 | return 0; /* No, this is a no-CBs (or offline) CPU. */ | 363 | 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) | |||
350 | } | 372 | } |
351 | 373 | ||
352 | /* | 374 | /* |
353 | * Return the root node of the specified rcu_state structure. | ||
354 | */ | ||
355 | static struct rcu_node *rcu_get_root(struct rcu_state *rsp) | ||
356 | { | ||
357 | return &rsp->node[0]; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | * rcu_eqs_enter_common - current CPU is moving towards extended quiescent state | 375 | * rcu_eqs_enter_common - current CPU is moving towards extended quiescent state |
362 | * | 376 | * |
363 | * If the new value of the ->dynticks_nesting counter now is zero, | 377 | * If the new value of the ->dynticks_nesting counter now is zero, |
@@ -1672,6 +1686,8 @@ static void rsp_wakeup(struct irq_work *work) | |||
1672 | 1686 | ||
1673 | /* Wake up rcu_gp_kthread() to start the grace period. */ | 1687 | /* Wake up rcu_gp_kthread() to start the grace period. */ |
1674 | wake_up(&rsp->gp_wq); | 1688 | wake_up(&rsp->gp_wq); |
1689 | trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum), | ||
1690 | "Workqueuewoken"); | ||
1675 | } | 1691 | } |
1676 | 1692 | ||
1677 | /* | 1693 | /* |
@@ -1706,8 +1722,11 @@ rcu_start_gp_advanced(struct rcu_state *rsp, struct rcu_node *rnp, | |||
1706 | * the wakeup to interrupt context. And don't bother waking | 1722 | * the wakeup to interrupt context. And don't bother waking |
1707 | * up the running kthread. | 1723 | * up the running kthread. |
1708 | */ | 1724 | */ |
1709 | if (current != rsp->gp_kthread) | 1725 | if (current != rsp->gp_kthread) { |
1726 | trace_rcu_grace_period(rsp->name, ACCESS_ONCE(rsp->gpnum), | ||
1727 | "Workqueuewake"); | ||
1710 | irq_work_queue(&rsp->wakeup_work); | 1728 | irq_work_queue(&rsp->wakeup_work); |
1729 | } | ||
1711 | } | 1730 | } |
1712 | 1731 | ||
1713 | /* | 1732 | /* |