diff options
| author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2018-04-12 19:29:13 -0400 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2018-05-15 13:30:59 -0400 |
| commit | c1935209df8c903fc3a33143223338826fa54bd1 (patch) | |
| tree | d60d6f9ac8350e6e3e5866ca7951387a5d4d4d48 /kernel | |
| parent | 384f77f4cb765707216ea43f9122580d8a07be7d (diff) | |
rcu: Simplify and inline cpu_needs_another_gp()
Now that RCU no longer relies on failsafe checks, cpu_needs_another_gp()
can be greatly simplified. This simplification eliminates the last
call to rcu_future_needs_gp() and to rcu_segcblist_future_gp_needed(),
both of which which can then be eliminated. And then, because
cpu_needs_another_gp() is called only from __rcu_pending(), it can be
inlined and eliminated.
This commit carries out the simplification, inlining, and elimination
called out above.
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Nicholas Piggin <npiggin@gmail.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/rcu/rcu_segcblist.c | 18 | ||||
| -rw-r--r-- | kernel/rcu/rcu_segcblist.h | 2 | ||||
| -rw-r--r-- | kernel/rcu/tree.c | 40 |
3 files changed, 3 insertions, 57 deletions
diff --git a/kernel/rcu/rcu_segcblist.c b/kernel/rcu/rcu_segcblist.c index 88cba7c2956c..5aff271adf1e 100644 --- a/kernel/rcu/rcu_segcblist.c +++ b/kernel/rcu/rcu_segcblist.c | |||
| @@ -404,24 +404,6 @@ bool rcu_segcblist_accelerate(struct rcu_segcblist *rsclp, unsigned long seq) | |||
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | /* | 406 | /* |
| 407 | * Scan the specified rcu_segcblist structure for callbacks that need | ||
| 408 | * a grace period later than the one specified by "seq". We don't look | ||
| 409 | * at the RCU_DONE_TAIL or RCU_NEXT_TAIL segments because they don't | ||
| 410 | * have a grace-period sequence number. | ||
| 411 | */ | ||
| 412 | bool rcu_segcblist_future_gp_needed(struct rcu_segcblist *rsclp, | ||
| 413 | unsigned long seq) | ||
| 414 | { | ||
| 415 | int i; | ||
| 416 | |||
| 417 | for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++) | ||
| 418 | if (rsclp->tails[i - 1] != rsclp->tails[i] && | ||
| 419 | ULONG_CMP_LT(seq, rsclp->gp_seq[i])) | ||
| 420 | return true; | ||
| 421 | return false; | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * Merge the source rcu_segcblist structure into the destination | 407 | * Merge the source rcu_segcblist structure into the destination |
| 426 | * rcu_segcblist structure, then initialize the source. Any pending | 408 | * rcu_segcblist structure, then initialize the source. Any pending |
| 427 | * callbacks from the source get to start over. It is best to | 409 | * callbacks from the source get to start over. It is best to |
diff --git a/kernel/rcu/rcu_segcblist.h b/kernel/rcu/rcu_segcblist.h index 581c12b63544..948470cef385 100644 --- a/kernel/rcu/rcu_segcblist.h +++ b/kernel/rcu/rcu_segcblist.h | |||
| @@ -134,7 +134,5 @@ void rcu_segcblist_insert_pend_cbs(struct rcu_segcblist *rsclp, | |||
| 134 | struct rcu_cblist *rclp); | 134 | struct rcu_cblist *rclp); |
| 135 | void rcu_segcblist_advance(struct rcu_segcblist *rsclp, unsigned long seq); | 135 | void rcu_segcblist_advance(struct rcu_segcblist *rsclp, unsigned long seq); |
| 136 | bool rcu_segcblist_accelerate(struct rcu_segcblist *rsclp, unsigned long seq); | 136 | bool rcu_segcblist_accelerate(struct rcu_segcblist *rsclp, unsigned long seq); |
| 137 | bool rcu_segcblist_future_gp_needed(struct rcu_segcblist *rsclp, | ||
| 138 | unsigned long seq); | ||
| 139 | void rcu_segcblist_merge(struct rcu_segcblist *dst_rsclp, | 137 | void rcu_segcblist_merge(struct rcu_segcblist *dst_rsclp, |
| 140 | struct rcu_segcblist *src_rsclp); | 138 | struct rcu_segcblist *src_rsclp); |
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 7776d709e060..020a0fe2dbee 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -709,42 +709,6 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp) | |||
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | /* | 711 | /* |
| 712 | * Is there any need for future grace periods? | ||
| 713 | * Interrupts must be disabled. If the caller does not hold the root | ||
| 714 | * rnp_node structure's ->lock, the results are advisory only. | ||
| 715 | */ | ||
| 716 | static int rcu_future_needs_gp(struct rcu_state *rsp) | ||
| 717 | { | ||
| 718 | struct rcu_node *rnp = rcu_get_root(rsp); | ||
| 719 | |||
| 720 | lockdep_assert_irqs_disabled(); | ||
| 721 | return need_any_future_gp(rnp); | ||
| 722 | } | ||
| 723 | |||
| 724 | /* | ||
| 725 | * Does the current CPU require a not-yet-started grace period? | ||
| 726 | * The caller must have disabled interrupts to prevent races with | ||
| 727 | * normal callback registry. | ||
| 728 | */ | ||
| 729 | static bool | ||
| 730 | cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) | ||
| 731 | { | ||
| 732 | lockdep_assert_irqs_disabled(); | ||
| 733 | if (rcu_gp_in_progress(rsp)) | ||
| 734 | return false; /* No, a grace period is already in progress. */ | ||
| 735 | if (rcu_future_needs_gp(rsp)) | ||
| 736 | return true; /* Yes, a no-CBs CPU needs one. */ | ||
| 737 | if (!rcu_segcblist_is_enabled(&rdp->cblist)) | ||
| 738 | return false; /* No, this is a no-CBs (or offline) CPU. */ | ||
| 739 | if (!rcu_segcblist_restempty(&rdp->cblist, RCU_NEXT_READY_TAIL)) | ||
| 740 | return true; /* Yes, CPU has newly registered callbacks. */ | ||
| 741 | if (rcu_segcblist_future_gp_needed(&rdp->cblist, | ||
| 742 | READ_ONCE(rsp->completed))) | ||
| 743 | return true; /* Yes, CBs for future grace period. */ | ||
| 744 | return false; /* No grace period needed. */ | ||
| 745 | } | ||
| 746 | |||
| 747 | /* | ||
| 748 | * Enter an RCU extended quiescent state, which can be either the | 712 | * Enter an RCU extended quiescent state, which can be either the |
| 749 | * idle loop or adaptive-tickless usermode execution. | 713 | * idle loop or adaptive-tickless usermode execution. |
| 750 | * | 714 | * |
| @@ -3298,7 +3262,9 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp) | |||
| 3298 | return 1; | 3262 | return 1; |
| 3299 | 3263 | ||
| 3300 | /* Has RCU gone idle with this CPU needing another grace period? */ | 3264 | /* Has RCU gone idle with this CPU needing another grace period? */ |
| 3301 | if (cpu_needs_another_gp(rsp, rdp)) | 3265 | if (!rcu_gp_in_progress(rsp) && |
| 3266 | rcu_segcblist_is_enabled(&rdp->cblist) && | ||
| 3267 | !rcu_segcblist_restempty(&rdp->cblist, RCU_NEXT_READY_TAIL)) | ||
| 3302 | return 1; | 3268 | return 1; |
| 3303 | 3269 | ||
| 3304 | /* Has another RCU grace period completed? */ | 3270 | /* Has another RCU grace period completed? */ |
