Skip to content

Commit

Permalink
powerpc/vdso32: Add support for CLOCK_{REALTIME/MONOTONIC}_COARSE
Browse files Browse the repository at this point in the history
This is copied and adapted from commit 5c92988 ("powerpc/vdso64:
Add support for CLOCK_{REALTIME/MONOTONIC}_COARSE")
from Santosh Sivaraj <santosh@fossix.org>

Benchmark from vdsotest-all:
clock-gettime-realtime: syscall: 3601 nsec/call
clock-gettime-realtime:    libc: 1072 nsec/call
clock-gettime-realtime:    vdso: 931 nsec/call
clock-gettime-monotonic: syscall: 4034 nsec/call
clock-gettime-monotonic:    libc: 1213 nsec/call
clock-gettime-monotonic:    vdso: 1076 nsec/call
clock-gettime-realtime-coarse: syscall: 2722 nsec/call
clock-gettime-realtime-coarse:    libc: 805 nsec/call
clock-gettime-realtime-coarse:    vdso: 668 nsec/call
clock-gettime-monotonic-coarse: syscall: 2949 nsec/call
clock-gettime-monotonic-coarse:    libc: 882 nsec/call
clock-gettime-monotonic-coarse:    vdso: 745 nsec/call

Additional test passed with:
	vdsotest -d 30 clock-gettime-monotonic-coarse verify

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Fix it for 64-bit compat by using TSPEC_TV_SEC etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/4644ccc9b4da78639ae9424db878c48711abf05a.1572342582.git.christophe.leroy@c-s.fr
  • Loading branch information
chleroy authored and mpe committed Nov 21, 2019
1 parent 78a30e1 commit 5e381d7
Showing 1 changed file with 59 additions and 7 deletions.
66 changes: 59 additions & 7 deletions arch/powerpc/kernel/vdso32/gettimeofday.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
#ifdef CONFIG_PPC64
#define LOPART 4
#define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART
#define TSPEC_TV_NSEC TSPC64_TV_NSEC+LOPART
#else
#define LOPART 0
#define TSPEC_TV_SEC TSPC32_TV_SEC
#define TSPEC_TV_NSEC TSPC32_TV_NSEC
#endif

.text
Expand Down Expand Up @@ -71,7 +73,13 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
cmpli cr0,r3,CLOCK_REALTIME
cmpli cr1,r3,CLOCK_MONOTONIC
cror cr0*4+eq,cr0*4+eq,cr1*4+eq
bne cr0,99f

cmpli cr5,r3,CLOCK_REALTIME_COARSE
cmpli cr6,r3,CLOCK_MONOTONIC_COARSE
cror cr5*4+eq,cr5*4+eq,cr6*4+eq

cror cr0*4+eq,cr0*4+eq,cr5*4+eq
bne cr0, .Lgettime_fallback

mflr r12 /* r12 saves lr */
.cfi_register lr,r12
Expand All @@ -80,8 +88,10 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
mr r9,r3 /* datapage ptr in r9 */
lis r7,NSEC_PER_SEC@h /* want nanoseconds */
ori r7,r7,NSEC_PER_SEC@l
50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
bne cr1,80f /* not monotonic -> all done */
beq cr5, .Lcoarse_clocks
.Lprecise_clocks:
bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
bne cr1, .Lfinish /* not monotonic -> all done */

/*
* CLOCK_MONOTONIC
Expand All @@ -105,24 +115,66 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
add r9,r9,r0
lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
cmpl cr0,r8,r0 /* check if updated */
bne- 50b
bne- .Lprecise_clocks
b .Lfinish_monotonic

/*
* For coarse clocks we get data directly from the vdso data page, so
* we don't need to call __do_get_tspec, but we still need to do the
* counter trick.
*/
.Lcoarse_clocks:
lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
andi. r0,r8,1 /* pending update ? loop */
bne- .Lcoarse_clocks
add r9,r9,r0 /* r0 is already 0 */

/*
* CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
* too
*/
lwz r3,STAMP_XTIME+TSPEC_TV_SEC(r9)
lwz r4,STAMP_XTIME+TSPEC_TV_NSEC(r9)
bne cr6,1f

/* CLOCK_MONOTONIC_COARSE */
lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9)
lwz r6,WTOM_CLOCK_NSEC(r9)

/* check if counter has updated */
or r0,r6,r5
1: or r0,r0,r3
or r0,r0,r4
xor r0,r0,r0
add r3,r3,r0
lwz r0,CFG_TB_UPDATE_COUNT+LOPART(r9)
cmpl cr0,r0,r8 /* check if updated */
bne- .Lcoarse_clocks

/* Counter has not updated, so continue calculating proper values for
* sec and nsec if monotonic coarse, or just return with the proper
* values for realtime.
*/
bne cr6, .Lfinish

/* Calculate and store result. Note that this mimics the C code,
* which may cause funny results if nsec goes negative... is that
* possible at all ?
*/
.Lfinish_monotonic:
add r3,r3,r5
add r4,r4,r6
cmpw cr0,r4,r7
cmpwi cr1,r4,0
blt 1f
subf r4,r7,r4
addi r3,r3,1
1: bge cr1,80f
1: bge cr1, .Lfinish
addi r3,r3,-1
add r4,r4,r7

80: stw r3,TSPC32_TV_SEC(r11)
.Lfinish:
stw r3,TSPC32_TV_SEC(r11)
stw r4,TSPC32_TV_NSEC(r11)

mtlr r12
Expand All @@ -133,7 +185,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
/*
* syscall fallback
*/
99:
.Lgettime_fallback:
li r0,__NR_clock_gettime
.cfi_restore lr
sc
Expand Down

0 comments on commit 5e381d7

Please sign in to comment.