Commit 3171a0305d62e6627a24bff35af4f997e4988a80

Authored by Atsushi Nemoto
Committed by Linus Torvalds
1 parent 27d91e07f9

[PATCH] simplify update_times (avoid jiffies/jiffies_64 aliasing problem)

Pass ticks to do_timer() and update_times(), and adjust x86_64 and s390
timer interrupt handler with this change.

Currently update_times() calculates ticks by "jiffies - wall_jiffies", but
callers of do_timer() should know how many ticks to update.  Passing ticks
get rid of this redundant calculation.  Also there are another redundancy
pointed out by Martin Schwidefsky.

This cleanup make a barrier added by
5aee405c662ca644980c184774277fc6d0769a84 needless.  So this patch removes
it.

As a bonus, this cleanup make wall_jiffies can be removed easily, since now
wall_jiffies is always synced with jiffies.  (This patch does not really
remove wall_jiffies.  It would be another cleanup patch)

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Andi Kleen <ak@muc.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Cc: Ian Molton <spyro@f2s.com>
Cc: Mikael Starvik <starvik@axis.com>
Acked-by: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Hirokazu Takata <takata.hirokazu@renesas.com>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Cc: Kyle McMartin <kyle@mcmartin.ca>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Richard Curnow <rc@rc0.org.uk>
Cc: William Lee Irwin III <wli@holomorphy.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Miles Bader <uclinux-v850@lsi.nec.co.jp>
Cc: Chris Zankel <chris@zankel.net>
Acked-by: "Luck, Tony" <tony.luck@intel.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 38 changed files with 52 additions and 60 deletions Side-by-side Diff

