From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: virtualization@lists.osdl.org, kvm-owner@vger.kernel.org
Subject: Re: [PATCH 2/5] Make xen use the paravirt clocksource structs and functions.
Date: Tue, 03 Jun 2008 14:41:50 +0100 [thread overview]
Message-ID: <48454A1E.2090703@goop.org> (raw)
In-Reply-To: <1212498439-1283-3-git-send-email-kraxel@redhat.com>
Gerd Hoffmann wrote:
> This patch updates the xen guest to use the pvclock structs
> and helper functions.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> arch/x86/xen/Kconfig | 1 +
> arch/x86/xen/time.c | 130 ++++---------------------------------------
> include/xen/interface/xen.h | 5 +-
> 3 files changed, 14 insertions(+), 122 deletions(-)
>
> diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
> index 2e641be..3a4f16a 100644
> --- a/arch/x86/xen/Kconfig
> +++ b/arch/x86/xen/Kconfig
> @@ -5,6 +5,7 @@
> config XEN
> bool "Xen guest support"
> select PARAVIRT
> + select PARAVIRT_CLOCK
> depends on X86_32
> depends on X86_CMPXCHG && X86_TSC && !(X86_VISWS || X86_VOYAGER)
> help
> diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
> index c39e1a5..bf31fb5 100644
> --- a/arch/x86/xen/time.c
> +++ b/arch/x86/xen/time.c
> @@ -13,6 +13,7 @@
> #include <linux/clockchips.h>
> #include <linux/kernel_stat.h>
>
> +#include <asm/pvclock.h>
> #include <asm/xen/hypervisor.h>
> #include <asm/xen/hypercall.h>
>
> @@ -30,17 +31,6 @@
>
> static cycle_t xen_clocksource_read(void);
>
> -/* These are perodically updated in shared_info, and then copied here. */
> -struct shadow_time_info {
> - u64 tsc_timestamp; /* TSC at last update of time vals. */
> - u64 system_timestamp; /* Time, in nanosecs, since boot. */
> - u32 tsc_to_nsec_mul;
> - int tsc_shift;
> - u32 version;
> -};
> -
> -static DEFINE_PER_CPU(struct shadow_time_info, shadow_time);
> -
> /* runstate info updated by Xen */
> static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
>
> @@ -230,121 +220,26 @@ unsigned long xen_cpu_khz(void)
> return xen_khz;
> }
>
> -/*
> - * Reads a consistent set of time-base values from Xen, into a shadow data
> - * area.
> - */
> -static unsigned get_time_values_from_xen(void)
> -{
> - struct vcpu_time_info *src;
> - struct shadow_time_info *dst;
> -
> - /* src is shared memory with the hypervisor, so we need to
> - make sure we get a consistent snapshot, even in the face of
> - being preempted. */
> - src = &__get_cpu_var(xen_vcpu)->time;
> - dst = &__get_cpu_var(shadow_time);
> -
> - do {
> - dst->version = src->version;
> - rmb(); /* fetch version before data */
> - dst->tsc_timestamp = src->tsc_timestamp;
> - dst->system_timestamp = src->system_time;
> - dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
> - dst->tsc_shift = src->tsc_shift;
> - rmb(); /* test version after fetching data */
> - } while ((src->version & 1) | (dst->version ^ src->version));
> -
> - return dst->version;
> -}
> -
> -/*
> - * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
> - * yielding a 64-bit result.
> - */
> -static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
> -{
> - u64 product;
> -#ifdef __i386__
> - u32 tmp1, tmp2;
> -#endif
> -
> - if (shift < 0)
> - delta >>= -shift;
> - else
> - delta <<= shift;
> -
> -#ifdef __i386__
> - __asm__ (
> - "mul %5 ; "
> - "mov %4,%%eax ; "
> - "mov %%edx,%4 ; "
> - "mul %5 ; "
> - "xor %5,%5 ; "
> - "add %4,%%eax ; "
> - "adc %5,%%edx ; "
> - : "=A" (product), "=r" (tmp1), "=r" (tmp2)
> - : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
> -#elif __x86_64__
> - __asm__ (
> - "mul %%rdx ; shrd $32,%%rdx,%%rax"
> - : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
> -#else
> -#error implement me!
> -#endif
> -
> - return product;
> -}
> -
> -static u64 get_nsec_offset(struct shadow_time_info *shadow)
> -{
> - u64 now, delta;
> - now = native_read_tsc();
> - delta = now - shadow->tsc_timestamp;
> - return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
> -}
> -
> static cycle_t xen_clocksource_read(void)
> {
> - struct shadow_time_info *shadow = &get_cpu_var(shadow_time);
> + struct vcpu_time_info *src;
> cycle_t ret;
> - unsigned version;
> -
> - do {
> - version = get_time_values_from_xen();
> - barrier();
> - ret = shadow->system_timestamp + get_nsec_offset(shadow);
> - barrier();
> - } while (version != __get_cpu_var(xen_vcpu)->time.version);
> -
> - put_cpu_var(shadow_time);
>
> + src = &get_cpu_var(xen_vcpu)->time;
> + ret = pvclock_clocksource_read((void*)src);
> + put_cpu_var(xen_vcpu);
> return ret;
> }
>
> static void xen_read_wallclock(struct timespec *ts)
> {
> - const struct shared_info *s = HYPERVISOR_shared_info;
> - u32 version;
> - u64 delta;
> - struct timespec now;
> -
> - /* get wallclock at system boot */
> - do {
> - version = s->wc_version;
> - rmb(); /* fetch version before time */
> - now.tv_sec = s->wc_sec;
> - now.tv_nsec = s->wc_nsec;
> - rmb(); /* fetch time before checking version */
> - } while ((s->wc_version & 1) | (version ^ s->wc_version));
> + struct shared_info *s = HYPERVISOR_shared_info;
> + struct pvclock_wall_clock *wall_clock = &(s->wc);
> + struct vcpu_time_info *vcpu_time;
>
> - delta = xen_clocksource_read(); /* time since system boot */
> - delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec;
> -
> - now.tv_nsec = do_div(delta, NSEC_PER_SEC);
> - now.tv_sec = delta;
> -
> - set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
> + vcpu_time = &get_cpu_var(xen_vcpu)->time;
> + pvclock_read_wallclock(wall_clock, (void*)vcpu_time, ts);
>
Why this cast here? Because the corresponding struct in vcpu_info
hasn't been updated to match?
J
next prev parent reply other threads:[~2008-06-03 13:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-03 13:07 [PATCH 0/5] paravirt clock source patches, #4 Gerd Hoffmann
2008-06-03 13:07 ` [PATCH 1/5] Add structs and functions for paravirt clocksource Gerd Hoffmann
2008-06-03 13:34 ` Jeremy Fitzhardinge
2008-06-03 13:07 ` [PATCH 2/5] Make xen use the paravirt clocksource structs and functions Gerd Hoffmann
2008-06-03 13:41 ` Jeremy Fitzhardinge [this message]
2008-06-03 13:07 ` [PATCH 3/5] Make kvm host use the paravirt clocksource structs Gerd Hoffmann
2008-06-03 13:07 ` [PATCH 4/5] Make kvm guest use the paravirt clocksource structs and functions Gerd Hoffmann
2008-06-03 13:07 ` [PATCH 5/5] Remove now unused structs from kvm_para.h Gerd Hoffmann
2008-06-03 13:26 ` David Miller
2008-06-03 13:42 ` [PATCH 0/5] paravirt clock source patches, #4 Jeremy Fitzhardinge
2008-06-03 13:46 ` Gerd Hoffmann
2008-06-03 13:49 ` Gerd Hoffmann
2008-06-04 14:01 ` Avi Kivity
2008-06-16 13:53 ` Avi Kivity
-- strict thread matches above, loose matches on Subject: below --
2008-06-03 14:17 [PATCH 0/5] paravirt clock source patches, #5 Gerd Hoffmann
2008-06-03 14:17 ` [PATCH 2/5] Make xen use the paravirt clocksource structs and functions Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48454A1E.2090703@goop.org \
--to=jeremy@goop.org \
--cc=kraxel@redhat.com \
--cc=kvm-owner@vger.kernel.org \
--cc=virtualization@lists.osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.