diff mbox

[v4,7/7] xen/x86: support XENPF_settime64

Message ID 1447349448-22610-7-git-send-email-stefano.stabellini@eu.citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefano Stabellini Nov. 12, 2015, 5:30 p.m. UTC
Try XENPF_settime64 first, if it is not available fall back to
XENPF_settime32.

No need to call __current_kernel_time() when all the info needed are
already passed via the struct timekeeper * argument.

Return NOTIFY_BAD in case of errors.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: konrad.wilk@oracle.com
CC: david.vrabel@citrix.com
CC: boris.ostrovsky@oracle.com
---
 arch/x86/xen/time.c |   35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

Comments

Arnd Bergmann Nov. 12, 2015, 7:14 p.m. UTC | #1
On Thursday 12 November 2015 17:30:48 Stefano Stabellini wrote:
> Try XENPF_settime64 first, if it is not available fall back to
> XENPF_settime32.
> 
> No need to call __current_kernel_time() when all the info needed are
> already passed via the struct timekeeper * argument.
> 
> Return NOTIFY_BAD in case of errors.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> CC: konrad.wilk@oracle.com
> CC: david.vrabel@citrix.com
> CC: boris.ostrovsky@oracle.com
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>
David Vrabel Nov. 13, 2015, 10:42 a.m. UTC | #2
On 12/11/15 17:30, Stefano Stabellini wrote:
> Try XENPF_settime64 first, if it is not available fall back to
> XENPF_settime32.
> 
> No need to call __current_kernel_time() when all the info needed are
> already passed via the struct timekeeper * argument.
> 
> Return NOTIFY_BAD in case of errors.
[...]
> @@ -123,9 +124,13 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
>  	static struct timespec next_sync;
>  
>  	struct xen_platform_op op;
> -	struct timespec now;
> +	struct timespec64 now;
> +	struct timekeeper *tk = priv;
> +	static bool settime64_supported = true;
> +	int ret;
>  
> -	now = __current_kernel_time();
> +	now.tv_sec = tk->xtime_sec;
> +	now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);

I think you should introduce __current_kernel_time64() or make
tk_xtime() available.

John, what do you think?

David
Stefano Stabellini Nov. 13, 2015, 10:45 a.m. UTC | #3
On Fri, 13 Nov 2015, David Vrabel wrote:
> On 12/11/15 17:30, Stefano Stabellini wrote:
> > Try XENPF_settime64 first, if it is not available fall back to
> > XENPF_settime32.
> > 
> > No need to call __current_kernel_time() when all the info needed are
> > already passed via the struct timekeeper * argument.
> > 
> > Return NOTIFY_BAD in case of errors.
> [...]
> > @@ -123,9 +124,13 @@ static int xen_pvclock_gtod_notify(struct notifier_block *nb,
> >  	static struct timespec next_sync;
> >  
> >  	struct xen_platform_op op;
> > -	struct timespec now;
> > +	struct timespec64 now;
> > +	struct timekeeper *tk = priv;
> > +	static bool settime64_supported = true;
> > +	int ret;
> >  
> > -	now = __current_kernel_time();
> > +	now.tv_sec = tk->xtime_sec;
> > +	now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
> 
> I think you should introduce __current_kernel_time64() or make
> tk_xtime() available.
> 
> John, what do you think?

We already had this discussion:

http://marc.info/?l=linux-kernel&m=144717103112014&w=2
http://marc.info/?l=linux-kernel&m=144724877203864&w=2
diff mbox

Patch

diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 3bbd377..4b8af45 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -16,6 +16,7 @@ 
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/pvclock_gtod.h>
+#include <linux/timekeeper_internal.h>
 
 #include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
@@ -123,9 +124,13 @@  static int xen_pvclock_gtod_notify(struct notifier_block *nb,
 	static struct timespec next_sync;
 
 	struct xen_platform_op op;
-	struct timespec now;
+	struct timespec64 now;
+	struct timekeeper *tk = priv;
+	static bool settime64_supported = true;
+	int ret;
 
-	now = __current_kernel_time();
+	now.tv_sec = tk->xtime_sec;
+	now.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
 
 	/*
 	 * We only take the expensive HV call when the clock was set
@@ -134,12 +139,28 @@  static int xen_pvclock_gtod_notify(struct notifier_block *nb,
 	if (!was_set && timespec_compare(&now, &next_sync) < 0)
 		return NOTIFY_OK;
 
-	op.cmd = XENPF_settime32;
-	op.u.settime32.secs = now.tv_sec;
-	op.u.settime32.nsecs = now.tv_nsec;
-	op.u.settime32.system_time = xen_clocksource_read();
+again:
+	if (settime64_supported) {
+		op.cmd = XENPF_settime64;
+		op.u.settime64.mbz = 0;
+		op.u.settime64.secs = now.tv_sec;
+		op.u.settime64.nsecs = now.tv_nsec;
+		op.u.settime64.system_time = xen_clocksource_read();
+	} else {
+		op.cmd = XENPF_settime32;
+		op.u.settime32.secs = now.tv_sec;
+		op.u.settime32.nsecs = now.tv_nsec;
+		op.u.settime32.system_time = xen_clocksource_read();
+	}
+
+	ret = HYPERVISOR_platform_op(&op);
 
-	(void)HYPERVISOR_platform_op(&op);
+	if (ret == -ENOSYS && settime64_supported) {
+		settime64_supported = false;
+		goto again;
+	}
+	if (ret < 0)
+		return NOTIFY_BAD;
 
 	/*
 	 * Move the next drift compensation time 11 minutes