path: root/arch/parisc/include
diff options
authorHelge Deller <>2016-04-20 21:34:15 +0200
committerHelge Deller <>2016-05-22 21:39:25 +0200
commit54b668009076caddbede8fde513ca2c982590bfe (patch)
tree873f576cebe662cdb3c8a6626ba6be193a0a6ef4 /arch/parisc/include
parent64e2a42bca12e408f0258c56adcf3595bcd116e7 (diff)
parisc: Add native high-resolution sched_clock() implementation
Add a native implementation for the sched_clock() function which utilizes the processor-internal cycle counter (Control Register 16) as high-resolution time source. With this patch we now get much more fine-grained resolutions in various in-kernel time measurements (e.g. when viewing the function tracing logs), and probably a more accurate scheduling on SMP systems. There are a few specific implementation details in this patch: 1. On a 32bit kernel we emulate the higher 32bits of the required 64-bit resolution of sched_clock() by increasing a per-cpu counter at every wrap-around of the 32bit cycle counter. 2. In a SMP system, the cycle counters of the various CPUs are not syncronized (similiar to the TSC in a x86_64 system). To cope with this we define HAVE_UNSTABLE_SCHED_CLOCK and let the upper layers do the adjustment work. 3. Since we need HAVE_UNSTABLE_SCHED_CLOCK, we need to provide a cmpxchg64() function even on a 32-bit kernel. 4. A 64-bit SMP kernel which is started on a UP system will mark the sched_clock() implementation as "stable", which means that we don't expect any jumps in the returned counter. This is true because we then run only on one CPU. Signed-off-by: Helge Deller <>
Diffstat (limited to 'arch/parisc/include')
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h
index 0a90b965cccb..7ada30900807 100644
--- a/arch/parisc/include/asm/cmpxchg.h
+++ b/arch/parisc/include/asm/cmpxchg.h
@@ -52,8 +52,7 @@ extern void __cmpxchg_called_with_bad_pointer(void);
/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old,
unsigned int new_);
-extern unsigned long __cmpxchg_u64(volatile unsigned long *ptr,
- unsigned long old, unsigned long new_);
+extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_);
/* don't worry...optimizer will get rid of most of this */
static inline unsigned long
@@ -61,7 +60,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
switch (size) {
#ifdef CONFIG_64BIT
- case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
+ case 8: return __cmpxchg_u64((u64 *)ptr, old, new_);
case 4: return __cmpxchg_u32((unsigned int *)ptr,
(unsigned int)old, (unsigned int)new_);
@@ -86,7 +85,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
switch (size) {
#ifdef CONFIG_64BIT
- case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_);
+ case 8: return __cmpxchg_u64((u64 *)ptr, old, new_);
case 4: return __cmpxchg_u32(ptr, old, new_);
@@ -111,4 +110,6 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n) __cmpxchg_u64(ptr, o, n)
#endif /* _ASM_PARISC_CMPXCHG_H_ */