Commit eb36c2884a1a2190791afe65fd833b2d3cd4b999

Authored by Paul Mackerras
Committed by Linus Torvalds
1 parent 98a3c78105

[PATCH] ppc32: fix last_jiffy time comparison

This fixes a hang on ppc32.

The problem was that I was comparing a 32-bit quantity with a 64-bit
quantity, and consequently time wasn't advancing.  This makes us use a
64-bit quantity on all platforms, which ends up simplifying the code
since we can now get rid of the tb_last_stamp variable (which actually
fixes another bug that Ben H and I noticed while going carefully through
the code).

This works fine on my G4 tibook.  Let me know how it goes on your
machines.

Acked-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 2 changed files with 8 additions and 21 deletions Side-by-side Diff

arch/powerpc/kernel/time.c
... ... @@ -125,16 +125,9 @@
125 125 unsigned long ppc_proc_freq;
126 126 unsigned long ppc_tb_freq;
127 127  
128   -u64 tb_last_jiffy __cacheline_aligned_in_smp;
129   -unsigned long tb_last_stamp;
  128 +static u64 tb_last_jiffy __cacheline_aligned_in_smp;
  129 +static DEFINE_PER_CPU(u64, last_jiffy);
130 130  
131   -/*
132   - * Note that on ppc32 this only stores the bottom 32 bits of
133   - * the timebase value, but that's enough to tell when a jiffy
134   - * has passed.
135   - */
136   -DEFINE_PER_CPU(unsigned long, last_jiffy);
137   -
138 131 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
139 132 /*
140 133 * Factors for converting from cputime_t (timebase ticks) to
... ... @@ -458,7 +451,7 @@
458 451 do {
459 452 seq = read_seqbegin_irqsave(&xtime_lock, flags);
460 453 sec = xtime.tv_sec;
461   - nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp);
  454 + nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy);
462 455 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
463 456 usec = nsec / 1000;
464 457 while (usec >= 1000000) {
... ... @@ -700,7 +693,6 @@
700 693 tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
701 694 if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
702 695 tb_last_jiffy = tb_next_jiffy;
703   - tb_last_stamp = per_cpu(last_jiffy, cpu);
704 696 do_timer(regs);
705 697 timer_recalc_offset(tb_last_jiffy);
706 698 timer_check_rtc();
... ... @@ -749,7 +741,7 @@
749 741 int i;
750 742 unsigned long half = tb_ticks_per_jiffy / 2;
751 743 unsigned long offset = tb_ticks_per_jiffy / max_cpus;
752   - unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
  744 + u64 previous_tb = per_cpu(last_jiffy, boot_cpuid);
753 745  
754 746 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
755 747 previous_tb -= tb_ticks_per_jiffy;
... ... @@ -830,7 +822,7 @@
830 822 * and therefore the (jiffies - wall_jiffies) computation
831 823 * has been removed.
832 824 */
833   - tb_delta = tb_ticks_since(tb_last_stamp);
  825 + tb_delta = tb_ticks_since(tb_last_jiffy);
834 826 tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */
835 827 new_nsec -= SCALE_XSEC(tb_delta, 1000000000);
836 828  
... ... @@ -950,8 +942,7 @@
950 942 if (__USE_RTC()) {
951 943 /* 601 processor: dec counts down by 128 every 128ns */
952 944 ppc_tb_freq = 1000000000;
953   - tb_last_stamp = get_rtcl();
954   - tb_last_jiffy = tb_last_stamp;
  945 + tb_last_jiffy = get_rtcl();
955 946 } else {
956 947 /* Normal PowerPC with timebase register */
957 948 ppc_md.calibrate_decr();
... ... @@ -959,7 +950,7 @@
959 950 ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
960 951 printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n",
961 952 ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
962   - tb_last_stamp = tb_last_jiffy = get_tb();
  953 + tb_last_jiffy = get_tb();
963 954 }
964 955  
965 956 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
... ... @@ -1036,7 +1027,7 @@
1036 1027 do_gtod.varp = &do_gtod.vars[0];
1037 1028 do_gtod.var_idx = 0;
1038 1029 do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
1039   - __get_cpu_var(last_jiffy) = tb_last_stamp;
  1030 + __get_cpu_var(last_jiffy) = tb_last_jiffy;
1040 1031 do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
1041 1032 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
1042 1033 do_gtod.varp->tb_to_xs = tb_to_xs;
include/asm-powerpc/time.h
... ... @@ -30,10 +30,6 @@
30 30 extern unsigned long tb_ticks_per_sec;
31 31 extern u64 tb_to_xs;
32 32 extern unsigned tb_to_us;
33   -extern unsigned long tb_last_stamp;
34   -extern u64 tb_last_jiffy;
35   -
36   -DECLARE_PER_CPU(unsigned long, last_jiffy);
37 33  
38 34 struct rtc_time;
39 35 extern void to_tm(int tim, struct rtc_time * tm);