s390/vdso: add vdso support for coarse clocks
Add CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE optimization to the 64-bit and 31-bit vdso. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
070b7be633
Коммит
b7eacb59cd
|
@ -22,13 +22,17 @@ struct vdso_data {
|
|||
__u64 xtime_tod_stamp; /* TOD clock for xtime 0x08 */
|
||||
__u64 xtime_clock_sec; /* Kernel time 0x10 */
|
||||
__u64 xtime_clock_nsec; /* 0x18 */
|
||||
__u64 wtom_clock_sec; /* Wall to monotonic clock 0x20 */
|
||||
__u64 wtom_clock_nsec; /* 0x28 */
|
||||
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
|
||||
__u32 tz_dsttime; /* Type of dst correction 0x34 */
|
||||
__u32 ectg_available; /* ECTG instruction present 0x38 */
|
||||
__u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
|
||||
__u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
|
||||
__u64 xtime_coarse_sec; /* Coarse kernel time 0x20 */
|
||||
__u64 xtime_coarse_nsec; /* 0x28 */
|
||||
__u64 wtom_clock_sec; /* Wall to monotonic clock 0x30 */
|
||||
__u64 wtom_clock_nsec; /* 0x38 */
|
||||
__u64 wtom_coarse_sec; /* Coarse wall to monotonic 0x40 */
|
||||
__u64 wtom_coarse_nsec; /* 0x48 */
|
||||
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x50 */
|
||||
__u32 tz_dsttime; /* Type of dst correction 0x54 */
|
||||
__u32 ectg_available; /* ECTG instruction present 0x58 */
|
||||
__u32 tk_mult; /* Mult. used for xtime_nsec 0x5c */
|
||||
__u32 tk_shift; /* Shift used for xtime_nsec 0x60 */
|
||||
};
|
||||
|
||||
struct vdso_per_cpu_data {
|
||||
|
|
|
@ -62,8 +62,12 @@ int main(void)
|
|||
DEFINE(__VDSO_XTIME_STAMP, offsetof(struct vdso_data, xtime_tod_stamp));
|
||||
DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec));
|
||||
DEFINE(__VDSO_XTIME_NSEC, offsetof(struct vdso_data, xtime_clock_nsec));
|
||||
DEFINE(__VDSO_XTIME_CRS_SEC, offsetof(struct vdso_data, xtime_coarse_sec));
|
||||
DEFINE(__VDSO_XTIME_CRS_NSEC, offsetof(struct vdso_data, xtime_coarse_nsec));
|
||||
DEFINE(__VDSO_WTOM_SEC, offsetof(struct vdso_data, wtom_clock_sec));
|
||||
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
|
||||
DEFINE(__VDSO_WTOM_CRS_SEC, offsetof(struct vdso_data, wtom_coarse_sec));
|
||||
DEFINE(__VDSO_WTOM_CRS_NSEC, offsetof(struct vdso_data, wtom_coarse_nsec));
|
||||
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
|
||||
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
|
||||
DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
|
||||
|
@ -73,8 +77,11 @@ int main(void)
|
|||
/* constants used by the vdso */
|
||||
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
|
||||
DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
|
||||
DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
|
||||
DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
|
||||
DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
|
||||
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
|
||||
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
|
||||
BLANK();
|
||||
/* idle data offsets */
|
||||
DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter));
|
||||
|
|
|
@ -232,6 +232,19 @@ void update_vsyscall(struct timekeeper *tk)
|
|||
vdso_data->wtom_clock_nsec -= nsecps;
|
||||
vdso_data->wtom_clock_sec++;
|
||||
}
|
||||
|
||||
vdso_data->xtime_coarse_sec = tk->xtime_sec;
|
||||
vdso_data->xtime_coarse_nsec =
|
||||
(long)(tk->tkr.xtime_nsec >> tk->tkr.shift);
|
||||
vdso_data->wtom_coarse_sec =
|
||||
vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec;
|
||||
vdso_data->wtom_coarse_nsec =
|
||||
vdso_data->xtime_coarse_nsec + tk->wall_to_monotonic.tv_nsec;
|
||||
while (vdso_data->wtom_coarse_nsec >= NSEC_PER_SEC) {
|
||||
vdso_data->wtom_coarse_nsec -= NSEC_PER_SEC;
|
||||
vdso_data->wtom_coarse_sec++;
|
||||
}
|
||||
|
||||
vdso_data->tk_mult = tk->tkr.mult;
|
||||
vdso_data->tk_shift = tk->tkr.shift;
|
||||
smp_wmb();
|
||||
|
|
|
@ -19,14 +19,20 @@
|
|||
.type __kernel_clock_getres,@function
|
||||
__kernel_clock_getres:
|
||||
.cfi_startproc
|
||||
basr %r1,0
|
||||
la %r1,4f-.(%r1)
|
||||
chi %r2,__CLOCK_REALTIME
|
||||
je 0f
|
||||
chi %r2,__CLOCK_MONOTONIC
|
||||
je 0f
|
||||
la %r1,5f-4f(%r1)
|
||||
chi %r2,__CLOCK_REALTIME_COARSE
|
||||
je 0f
|
||||
chi %r2,__CLOCK_MONOTONIC_COARSE
|
||||
jne 3f
|
||||
0: ltr %r3,%r3
|
||||
jz 2f /* res == NULL */
|
||||
basr %r1,0
|
||||
1: l %r0,4f-1b(%r1)
|
||||
1: l %r0,0(%r1)
|
||||
xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */
|
||||
st %r0,4(%r3) /* store tp->tv_usec */
|
||||
2: lhi %r2,0
|
||||
|
@ -35,5 +41,6 @@ __kernel_clock_getres:
|
|||
svc 0
|
||||
br %r14
|
||||
4: .long __CLOCK_REALTIME_RES
|
||||
5: .long __CLOCK_COARSE_RES
|
||||
.cfi_endproc
|
||||
.size __kernel_clock_getres,.-__kernel_clock_getres
|
||||
|
|
|
@ -21,8 +21,12 @@ __kernel_clock_gettime:
|
|||
.cfi_startproc
|
||||
basr %r5,0
|
||||
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
|
||||
chi %r2,__CLOCK_REALTIME_COARSE
|
||||
je 10f
|
||||
chi %r2,__CLOCK_REALTIME
|
||||
je 11f
|
||||
chi %r2,__CLOCK_MONOTONIC_COARSE
|
||||
je 9f
|
||||
chi %r2,__CLOCK_MONOTONIC
|
||||
jne 19f
|
||||
|
||||
|
@ -68,6 +72,26 @@ __kernel_clock_gettime:
|
|||
lhi %r2,0
|
||||
br %r14
|
||||
|
||||
/* CLOCK_MONOTONIC_COARSE */
|
||||
9: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
|
||||
tml %r4,0x0001 /* pending update ? loop */
|
||||
jnz 9b
|
||||
l %r2,__VDSO_WTOM_CRS_SEC+4(%r5)
|
||||
l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5)
|
||||
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
|
||||
jne 9b
|
||||
j 8b
|
||||
|
||||
/* CLOCK_REALTIME_COARSE */
|
||||
10: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
|
||||
tml %r4,0x0001 /* pending update ? loop */
|
||||
jnz 10b
|
||||
l %r2,__VDSO_XTIME_CRS_SEC+4(%r5)
|
||||
l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5)
|
||||
cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */
|
||||
jne 10b
|
||||
j 17f
|
||||
|
||||
/* CLOCK_REALTIME */
|
||||
11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
|
||||
tml %r4,0x0001 /* pending update ? loop */
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
.type __kernel_clock_getres,@function
|
||||
__kernel_clock_getres:
|
||||
.cfi_startproc
|
||||
larl %r1,4f
|
||||
cghi %r2,__CLOCK_REALTIME_COARSE
|
||||
je 0f
|
||||
cghi %r2,__CLOCK_MONOTONIC_COARSE
|
||||
je 0f
|
||||
larl %r1,3f
|
||||
cghi %r2,__CLOCK_REALTIME
|
||||
je 0f
|
||||
cghi %r2,__CLOCK_MONOTONIC
|
||||
|
@ -32,7 +38,6 @@ __kernel_clock_getres:
|
|||
jz 2f
|
||||
0: ltgr %r3,%r3
|
||||
jz 1f /* res == NULL */
|
||||
larl %r1,3f
|
||||
lg %r0,0(%r1)
|
||||
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
|
||||
stg %r0,8(%r3) /* store tp->tv_usec */
|
||||
|
@ -42,5 +47,6 @@ __kernel_clock_getres:
|
|||
svc 0
|
||||
br %r14
|
||||
3: .quad __CLOCK_REALTIME_RES
|
||||
4: .quad __CLOCK_COARSE_RES
|
||||
.cfi_endproc
|
||||
.size __kernel_clock_getres,.-__kernel_clock_getres
|
||||
|
|
|
@ -20,12 +20,16 @@
|
|||
__kernel_clock_gettime:
|
||||
.cfi_startproc
|
||||
larl %r5,_vdso_data
|
||||
cghi %r2,__CLOCK_REALTIME_COARSE
|
||||
je 4f
|
||||
cghi %r2,__CLOCK_REALTIME
|
||||
je 5f
|
||||
cghi %r2,__CLOCK_THREAD_CPUTIME_ID
|
||||
je 9f
|
||||
cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
|
||||
je 9f
|
||||
cghi %r2,__CLOCK_MONOTONIC_COARSE
|
||||
je 3f
|
||||
cghi %r2,__CLOCK_MONOTONIC
|
||||
jne 12f
|
||||
|
||||
|
@ -54,6 +58,26 @@ __kernel_clock_gettime:
|
|||
lghi %r2,0
|
||||
br %r14
|
||||
|
||||
/* CLOCK_MONOTONIC_COARSE */
|
||||
3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
|
||||
tmll %r4,0x0001 /* pending update ? loop */
|
||||
jnz 3b
|
||||
lg %r0,__VDSO_WTOM_CRS_SEC(%r5)
|
||||
lg %r1,__VDSO_WTOM_CRS_NSEC(%r5)
|
||||
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
|
||||
jne 3b
|
||||
j 2b
|
||||
|
||||
/* CLOCK_REALTIME_COARSE */
|
||||
4: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
|
||||
tmll %r4,0x0001 /* pending update ? loop */
|
||||
jnz 4b
|
||||
lg %r0,__VDSO_XTIME_CRS_SEC(%r5)
|
||||
lg %r1,__VDSO_XTIME_CRS_NSEC(%r5)
|
||||
clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
|
||||
jne 4b
|
||||
j 7f
|
||||
|
||||
/* CLOCK_REALTIME */
|
||||
5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
|
||||
tmll %r4,0x0001 /* pending update ? loop */
|
||||
|
|
Загрузка…
Ссылка в новой задаче