[kernel/f13/master] x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
Chuck Ebbert
cebbert at fedoraproject.org
Sun Sep 5 10:07:43 UTC 2010
commit fb84bd51fb5e4e7dc601d4702979243c817a3208
Author: Chuck Ebbert <cebbert at redhat.com>
Date: Sun Sep 5 06:07:58 2010 -0400
x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
Fix load balancing after suspend/resume cycle (taken from 2.6.32 stable queue)
kernel.spec | 5 +
..._offset-s-during-resume-from-sleep-states.patch | 115 ++++++++++++++++++++
2 files changed, 120 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index b6bf610..e39d4fa 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -787,6 +787,7 @@ Patch12523: keys-fix-rcu-no-lock-warning-in-keyctl-session-to-parent.patch
Patch12530: pci-msi-remove-unsafe-and-unnecessary-hardware-access.patch
Patch12531: pci-msi-restore-read_msi_msg_desc-add-get_cached_msi_msg_desc.patch
+Patch12532: x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
%endif
@@ -1487,6 +1488,8 @@ ApplyPatch keys-fix-rcu-no-lock-warning-in-keyctl-session-to-parent.patch
# Fix unsafe access to MSI registers during suspend
ApplyPatch pci-msi-remove-unsafe-and-unnecessary-hardware-access.patch
ApplyPatch pci-msi-restore-read_msi_msg_desc-add-get_cached_msi_msg_desc.patch
+# Fix scheduler load balancing after suspend/resume cycle
+ApplyPatch x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
# END OF PATCH APPLICATIONS
@@ -2114,6 +2117,8 @@ fi
- Fix unsafe access to MSI registers during suspend
(pci-msi-remove-unsafe-and-unnecessary-hardware-access.patch,
pci-msi-restore-read_msi_msg_desc-add-get_cached_msi_msg_desc.patch)
+- x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
+ Fix load balancing after suspend/resume cycle (taken from 2.6.32 stable queue)
* Fri Sep 03 2010 Chuck Ebbert <cebbert at redhat.com> 2.6.34.6-52
- acpi-ec-pm-fix-race-between-ec-transactions-and-system-suspend.patch:
diff --git a/x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch b/x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
new file mode 100644
index 0000000..c0d1e86
--- /dev/null
+++ b/x86-tsc-sched-recompute-cyc2ns_offset-s-during-resume-from-sleep-states.patch
@@ -0,0 +1,115 @@
+From cd7240c0b900eb6d690ccee088a6c9b46dae815a Mon Sep 17 00:00:00 2001
+From: Suresh Siddha <suresh.b.siddha at intel.com>
+Date: Thu, 19 Aug 2010 17:03:38 -0700
+Subject: x86, tsc, sched: Recompute cyc2ns_offset's during resume from sleep states
+
+From: Suresh Siddha <suresh.b.siddha at intel.com>
+
+commit cd7240c0b900eb6d690ccee088a6c9b46dae815a upstream.
+
+TSC's get reset after suspend/resume (even on cpu's with invariant TSC
+which runs at a constant rate across ACPI P-, C- and T-states). And in
+some systems BIOS seem to reinit TSC to arbitrary large value (still
+sync'd across cpu's) during resume.
+
+This leads to a scenario of scheduler rq->clock (sched_clock_cpu()) less
+than rq->age_stamp (introduced in 2.6.32). This leads to a big value
+returned by scale_rt_power() and the resulting big group power set by the
+update_group_power() is causing improper load balancing between busy and
+idle cpu's after suspend/resume.
+
+This resulted in multi-threaded workloads (like kernel-compilation) go
+slower after suspend/resume cycle on core i5 laptops.
+
+Fix this by recomputing cyc2ns_offset's during resume, so that
+sched_clock() continues from the point where it was left off during
+suspend.
+
+Reported-by: Florian Pritz <flo at xssn.at>
+Signed-off-by: Suresh Siddha <suresh.b.siddha at intel.com>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra at chello.nl>
+LKML-Reference: <1282262618.2675.24.camel at sbsiddha-MOBL3.sc.intel.com>
+Signed-off-by: Ingo Molnar <mingo at elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+
+---
+ arch/x86/include/asm/tsc.h | 2 ++
+ arch/x86/kernel/tsc.c | 38 ++++++++++++++++++++++++++++++++++++++
+ arch/x86/power/cpu.c | 2 ++
+ 3 files changed, 42 insertions(+)
+
+--- a/arch/x86/include/asm/tsc.h
++++ b/arch/x86/include/asm/tsc.h
+@@ -59,5 +59,7 @@ extern void check_tsc_sync_source(int cp
+ extern void check_tsc_sync_target(void);
+
+ extern int notsc_setup(char *);
++extern void save_sched_clock_state(void);
++extern void restore_sched_clock_state(void);
+
+ #endif /* _ASM_X86_TSC_H */
+--- a/arch/x86/kernel/tsc.c
++++ b/arch/x86/kernel/tsc.c
+@@ -626,6 +626,44 @@ static void set_cyc2ns_scale(unsigned lo
+ local_irq_restore(flags);
+ }
+
++static unsigned long long cyc2ns_suspend;
++
++void save_sched_clock_state(void)
++{
++ if (!sched_clock_stable)
++ return;
++
++ cyc2ns_suspend = sched_clock();
++}
++
++/*
++ * Even on processors with invariant TSC, TSC gets reset in some the
++ * ACPI system sleep states. And in some systems BIOS seem to reinit TSC to
++ * arbitrary value (still sync'd across cpu's) during resume from such sleep
++ * states. To cope up with this, recompute the cyc2ns_offset for each cpu so
++ * that sched_clock() continues from the point where it was left off during
++ * suspend.
++ */
++void restore_sched_clock_state(void)
++{
++ unsigned long long offset;
++ unsigned long flags;
++ int cpu;
++
++ if (!sched_clock_stable)
++ return;
++
++ local_irq_save(flags);
++
++ get_cpu_var(cyc2ns_offset) = 0;
++ offset = cyc2ns_suspend - sched_clock();
++
++ for_each_possible_cpu(cpu)
++ per_cpu(cyc2ns_offset, cpu) = offset;
++
++ local_irq_restore(flags);
++}
++
+ #ifdef CONFIG_CPU_FREQ
+
+ /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -112,6 +112,7 @@ static void __save_processor_state(struc
+ void save_processor_state(void)
+ {
+ __save_processor_state(&saved_context);
++ save_sched_clock_state();
+ }
+ #ifdef CONFIG_X86_32
+ EXPORT_SYMBOL(save_processor_state);
+@@ -253,6 +254,7 @@ static void __restore_processor_state(st
+ void restore_processor_state(void)
+ {
+ __restore_processor_state(&saved_context);
++ restore_sched_clock_state();
+ }
+ #ifdef CONFIG_X86_32
+ EXPORT_SYMBOL(restore_processor_state);
More information about the scm-commits
mailing list