aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2013-02-10 23:48:58 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-03-26 11:04:44 -0400
commitdae6e64d2bcfd4b06304ab864c7e3a4f6b5fedf4 (patch)
tree79172d32aab5e0cecf8fc7ab4cf1fabf14328d81 /kernel/rcutree.c
parent911af505ef407c2511106c224dd640f882f0f590 (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.c6
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)
1364static void rcu_gp_cleanup(struct rcu_state *rsp) 1364static 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