diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2013-02-10 23:48:58 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2013-03-26 11:04:44 -0400 |
commit | dae6e64d2bcfd4b06304ab864c7e3a4f6b5fedf4 (patch) | |
tree | 79172d32aab5e0cecf8fc7ab4cf1fabf14328d81 /kernel/rcutree.c | |
parent | 911af505ef407c2511106c224dd640f882f0f590 (diff) |
rcu: Introduce proper blocking to no-CBs kthreads GP waits
Currently, the no-CBs kthreads do repeated timed waits for grace periods
to elapse. This is crude and energy inefficient, so this commit allows
no-CBs kthreads to specify exactly which grace period they are waiting
for and also allows them to block for the entire duration until the
desired grace period completes.
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r-- | kernel/rcutree.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 6ad0716e65dc..433f426c848f 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -310,7 +310,7 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) | |||
310 | 310 | ||
311 | if (rcu_gp_in_progress(rsp)) | 311 | if (rcu_gp_in_progress(rsp)) |
312 | return 0; /* No, a grace period is already in progress. */ | 312 | return 0; /* No, a grace period is already in progress. */ |
313 | if (rcu_nocb_needs_gp(rdp)) | 313 | if (rcu_nocb_needs_gp(rsp)) |
314 | return 1; /* Yes, a no-CBs CPU needs one. */ | 314 | return 1; /* Yes, a no-CBs CPU needs one. */ |
315 | if (!rdp->nxttail[RCU_NEXT_TAIL]) | 315 | if (!rdp->nxttail[RCU_NEXT_TAIL]) |
316 | return 0; /* No, this is a no-CBs (or offline) CPU. */ | 316 | return 0; /* No, this is a no-CBs (or offline) CPU. */ |
@@ -1364,6 +1364,7 @@ int rcu_gp_fqs(struct rcu_state *rsp, int fqs_state_in) | |||
1364 | static void rcu_gp_cleanup(struct rcu_state *rsp) | 1364 | static void rcu_gp_cleanup(struct rcu_state *rsp) |
1365 | { | 1365 | { |
1366 | unsigned long gp_duration; | 1366 | unsigned long gp_duration; |
1367 | int nocb = 0; | ||
1367 | struct rcu_data *rdp; | 1368 | struct rcu_data *rdp; |
1368 | struct rcu_node *rnp = rcu_get_root(rsp); | 1369 | struct rcu_node *rnp = rcu_get_root(rsp); |
1369 | 1370 | ||
@@ -1394,11 +1395,13 @@ static void rcu_gp_cleanup(struct rcu_state *rsp) | |||
1394 | rcu_for_each_node_breadth_first(rsp, rnp) { | 1395 | rcu_for_each_node_breadth_first(rsp, rnp) { |
1395 | raw_spin_lock_irq(&rnp->lock); | 1396 | raw_spin_lock_irq(&rnp->lock); |
1396 | rnp->completed = rsp->gpnum; | 1397 | rnp->completed = rsp->gpnum; |
1398 | nocb += rcu_nocb_gp_cleanup(rsp, rnp); | ||
1397 | raw_spin_unlock_irq(&rnp->lock); | 1399 | raw_spin_unlock_irq(&rnp->lock); |
1398 | cond_resched(); | 1400 | cond_resched(); |
1399 | } | 1401 | } |
1400 | rnp = rcu_get_root(rsp); | 1402 | rnp = rcu_get_root(rsp); |
1401 | raw_spin_lock_irq(&rnp->lock); | 1403 | raw_spin_lock_irq(&rnp->lock); |
1404 | rcu_nocb_gp_set(rnp, nocb); | ||
1402 | 1405 | ||
1403 | rsp->completed = rsp->gpnum; /* Declare grace period done. */ | 1406 | rsp->completed = rsp->gpnum; /* Declare grace period done. */ |
1404 | trace_rcu_grace_period(rsp->name, rsp->completed, "end"); | 1407 | trace_rcu_grace_period(rsp->name, rsp->completed, "end"); |
@@ -3084,6 +3087,7 @@ static void __init rcu_init_one(struct rcu_state *rsp, | |||
3084 | } | 3087 | } |
3085 | rnp->level = i; | 3088 | rnp->level = i; |
3086 | INIT_LIST_HEAD(&rnp->blkd_tasks); | 3089 | INIT_LIST_HEAD(&rnp->blkd_tasks); |
3090 | rcu_init_one_nocb(rnp); | ||
3087 | } | 3091 | } |
3088 | } | 3092 | } |
3089 | 3093 | ||