aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
authorNathan Lynch <ntl@pobox.com>2006-08-22 21:36:05 -0400
committerPaul Mackerras <paulus@samba.org>2006-08-23 01:51:18 -0400
commit5db9fa9593e2ff69f2b95f9d59229dc4faaa564d (patch)
treed58ba58c05408edf8993d0da5a31b3ea3df1a053 /include/asm-powerpc
parentaa74a30be971c632d734e487df42278b1cf85151 (diff)
[POWERPC] Fix gettimeofday inaccuracies
There are two problems in the powerpc gettimeofday code which can cause incorrect results to be returned. The first is that there is a race between do_gettimeofday and the timer interrupt: 1. do_gettimeofday does get_tb() 2. decrementer exception on boot cpu which runs timer_recalc_offset, which also samples the timebase and updates the do_gtod structure with a greater timebase value. 3. do_gettimeofday calls __do_gettimeofday, which leads to the negative result from tb_val - temp_varp->tb_orig_stamp. The second is caused by taking the boot cpu offline, which can cause the value of tb_last_jiffy to be increased past the currently available timebase, causing the same underflow as above. [paulus@samba.org - define and use data_barrier() instead of mb().] Signed-off-by: Nathan Lynch <ntl@pobox.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/system.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 7307aa775671..4c9f5229e833 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -53,6 +53,15 @@
53#define smp_read_barrier_depends() do { } while(0) 53#define smp_read_barrier_depends() do { } while(0)
54#endif /* CONFIG_SMP */ 54#endif /* CONFIG_SMP */
55 55
56/*
57 * This is a barrier which prevents following instructions from being
58 * started until the value of the argument x is known. For example, if
59 * x is a variable loaded from memory, this prevents following
60 * instructions from being executed until the load has been performed.
61 */
62#define data_barrier(x) \
63 asm volatile("twi 0,%0,0; isync" : : "r" (x) : "memory");
64
56struct task_struct; 65struct task_struct;
57struct pt_regs; 66struct pt_regs;
58 67