Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7eacb59 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 070b7be6
Loading
Loading
Loading
Loading
+11 −7
Original line number Original line Diff line number Diff line
@@ -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 {
+7 −0
Original line number Original line Diff line number Diff line
@@ -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));
+13 −0
Original line number Original line Diff line number Diff line
@@ -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();
+9 −2
Original line number Original line Diff line number Diff line
@@ -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
+24 −0
Original line number Original line Diff line number Diff line
@@ -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 */
Loading