arch/alpha/kernel/time.c
... ... @@ -132,7 +132,7 @@
132 132 nticks = delta >> FIX_SHIFT;
133 133  
134 134 while (nticks > 0) {
135   - do_timer(regs);
  135 + do_timer(1);
136 136 #ifndef CONFIG_SMP
137 137 update_process_times(user_mode(regs));
138 138 #endif
arch/arm/kernel/time.c
... ... @@ -337,7 +337,7 @@
337 337 profile_tick(CPU_PROFILING, regs);
338 338 do_leds();
339 339 do_set_rtc();
340   - do_timer(regs);
  340 + do_timer(1);
341 341 #ifndef CONFIG_SMP
342 342 update_process_times(user_mode(regs));
343 343 #endif
arch/arm26/kernel/time.c
... ... @@ -194,7 +194,7 @@
194 194  
195 195 static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
196 196 {
197   - do_timer(regs);
  197 + do_timer(1);
198 198 #ifndef CONFIG_SMP
199 199 update_process_times(user_mode(regs));
200 200 #endif
arch/avr32/kernel/time.c
... ... @@ -148,7 +148,7 @@
148 148 * Call the generic timer interrupt handler
149 149 */
150 150 write_seqlock(&xtime_lock);
151   - do_timer(regs);
  151 + do_timer(1);
152 152 write_sequnlock(&xtime_lock);
153 153  
154 154 /*
arch/cris/arch-v10/kernel/time.c
... ... @@ -227,7 +227,7 @@
227 227  
228 228 /* call the real timer interrupt handler */
229 229  
230   - do_timer(regs);
  230 + do_timer(1);
231 231  
232 232 cris_do_profile(regs); /* Save profiling information */
233 233  
arch/cris/arch-v32/kernel/time.c
... ... @@ -219,7 +219,7 @@
219 219 return IRQ_HANDLED;
220 220  
221 221 /* call the real timer interrupt handler */
222   - do_timer(regs);
  222 + do_timer(1);
223 223  
224 224 /*
225 225 * If we have an externally synchronized Linux clock, then update
arch/frv/kernel/time.c
... ... @@ -70,7 +70,7 @@
70 70 */
71 71 write_seqlock(&xtime_lock);
72 72  
73   - do_timer(regs);
  73 + do_timer(1);
74 74 update_process_times(user_mode(regs));
75 75 profile_tick(CPU_PROFILING, regs);
76 76  
arch/h8300/kernel/time.c
... ... @@ -41,7 +41,7 @@
41 41 /* may need to kick the hardware timer */
42 42 platform_timer_eoi();
43 43  
44   - do_timer(regs);
  44 + do_timer(1);
45 45 #ifndef CONFIG_SMP
46 46 update_process_times(user_mode(regs));
47 47 #endif
arch/ia64/kernel/time.c
... ... @@ -78,7 +78,7 @@
78 78 * xtime_lock.
79 79 */
80 80 write_seqlock(&xtime_lock);
81   - do_timer(regs);
  81 + do_timer(1);
82 82 local_cpu_data->itm_next = new_itm;
83 83 write_sequnlock(&xtime_lock);
84 84 } else
arch/m32r/kernel/time.c
... ... @@ -202,7 +202,7 @@
202 202 #ifndef CONFIG_SMP
203 203 profile_tick(CPU_PROFILING, regs);
204 204 #endif
205   - do_timer(regs);
  205 + do_timer(1);
206 206  
207 207 #ifndef CONFIG_SMP
208 208 update_process_times(user_mode(regs));
arch/m68k/kernel/time.c
... ... @@ -40,7 +40,7 @@
40 40 */
41 41 static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
42 42 {
43   - do_timer(regs);
  43 + do_timer(1);
44 44 #ifndef CONFIG_SMP
45 45 update_process_times(user_mode(regs));
46 46 #endif
arch/m68k/sun3/sun3ints.c
... ... @@ -65,7 +65,7 @@
65 65 #ifdef CONFIG_SUN3
66 66 intersil_clear();
67 67 #endif
68   - do_timer(fp);
  68 + do_timer(1);
69 69 #ifndef CONFIG_SMP
70 70 update_process_times(user_mode(fp));
71 71 #endif
arch/m68knommu/kernel/time.c
... ... @@ -51,7 +51,7 @@
51 51  
52 52 write_seqlock(&xtime_lock);
53 53  
54   - do_timer(regs);
  54 + do_timer(1);
55 55 #ifndef CONFIG_SMP
56 56 update_process_times(user_mode(regs));
57 57 #endif
arch/mips/au1000/common/time.c
... ... @@ -96,7 +96,7 @@
96 96 timerlo = count;
97 97  
98 98 kstat_this_cpu.irqs[irq]++;
99   - do_timer(regs);
  99 + do_timer(1);
100 100 #ifndef CONFIG_SMP
101 101 update_process_times(user_mode(regs));
102 102 #endif
... ... @@ -137,7 +137,7 @@
137 137 }
138 138  
139 139 while (time_elapsed > 0) {
140   - do_timer(regs);
  140 + do_timer(1);
141 141 #ifndef CONFIG_SMP
142 142 update_process_times(user_mode(regs));
143 143 #endif
... ... @@ -156,7 +156,7 @@
156 156  
157 157 if (jiffie_drift >= 999) {
158 158 jiffie_drift -= 999;
159   - do_timer(regs); /* increment jiffies by one */
  159 + do_timer(1); /* increment jiffies by one */
160 160 #ifndef CONFIG_SMP
161 161 update_process_times(user_mode(regs));
162 162 #endif
arch/mips/gt64120/common/time.c
... ... @@ -34,7 +34,7 @@
34 34 if (irq_src & 0x00000800) { /* Check for timer interrupt */
35 35 handled = 1;
36 36 irq_src &= ~0x00000800;
37   - do_timer(regs);
  37 + do_timer(1);
38 38 #ifndef CONFIG_SMP
39 39 update_process_times(user_mode(regs));
40 40 #endif
arch/mips/kernel/time.c
... ... @@ -434,7 +434,7 @@
434 434 /*
435 435 * call the generic timer interrupt handling
436 436 */
437   - do_timer(regs);
  437 + do_timer(1);
438 438  
439 439 /*
440 440 * If we have an externally synchronized Linux clock, then update
arch/mips/momentum/ocelot_g/gt-irq.c
... ... @@ -133,7 +133,7 @@
133 133 MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
134 134  
135 135 /* handle the timer call */
136   - do_timer(regs);
  136 + do_timer(1);
137 137 #ifndef CONFIG_SMP
138 138 update_process_times(user_mode(regs));
139 139 #endif
arch/mips/sgi-ip27/ip27-timer.c
... ... @@ -111,7 +111,7 @@
111 111 kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */
112 112  
113 113 if (cpu == 0)
114   - do_timer(regs);
  114 + do_timer(1);
115 115  
116 116 update_process_times(user_mode(regs));
117 117  
arch/parisc/kernel/time.c
... ... @@ -79,7 +79,7 @@
79 79 #endif
80 80 if (cpu == 0) {
81 81 write_seqlock(&xtime_lock);
82   - do_timer(regs);
  82 + do_timer(1);
83 83 write_sequnlock(&xtime_lock);
84 84 }
85 85 }
arch/powerpc/kernel/time.c
... ... @@ -693,7 +693,7 @@
693 693 tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
694 694 if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
695 695 tb_last_jiffy = tb_next_jiffy;
696   - do_timer(regs);
  696 + do_timer(1);
697 697 timer_recalc_offset(tb_last_jiffy);
698 698 timer_check_rtc();
699 699 }
arch/ppc/kernel/time.c
... ... @@ -153,7 +153,7 @@
153 153 /* We are in an interrupt, no need to save/restore flags */
154 154 write_seqlock(&xtime_lock);
155 155 tb_last_stamp = jiffy_stamp;
156   - do_timer(regs);
  156 + do_timer(1);
157 157  
158 158 /*
159 159 * update the rtc when needed, this should be performed on the
arch/s390/kernel/time.c
... ... @@ -166,7 +166,7 @@
166 166 void account_ticks(struct pt_regs *regs)
167 167 {
168 168 __u64 tmp;
169   - __u32 ticks, xticks;
  169 + __u32 ticks;
170 170  
171 171 /* Calculate how many ticks have passed. */
172 172 if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) {
... ... @@ -204,6 +204,7 @@
204 204 */
205 205 write_seqlock(&xtime_lock);
206 206 if (S390_lowcore.jiffy_timer > xtime_cc) {
  207 + __u32 xticks;
207 208 tmp = S390_lowcore.jiffy_timer - xtime_cc;
208 209 if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
209 210 xticks = __div(tmp, CLK_TICKS_PER_JIFFY);
210 211  
... ... @@ -212,13 +213,11 @@
212 213 xticks = 1;
213 214 xtime_cc += CLK_TICKS_PER_JIFFY;
214 215 }
215   - while (xticks--)
216   - do_timer(regs);
  216 + do_timer(xticks);
217 217 }
218 218 write_sequnlock(&xtime_lock);
219 219 #else
220   - for (xticks = ticks; xticks > 0; xticks--)
221   - do_timer(regs);
  220 + do_timer(ticks);
222 221 #endif
223 222  
224 223 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
arch/sh/kernel/time.c
... ... @@ -117,7 +117,7 @@
117 117 */
118 118 void handle_timer_tick(struct pt_regs *regs)
119 119 {
120   - do_timer(regs);
  120 + do_timer(1);
121 121 #ifndef CONFIG_SMP
122 122 update_process_times(user_mode(regs));
123 123 #endif
arch/sh64/kernel/time.c
... ... @@ -298,7 +298,7 @@
298 298 asm ("getcon cr62, %0" : "=r" (current_ctc));
299 299 ctc_last_interrupt = (unsigned long) current_ctc;
300 300  
301   - do_timer(regs);
  301 + do_timer(1);
302 302 #ifndef CONFIG_SMP
303 303 update_process_times(user_mode(regs));
304 304 #endif
arch/sparc/kernel/pcic.c
... ... @@ -712,7 +712,7 @@
712 712 {
713 713 write_seqlock(&xtime_lock); /* Dummy, to show that we remember */
714 714 pcic_clear_clock_irq();
715   - do_timer(regs);
  715 + do_timer(1);
716 716 #ifndef CONFIG_SMP
717 717 update_process_times(user_mode(regs));
718 718 #endif
arch/sparc/kernel/time.c
... ... @@ -128,7 +128,7 @@
128 128 #endif
129 129 clear_clock_irq();
130 130  
131   - do_timer(regs);
  131 + do_timer(1);
132 132 #ifndef CONFIG_SMP
133 133 update_process_times(user_mode(regs));
134 134 #endif
arch/sparc64/kernel/time.c
... ... @@ -465,7 +465,7 @@
465 465 profile_tick(CPU_PROFILING, regs);
466 466 update_process_times(user_mode(regs));
467 467 #endif
468   - do_timer(regs);
  468 + do_timer(1);
469 469  
470 470 /* Guarantee that the following sequences execute
471 471 * uninterrupted.
... ... @@ -496,7 +496,7 @@
496 496 {
497 497 write_seqlock(&xtime_lock);
498 498  
499   - do_timer(regs);
  499 + do_timer(1);
500 500  
501 501 timer_check_rtc();
502 502  
arch/um/kernel/time.c
... ... @@ -93,7 +93,7 @@
93 93  
94 94 write_seqlock_irqsave(&xtime_lock, flags);
95 95  
96   - do_timer(regs);
  96 + do_timer(1);
97 97  
98 98 nsecs = get_time();
99 99 xtime.tv_sec = nsecs / NSEC_PER_SEC;
arch/v850/kernel/time.c
... ... @@ -51,7 +51,7 @@
51 51 if (mach_tick)
52 52 mach_tick ();
53 53  
54   - do_timer (regs);
  54 + do_timer (1);
55 55 #ifndef CONFIG_SMP
56 56 update_process_times(user_mode(regs));
57 57 #endif
arch/x86_64/kernel/time.c
... ... @@ -415,16 +415,16 @@
415 415 (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1;
416 416 }
417 417  
418   - if (lost > 0) {
  418 + if (lost > 0)
419 419 handle_lost_ticks(lost, regs);
420   - jiffies += lost;
421   - }
  420 + else
  421 + lost = 0;
422 422  
423 423 /*
424 424 * Do the timer stuff.
425 425 */
426 426  
427   - do_timer(regs);
  427 + do_timer(lost + 1);
428 428 #ifndef CONFIG_SMP
429 429 update_process_times(user_mode(regs));
430 430 #endif
arch/xtensa/kernel/time.c
... ... @@ -175,7 +175,7 @@
175 175  
176 176 last_ccount_stamp = next;
177 177 next += CCOUNT_PER_JIFFY;
178   - do_timer (regs); /* Linux handler in kernel/timer.c */
  178 + do_timer (1); /* Linux handler in kernel/timer.c */
179 179  
180 180 if (ntp_synced() &&
181 181 xtime.tv_sec - last_rtc_update >= 659 &&
include/asm-arm/arch-clps711x/time.h
... ... @@ -29,7 +29,7 @@
29 29 p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
30 30 {
31 31 do_leds();
32   - do_timer(regs);
  32 + do_timer(1);
33 33 #ifndef CONFIG_SMP
34 34 update_process_times(user_mode(regs));
35 35 #endif
include/asm-arm/arch-l7200/time.h
... ... @@ -45,7 +45,7 @@
45 45 static irqreturn_t
46 46 timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
47 47 {
48   - do_timer(regs);
  48 + do_timer(1);
49 49 #ifndef CONFIG_SMP
50 50 update_process_times(user_mode(regs));
51 51 #endif
include/asm-i386/mach-default/do_timer.h
... ... @@ -16,7 +16,7 @@
16 16  
17 17 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
18 18 {
19   - do_timer(regs);
  19 + do_timer(1);
20 20 #ifndef CONFIG_SMP
21 21 update_process_times(user_mode_vm(regs));
22 22 #endif
include/asm-i386/mach-visws/do_timer.h
... ... @@ -9,7 +9,7 @@
9 9 /* Clear the interrupt */
10 10 co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
11 11  
12   - do_timer(regs);
  12 + do_timer(1);
13 13 #ifndef CONFIG_SMP
14 14 update_process_times(user_mode_vm(regs));
15 15 #endif
include/asm-i386/mach-voyager/do_timer.h
... ... @@ -3,7 +3,7 @@
3 3  
4 4 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
5 5 {
6   - do_timer(regs);
  6 + do_timer(1);
7 7 #ifndef CONFIG_SMP
8 8 update_process_times(user_mode_vm(regs));
9 9 #endif
include/linux/sched.h
... ... @@ -1206,7 +1206,7 @@
1206 1206  
1207 1207 #include <asm/current.h>
1208 1208  
1209   -extern void do_timer(struct pt_regs *);
  1209 +extern void do_timer(unsigned long ticks);
1210 1210  
1211 1211 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
1212 1212 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
... ... @@ -1222,10 +1222,8 @@
1222 1222 unsigned long active_tasks; /* fixed-point */
1223 1223 static int count = LOAD_FREQ;
1224 1224  
1225   - count -= ticks;
1226   - if (count < 0) {
1227   - count += LOAD_FREQ;
1228   - active_tasks = count_active_tasks();
  1225 + active_tasks = count_active_tasks();
  1226 + for (count -= ticks; count < 0; count += LOAD_FREQ) {
1229 1227 CALC_LOAD(avenrun[0], EXP_1, active_tasks);
1230 1228 CALC_LOAD(avenrun[1], EXP_5, active_tasks);
1231 1229 CALC_LOAD(avenrun[2], EXP_15, active_tasks);
1232 1230  
... ... @@ -1270,11 +1268,8 @@
1270 1268 * Called by the timer interrupt. xtime_lock must already be taken
1271 1269 * by the timer IRQ!
1272 1270 */
1273   -static inline void update_times(void)
  1271 +static inline void update_times(unsigned long ticks)
1274 1272 {
1275   - unsigned long ticks;
1276   -
1277   - ticks = jiffies - wall_jiffies;
1278 1273 wall_jiffies += ticks;
1279 1274 update_wall_time();
1280 1275 calc_load(ticks);
1281 1276  
... ... @@ -1286,12 +1281,10 @@
1286 1281 * jiffies is defined in the linker script...
1287 1282 */
1288 1283  
1289   -void do_timer(struct pt_regs *regs)
  1284 +void do_timer(unsigned long ticks)
1290 1285 {
1291   - jiffies_64++;
1292   - /* prevent loading jiffies before storing new jiffies_64 value. */
1293   - barrier();
1294   - update_times();
  1286 + jiffies_64 += ticks;
  1287 + update_times(ticks);
1295 1288 }
1296 1289  
1297 1290 #ifdef __ARCH_WANT_SYS_ALARM