aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@alien8.de>2013-04-21 18:12:42 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2013-08-18 20:37:17 -0400
commitd1d74d14e98a6be740a6f12456c7d9ad47be9c9c (patch)
tree2a0d4f2b81e587ecbbc0362314a36ddec2ff64f2
parentf7f7bac9cb1c50783f15937a11743655a5756a36 (diff)
rcu: Expedite grace periods during suspend/resume
CONFIG_RCU_FAST_NO_HZ can increase grace-period durations by up to a factor of four, which can result in long suspend and resume times. Thus, this commit temporarily switches to expedited grace periods when suspending the box and return to normal settings when resuming. Similar logic is applied to hibernation. Because expedited grace periods are of dubious benefit on very large systems, so this commit restricts their automated use during suspend and resume to systems of 256 or fewer CPUs. (Some day a number of Linux-kernel facilities, including RCU's expedited grace periods, will be more scalable, but I need to see bug reports first.) [ paulmck: This also papers over an audio/irq bug, but hopefully that will be fixed soon. ] Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
-rw-r--r--kernel/rcutree.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 338f1d1c1c66..a7bf517b0482 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -54,6 +54,7 @@
54#include <linux/stop_machine.h> 54#include <linux/stop_machine.h>
55#include <linux/random.h> 55#include <linux/random.h>
56#include <linux/ftrace_event.h> 56#include <linux/ftrace_event.h>
57#include <linux/suspend.h>
57 58
58#include "rcutree.h" 59#include "rcutree.h"
59#include <trace/events/rcu.h> 60#include <trace/events/rcu.h>
@@ -3032,6 +3033,25 @@ static int rcu_cpu_notify(struct notifier_block *self,
3032 return NOTIFY_OK; 3033 return NOTIFY_OK;
3033} 3034}
3034 3035
3036static int rcu_pm_notify(struct notifier_block *self,
3037 unsigned long action, void *hcpu)
3038{
3039 switch (action) {
3040 case PM_HIBERNATION_PREPARE:
3041 case PM_SUSPEND_PREPARE:
3042 if (nr_cpu_ids <= 256) /* Expediting bad for large systems. */
3043 rcu_expedited = 1;
3044 break;
3045 case PM_POST_HIBERNATION:
3046 case PM_POST_SUSPEND:
3047 rcu_expedited = 0;
3048 break;
3049 default:
3050 break;
3051 }
3052 return NOTIFY_OK;
3053}
3054
3035/* 3055/*
3036 * Spawn the kthread that handles this RCU flavor's grace periods. 3056 * Spawn the kthread that handles this RCU flavor's grace periods.
3037 */ 3057 */
@@ -3273,6 +3293,7 @@ void __init rcu_init(void)
3273 * or the scheduler are operational. 3293 * or the scheduler are operational.
3274 */ 3294 */
3275 cpu_notifier(rcu_cpu_notify, 0); 3295 cpu_notifier(rcu_cpu_notify, 0);
3296 pm_notifier(rcu_pm_notify, 0);
3276 for_each_online_cpu(cpu) 3297 for_each_online_cpu(cpu)
3277 rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu); 3298 rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
3278} 3299}