aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul E. McKenney <paul.mckenney@linaro.org>2011-11-29 18:57:13 -0500
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-12-11 13:32:09 -0500
commitdff1672d9199fffddb58fa7970ccf59005fc35f3 (patch)
treea9740f65dfc203d183cb06ce0faeed0de5cef58b
parentfacc4e159672b4ed10aa18147bfa187b013c9505 (diff)
rcu: Keep invoking callbacks if CPU otherwise idle
The rcu_do_batch() function that invokes callbacks for TREE_RCU and TREE_PREEMPT_RCU normally throttles callback invocation to avoid degrading scheduling latency. However, as long as the CPU would otherwise be idle, there is no downside to continuing to invoke any callbacks that have passed through their grace periods. In fact, processing such callbacks in a timely manner has the benefit of increasing the probability that the CPU can enter the power-saving dyntick-idle mode. Therefore, this commit allows callback invocation to continue beyond the preset limit as long as the scheduler does not have some other task to run and as long as context is that of the idle task or the relevant RCU kthread. Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-rw-r--r--kernel/rcutree.c5
-rw-r--r--kernel/rcutree.h1
-rw-r--r--kernel/rcutree_plugin.h14
3 files changed, 19 insertions, 1 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index c0ed3765ec39..4ec4b14cfba6 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -1403,7 +1403,10 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
1403 debug_rcu_head_unqueue(list); 1403 debug_rcu_head_unqueue(list);
1404 __rcu_reclaim(rsp->name, list); 1404 __rcu_reclaim(rsp->name, list);
1405 list = next; 1405 list = next;
1406 if (++count >= bl) 1406 /* Stop only if limit reached and CPU has something to do. */
1407 if (++count >= bl &&
1408 (need_resched() ||
1409 (!is_idle_task(current) && !rcu_is_callbacks_kthread())))
1407 break; 1410 break;
1408 } 1411 }
1409 1412
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 9bcfbc9d16c6..fddff92d6676 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -455,6 +455,7 @@ static void __init __rcu_init_preempt(void);
455static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); 455static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
456static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); 456static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);
457static void invoke_rcu_callbacks_kthread(void); 457static void invoke_rcu_callbacks_kthread(void);
458static bool rcu_is_callbacks_kthread(void);
458#ifdef CONFIG_RCU_BOOST 459#ifdef CONFIG_RCU_BOOST
459static void rcu_preempt_do_callbacks(void); 460static void rcu_preempt_do_callbacks(void);
460static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, 461static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp,
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index dbcea6b93aea..adb6e666c6f4 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -1337,6 +1337,15 @@ static void invoke_rcu_callbacks_kthread(void)
1337} 1337}
1338 1338
1339/* 1339/*
1340 * Is the current CPU running the RCU-callbacks kthread?
1341 * Caller must have preemption disabled.
1342 */
1343static bool rcu_is_callbacks_kthread(void)
1344{
1345 return __get_cpu_var(rcu_cpu_kthread_task) == current;
1346}
1347
1348/*
1340 * Set the affinity of the boost kthread. The CPU-hotplug locks are 1349 * Set the affinity of the boost kthread. The CPU-hotplug locks are
1341 * held, so no one should be messing with the existence of the boost 1350 * held, so no one should be messing with the existence of the boost
1342 * kthread. 1351 * kthread.
@@ -1780,6 +1789,11 @@ static void invoke_rcu_callbacks_kthread(void)
1780 WARN_ON_ONCE(1); 1789 WARN_ON_ONCE(1);
1781} 1790}
1782 1791
1792static bool rcu_is_callbacks_kthread(void)
1793{
1794 return false;
1795}
1796
1783static void rcu_preempt_boost_start_gp(struct rcu_node *rnp) 1797static void rcu_preempt_boost_start_gp(struct rcu_node *rnp)
1784{ 1798{
1785} 1799}