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_tod_stamp; /* TOD clock for xtime 0x08 */
|
||||||
__u64 xtime_clock_sec; /* Kernel time 0x10 */
|
__u64 xtime_clock_sec; /* Kernel time 0x10 */
|
||||||
__u64 xtime_clock_nsec; /* 0x18 */
|
__u64 xtime_clock_nsec; /* 0x18 */
|
||||||
__u64 wtom_clock_sec; /* Wall to monotonic clock 0x20 */
|
__u64 xtime_coarse_sec; /* Coarse kernel time 0x20 */
|
||||||
__u64 wtom_clock_nsec; /* 0x28 */
|
__u64 xtime_coarse_nsec; /* 0x28 */
|
||||||
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
|
__u64 wtom_clock_sec; /* Wall to monotonic clock 0x30 */
|
||||||
__u32 tz_dsttime; /* Type of dst correction 0x34 */
|
__u64 wtom_clock_nsec; /* 0x38 */
|
||||||
__u32 ectg_available; /* ECTG instruction present 0x38 */
|
__u64 wtom_coarse_sec; /* Coarse wall to monotonic 0x40 */
|
||||||
__u32 tk_mult; /* Mult. used for xtime_nsec 0x3c */
|
__u64 wtom_coarse_nsec; /* 0x48 */
|
||||||
__u32 tk_shift; /* Shift used for xtime_nsec 0x40 */
|
__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 {
|
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_STAMP, offsetof(struct vdso_data, xtime_tod_stamp));
|
||||||
DEFINE(__VDSO_XTIME_SEC, offsetof(struct vdso_data, xtime_clock_sec));
|
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_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_SEC, offsetof(struct vdso_data, wtom_clock_sec));
|
||||||
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
|
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_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
|
||||||
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
|
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
|
||||||
DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
|
DEFINE(__VDSO_TK_MULT, offsetof(struct vdso_data, tk_mult));
|
||||||
|
@ -73,8 +77,11 @@ int main(void)
|
||||||
/* constants used by the vdso */
|
/* constants used by the vdso */
|
||||||
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
|
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
|
||||||
DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
|
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_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
|
||||||
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
|
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
|
||||||
|
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
|
||||||
BLANK();
|
BLANK();
|
||||||
/* idle data offsets */
|
/* idle data offsets */
|
||||||
DEFINE(__CLOCK_IDLE_ENTER, offsetof(struct s390_idle_data, clock_idle_enter));
|
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_nsec -= nsecps;
|
||||||
vdso_data->wtom_clock_sec++;
|
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_mult = tk->tkr.mult;
|
||||||
vdso_data->tk_shift = tk->tkr.shift;
|
vdso_data->tk_shift = tk->tkr.shift;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
|
|
|
@ -19,14 +19,20 @@
|
||||||
.type __kernel_clock_getres,@function
|
.type __kernel_clock_getres,@function
|
||||||
__kernel_clock_getres:
|
__kernel_clock_getres:
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
|
basr %r1,0
|
||||||
|
la %r1,4f-.(%r1)
|
||||||
chi %r2,__CLOCK_REALTIME
|
chi %r2,__CLOCK_REALTIME
|
||||||
je 0f
|
je 0f
|
||||||
chi %r2,__CLOCK_MONOTONIC
|
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
|
jne 3f
|
||||||
0: ltr %r3,%r3
|
0: ltr %r3,%r3
|
||||||
jz 2f /* res == NULL */
|
jz 2f /* res == NULL */
|
||||||
basr %r1,0
|
1: l %r0,0(%r1)
|
||||||
1: l %r0,4f-1b(%r1)
|
|
||||||
xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */
|
xc 0(4,%r3),0(%r3) /* set tp->tv_sec to zero */
|
||||||
st %r0,4(%r3) /* store tp->tv_usec */
|
st %r0,4(%r3) /* store tp->tv_usec */
|
||||||
2: lhi %r2,0
|
2: lhi %r2,0
|
||||||
|
@ -35,5 +41,6 @@ __kernel_clock_getres:
|
||||||
svc 0
|
svc 0
|
||||||
br %r14
|
br %r14
|
||||||
4: .long __CLOCK_REALTIME_RES
|
4: .long __CLOCK_REALTIME_RES
|
||||||
|
5: .long __CLOCK_COARSE_RES
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
.size __kernel_clock_getres,.-__kernel_clock_getres
|
.size __kernel_clock_getres,.-__kernel_clock_getres
|
||||||
|
|
|
@ -21,8 +21,12 @@ __kernel_clock_gettime:
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
basr %r5,0
|
basr %r5,0
|
||||||
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
|
0: al %r5,21f-0b(%r5) /* get &_vdso_data */
|
||||||
|
chi %r2,__CLOCK_REALTIME_COARSE
|
||||||
|
je 10f
|
||||||
chi %r2,__CLOCK_REALTIME
|
chi %r2,__CLOCK_REALTIME
|
||||||
je 11f
|
je 11f
|
||||||
|
chi %r2,__CLOCK_MONOTONIC_COARSE
|
||||||
|
je 9f
|
||||||
chi %r2,__CLOCK_MONOTONIC
|
chi %r2,__CLOCK_MONOTONIC
|
||||||
jne 19f
|
jne 19f
|
||||||
|
|
||||||
|
@ -68,6 +72,26 @@ __kernel_clock_gettime:
|
||||||
lhi %r2,0
|
lhi %r2,0
|
||||||
br %r14
|
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 */
|
/* CLOCK_REALTIME */
|
||||||
11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
|
11: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */
|
||||||
tml %r4,0x0001 /* pending update ? loop */
|
tml %r4,0x0001 /* pending update ? loop */
|
||||||
|
|
|
@ -19,6 +19,12 @@
|
||||||
.type __kernel_clock_getres,@function
|
.type __kernel_clock_getres,@function
|
||||||
__kernel_clock_getres:
|
__kernel_clock_getres:
|
||||||
.cfi_startproc
|
.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
|
cghi %r2,__CLOCK_REALTIME
|
||||||
je 0f
|
je 0f
|
||||||
cghi %r2,__CLOCK_MONOTONIC
|
cghi %r2,__CLOCK_MONOTONIC
|
||||||
|
@ -32,7 +38,6 @@ __kernel_clock_getres:
|
||||||
jz 2f
|
jz 2f
|
||||||
0: ltgr %r3,%r3
|
0: ltgr %r3,%r3
|
||||||
jz 1f /* res == NULL */
|
jz 1f /* res == NULL */
|
||||||
larl %r1,3f
|
|
||||||
lg %r0,0(%r1)
|
lg %r0,0(%r1)
|
||||||
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
|
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
|
||||||
stg %r0,8(%r3) /* store tp->tv_usec */
|
stg %r0,8(%r3) /* store tp->tv_usec */
|
||||||
|
@ -42,5 +47,6 @@ __kernel_clock_getres:
|
||||||
svc 0
|
svc 0
|
||||||
br %r14
|
br %r14
|
||||||
3: .quad __CLOCK_REALTIME_RES
|
3: .quad __CLOCK_REALTIME_RES
|
||||||
|
4: .quad __CLOCK_COARSE_RES
|
||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
.size __kernel_clock_getres,.-__kernel_clock_getres
|
.size __kernel_clock_getres,.-__kernel_clock_getres
|
||||||
|
|
|
@ -20,12 +20,16 @@
|
||||||
__kernel_clock_gettime:
|
__kernel_clock_gettime:
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
larl %r5,_vdso_data
|
larl %r5,_vdso_data
|
||||||
|
cghi %r2,__CLOCK_REALTIME_COARSE
|
||||||
|
je 4f
|
||||||
cghi %r2,__CLOCK_REALTIME
|
cghi %r2,__CLOCK_REALTIME
|
||||||
je 5f
|
je 5f
|
||||||
cghi %r2,__CLOCK_THREAD_CPUTIME_ID
|
cghi %r2,__CLOCK_THREAD_CPUTIME_ID
|
||||||
je 9f
|
je 9f
|
||||||
cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
|
cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
|
||||||
je 9f
|
je 9f
|
||||||
|
cghi %r2,__CLOCK_MONOTONIC_COARSE
|
||||||
|
je 3f
|
||||||
cghi %r2,__CLOCK_MONOTONIC
|
cghi %r2,__CLOCK_MONOTONIC
|
||||||
jne 12f
|
jne 12f
|
||||||
|
|
||||||
|
@ -54,6 +58,26 @@ __kernel_clock_gettime:
|
||||||
lghi %r2,0
|
lghi %r2,0
|
||||||
br %r14
|
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 */
|
/* CLOCK_REALTIME */
|
||||||
5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
|
5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
|
||||||
tmll %r4,0x0001 /* pending update ? loop */
|
tmll %r4,0x0001 /* pending update ? loop */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче