Commit 0dd2ea9af8f0eca43cf6200baa182b3aba307049

Authored by Shaohua Li
Committed by Linus Torvalds
1 parent 6f3814cd2f

[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>

Showing 3 changed files with 18 additions and 0 deletions Side-by-side Diff

arch/x86_64/kernel/pmtimer.c
... ... @@ -80,6 +80,11 @@
80 80 return lost - 1;
81 81 }
82 82  
  83 +void pmtimer_resume(void)
  84 +{
  85 + last_pmtmr_tick = inl(pmtmr_ioport);
  86 +}
  87 +
83 88 unsigned int do_gettimeoffset_pm(void)
84 89 {
85 90 u32 now, offset, delta = 0;
arch/x86_64/kernel/time.c
... ... @@ -1047,9 +1047,21 @@
1047 1047 write_seqlock_irqsave(&xtime_lock,flags);
1048 1048 xtime.tv_sec = sec;
1049 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 1061 write_sequnlock_irqrestore(&xtime_lock,flags);
1051 1062 jiffies += sleep_length;
1052 1063 wall_jiffies += sleep_length;
  1064 + monotonic_base += sleep_length * (NSEC_PER_SEC/HZ);
1053 1065 touch_softlockup_watchdog();
1054 1066 return 0;
1055 1067 }
include/asm-x86_64/proto.h
... ... @@ -41,6 +41,7 @@
41 41  
42 42 extern void time_init_gtod(void);
43 43 extern int pmtimer_mark_offset(void);
  44 +extern void pmtimer_resume(void);
44 45 extern unsigned int do_gettimeoffset_pm(void);
45 46 #ifdef CONFIG_X86_PM_TIMER
46 47 extern u32 pmtmr_ioport;