diff options
author | Shaohua Li <shaohua.li@intel.com> | 2006-02-03 15:50:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-04 19:43:13 -0500 |
commit | 0dd2ea9af8f0eca43cf6200baa182b3aba307049 (patch) | |
tree | 68d19724e9c50e14ea7d900493a9af37ff26c948 | |
parent | 6f3814cd2fb5ea4d53a7fa5b0635d68fa4036c1b (diff) |
[PATCH] x86_64: [PATCH] timer resume
At resume time, TSC's value or something similar might be changed a lot
against suspend time. This could make system gets a very big lost ticks.
See http://bugzilla.kernel.org/show_bug.cgi?id=5825
Signed-off-by: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/x86_64/kernel/pmtimer.c | 5 | ||||
-rw-r--r-- | arch/x86_64/kernel/time.c | 12 | ||||
-rw-r--r-- | include/asm-x86_64/proto.h | 1 |
3 files changed, 18 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c index feb5f108dd26..8b2655ae4e61 100644 --- a/arch/x86_64/kernel/pmtimer.c +++ b/arch/x86_64/kernel/pmtimer.c | |||
@@ -80,6 +80,11 @@ int pmtimer_mark_offset(void) | |||
80 | return lost - 1; | 80 | return lost - 1; |
81 | } | 81 | } |
82 | 82 | ||
83 | void pmtimer_resume(void) | ||
84 | { | ||
85 | last_pmtmr_tick = inl(pmtmr_ioport); | ||
86 | } | ||
87 | |||
83 | unsigned int do_gettimeoffset_pm(void) | 88 | unsigned int do_gettimeoffset_pm(void) |
84 | { | 89 | { |
85 | u32 now, offset, delta = 0; | 90 | u32 now, offset, delta = 0; |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 91a448a86ebd..c1f76055b578 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -1047,9 +1047,21 @@ static int timer_resume(struct sys_device *dev) | |||
1047 | write_seqlock_irqsave(&xtime_lock,flags); | 1047 | write_seqlock_irqsave(&xtime_lock,flags); |
1048 | xtime.tv_sec = sec; | 1048 | xtime.tv_sec = sec; |
1049 | xtime.tv_nsec = 0; | 1049 | xtime.tv_nsec = 0; |
1050 | if (vxtime.mode == VXTIME_HPET) { | ||
1051 | if (hpet_use_timer) | ||
1052 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | ||
1053 | else | ||
1054 | vxtime.last = hpet_readl(HPET_COUNTER); | ||
1055 | #ifdef CONFIG_X86_PM_TIMER | ||
1056 | } else if (vxtime.mode == VXTIME_PMTMR) { | ||
1057 | pmtimer_resume(); | ||
1058 | #endif | ||
1059 | } else | ||
1060 | vxtime.last_tsc = get_cycles_sync(); | ||
1050 | write_sequnlock_irqrestore(&xtime_lock,flags); | 1061 | write_sequnlock_irqrestore(&xtime_lock,flags); |
1051 | jiffies += sleep_length; | 1062 | jiffies += sleep_length; |
1052 | wall_jiffies += sleep_length; | 1063 | wall_jiffies += sleep_length; |
1064 | monotonic_base += sleep_length * (NSEC_PER_SEC/HZ); | ||
1053 | touch_softlockup_watchdog(); | 1065 | touch_softlockup_watchdog(); |
1054 | return 0; | 1066 | return 0; |
1055 | } | 1067 | } |
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index c1e2307445d4..a6748b9568fe 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h | |||
@@ -41,6 +41,7 @@ extern void iommu_hole_init(void); | |||
41 | 41 | ||
42 | extern void time_init_gtod(void); | 42 | extern void time_init_gtod(void); |
43 | extern int pmtimer_mark_offset(void); | 43 | extern int pmtimer_mark_offset(void); |
44 | extern void pmtimer_resume(void); | ||
44 | extern unsigned int do_gettimeoffset_pm(void); | 45 | extern unsigned int do_gettimeoffset_pm(void); |
45 | #ifdef CONFIG_X86_PM_TIMER | 46 | #ifdef CONFIG_X86_PM_TIMER |
46 | extern u32 pmtmr_ioport; | 47 | extern u32 pmtmr_ioport; |