[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v4 1/3] xen: move wallclock functions from x86 to common



On Thu, 2015-11-12 at 17:46 +0000, Stefano Stabellini wrote:
> Remove dummy arm implementation of wallclock_time.
> Use shared_info() in common code rather than x86-ism to access it, when
> possible.
> 
> Define the static variable wc_sec, and the local variale sec in

                         Âvariable

> update_domain_wallclock_time, as uint64_t instead of unsigned long, to
> avoid size issue on arm.

      Âissues

> Take a uint64_t sec paramter in do_settime for the same reason.

           parameter

> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> Acked-by: Jan Beulich <jbeulich@xxxxxxxx>

Apart from the typos:

Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

> CC: JBeulich@xxxxxxxx
> CC: andrew.cooper3@xxxxxxxxxx
> 
> ---
> 
> Changes in v3:
> - remove stray blank lines
> 
> Changes in v2:
> - remove stray blank lines
> - remove include <xen/config.h>
> - move version_update_* to include/xen/time.h
> - introduce ifdef to fix build issue in common/time.c
> - define wc_sec and sec as uint64_t
> - pass u64 to do_settime
> ---
> Âxen/arch/arm/time.cÂÂÂÂ|ÂÂÂÂ5 ---
> Âxen/arch/x86/time.cÂÂÂÂ|ÂÂÂ96 +-----------------------------------------
> ------
> Âxen/common/time.cÂÂÂÂÂÂ|ÂÂÂ95
> ++++++++++++++++++++++++++++++++++++++++++++++-
> Âxen/include/xen/time.h |ÂÂÂÂ5 ++-
> Â4 files changed, 99 insertions(+), 102 deletions(-)
> 
> diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
> index 5ded30c..6207615 100644
> --- a/xen/arch/arm/time.c
> +++ b/xen/arch/arm/time.c
> @@ -280,11 +280,6 @@ void domain_set_time_offset(struct domain *d,
> int64_t time_offset_seconds)
> ÂÂÂÂÂ/* XXX update guest visible wallclock time */
> Â}
> Â
> -struct tm wallclock_time(uint64_t *ns)
> -{
> -ÂÂÂÂreturn (struct tm) { 0 };
> -}
> -
> Â/*
> Â * Local variables:
> Â * mode: C
> diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
> index bbb7e6c..0f16db5 100644
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -47,9 +47,6 @@ string_param("clocksource", opt_clocksource);
> Âunsigned long __read_mostly cpu_khz;ÂÂ/* CPU clock frequency in kHz. */
> ÂDEFINE_SPINLOCK(rtc_lock);
> Âunsigned long pit0_ticks;
> -static unsigned long wc_sec; /* UTC time at last 'time update'. */
> -static unsigned int wc_nsec;
> -static DEFINE_SPINLOCK(wc_lock);
> Â
> Âstruct cpu_time {
> ÂÂÂÂÂu64 local_tsc_stamp;
> @@ -783,10 +780,6 @@ uint64_t tsc_ticks2ns(uint64_t ticks)
> ÂÂÂÂÂreturn scale_delta(ticks, &t->tsc_scale);
> Â}
> Â
> -/* Explicitly OR with 1 just in case version number gets out of sync. */
> -#define version_update_begin(v) (((v)+1)|1)
> -#define version_update_end(v)ÂÂÂ((v)+1)
> -
> Âstatic void __update_vcpu_system_time(struct vcpu *v, int force)
> Â{
> ÂÂÂÂÂstruct cpu_timeÂÂÂÂÂÂÂ*t;
> @@ -900,37 +893,6 @@ void force_update_vcpu_system_time(struct vcpu *v)
> ÂÂÂÂÂ__update_vcpu_system_time(v, 1);
> Â}
> Â
> -void update_domain_wallclock_time(struct domain *d)
> -{
> -ÂÂÂÂuint32_t *wc_version;
> -ÂÂÂÂunsigned long sec;
> -
> -ÂÂÂÂspin_lock(&wc_lock);
> -
> -ÂÂÂÂwc_version = &shared_info(d, wc_version);
> -ÂÂÂÂ*wc_version = version_update_begin(*wc_version);
> -ÂÂÂÂwmb();
> -
> -ÂÂÂÂsec = wc_sec + d->time_offset_seconds;
> -ÂÂÂÂif ( likely(!has_32bit_shinfo(d)) )
> -ÂÂÂÂ{
> -ÂÂÂÂÂÂÂÂd->shared_info->native.wc_secÂÂÂÂ= sec;
> -ÂÂÂÂÂÂÂÂd->shared_info->native.wc_nsecÂÂÂ= wc_nsec;
> -ÂÂÂÂÂÂÂÂd->shared_info->native.wc_sec_hi = sec >> 32;
> -ÂÂÂÂ}
> -ÂÂÂÂelse
> -ÂÂÂÂ{
> -ÂÂÂÂÂÂÂÂd->shared_info->compat.wc_secÂÂÂÂÂÂÂÂÂ= sec;
> -ÂÂÂÂÂÂÂÂd->shared_info->compat.wc_nsecÂÂÂÂÂÂÂÂ= wc_nsec;
> -ÂÂÂÂÂÂÂÂd->shared_info->compat.arch.wc_sec_hi = sec >> 32;
> -ÂÂÂÂ}
> -
> -ÂÂÂÂwmb();
> -ÂÂÂÂ*wc_version = version_update_end(*wc_version);
> -
> -ÂÂÂÂspin_unlock(&wc_lock);
> -}
> -
> Âstatic void update_domain_rtc(void)
> Â{
> ÂÂÂÂÂstruct domain *d;
> @@ -988,27 +950,6 @@ int cpu_frequency_change(u64 freq)
> ÂÂÂÂÂreturn 0;
> Â}
> Â
> -/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
> -void do_settime(unsigned long secs, unsigned int nsecs, u64
> system_time_base)
> -{
> -ÂÂÂÂu64 x;
> -ÂÂÂÂu32 y;
> -ÂÂÂÂstruct domain *d;
> -
> -ÂÂÂÂx = SECONDS(secs) + nsecs - system_time_base;
> -ÂÂÂÂy = do_div(x, 1000000000);
> -
> -ÂÂÂÂspin_lock(&wc_lock);
> -ÂÂÂÂwc_secÂÂ= x;
> -ÂÂÂÂwc_nsec = y;
> -ÂÂÂÂspin_unlock(&wc_lock);
> -
> -ÂÂÂÂrcu_read_lock(&domlist_read_lock);
> -ÂÂÂÂfor_each_domain ( d )
> -ÂÂÂÂÂÂÂÂupdate_domain_wallclock_time(d);
> -ÂÂÂÂrcu_read_unlock(&domlist_read_lock);
> -}
> -
> Â/* Per-CPU communication between rendezvous IRQ and softirq handler. */
> Âstruct cpu_calibration {
> ÂÂÂÂÂu64 local_tsc_stamp;
> @@ -1608,25 +1549,6 @@ void send_timer_event(struct vcpu *v)
> ÂÂÂÂÂsend_guest_vcpu_virq(v, VIRQ_TIMER);
> Â}
> Â
> -/* Return secs after 00:00:00 localtime, 1 January, 1970. */
> -unsigned long get_localtime(struct domain *d)
> -{
> -ÂÂÂÂreturn wc_sec + (wc_nsec + NOW()) / 1000000000ULL 
> -ÂÂÂÂÂÂÂÂ+ d->time_offset_seconds;
> -}
> -
> -/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
> -uint64_t get_localtime_us(struct domain *d)
> -{
> -ÂÂÂÂreturn (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
> -ÂÂÂÂÂÂÂÂÂÂÂ/ 1000UL;
> -}
> -
> -unsigned long get_sec(void)
> -{
> -ÂÂÂÂreturn wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
> -}
> -
> Â/* "cmos_utc_offset" is the difference between UTC time and CMOS time.
> */
> Âstatic long cmos_utc_offset; /* in seconds */
> Â
> @@ -1635,7 +1557,7 @@ int time_suspend(void)
> ÂÂÂÂÂif ( smp_processor_id() == 0 )
> ÂÂÂÂÂ{
> ÂÂÂÂÂÂÂÂÂcmos_utc_offset = -get_cmos_time();
> -ÂÂÂÂÂÂÂÂcmos_utc_offset += (wc_sec + (wc_nsec + NOW()) / 1000000000ULL);
> +ÂÂÂÂÂÂÂÂcmos_utc_offset += get_sec();
> ÂÂÂÂÂÂÂÂÂkill_timer(&calibration_timer);
> Â
> ÂÂÂÂÂÂÂÂÂ/* Sync platform timer stamps. */
> @@ -1715,22 +1637,6 @@ int hwdom_pit_access(struct ioreq *ioreq)
> ÂÂÂÂÂreturn 0;
> Â}
> Â
> -struct tm wallclock_time(uint64_t *ns)
> -{
> -ÂÂÂÂuint64_t seconds, nsec;
> -
> -ÂÂÂÂif ( !wc_sec )
> -ÂÂÂÂÂÂÂÂreturn (struct tm) { 0 };
> -
> -ÂÂÂÂseconds = NOW() + SECONDS(wc_sec) + wc_nsec;
> -ÂÂÂÂnsec = do_div(seconds, 1000000000);
> -
> -ÂÂÂÂif ( ns )
> -ÂÂÂÂÂÂÂÂ*ns = nsec;
> -
> -ÂÂÂÂreturn gmtime(seconds);
> -}
> -
> Â/*
> Â * PV SoftTSC Emulation.
> Â */
> diff --git a/xen/common/time.c b/xen/common/time.c
> index 29fdf52..721ada8 100644
> --- a/xen/common/time.c
> +++ b/xen/common/time.c
> @@ -15,8 +15,12 @@
> Â * along with this program; If not, see <http://www.gnu.org/licenses/>.
> Â */
> Â
> -#include <xen/config.h>
> +#include <xen/sched.h>
> +#include <xen/shared.h>
> +#include <xen/spinlock.h>
> Â#include <xen/time.h>
> +#include <asm/div64.h>
> +#include <asm/domain.h>
> Â
> Â/* Nonzero if YEAR is a leap year (every 4 years,
> ÂÂÂÂexcept every 100th isn't, and every 400th is).ÂÂ*/
> @@ -34,6 +38,10 @@ const unsigned short int __mon_lengths[2][12] = {
> Â#define SECS_PER_HOUR (60 * 60)
> Â#define SECS_PER_DAYÂÂ(SECS_PER_HOUR * 24)
> Â
> +static uint64_t wc_sec; /* UTC time at last 'time update'. */
> +static unsigned int wc_nsec;
> +static DEFINE_SPINLOCK(wc_lock);
> +
> Âstruct tm gmtime(unsigned long t)
> Â{
> ÂÂÂÂÂstruct tm tbuf;
> @@ -85,3 +93,88 @@ struct tm gmtime(unsigned long t)
> Â
> ÂÂÂÂÂreturn tbuf;
> Â}
> +
> +void update_domain_wallclock_time(struct domain *d)
> +{
> +ÂÂÂÂuint32_t *wc_version;
> +ÂÂÂÂuint64_t sec;
> +
> +ÂÂÂÂspin_lock(&wc_lock);
> +
> +ÂÂÂÂwc_version = &shared_info(d, wc_version);
> +ÂÂÂÂ*wc_version = version_update_begin(*wc_version);
> +ÂÂÂÂwmb();
> +
> +ÂÂÂÂsec = wc_sec + d->time_offset_seconds;
> +ÂÂÂÂshared_info(d, wc_sec)ÂÂÂÂ= sec;
> +ÂÂÂÂshared_info(d, wc_nsec)ÂÂÂ= wc_nsec;
> +#ifdef CONFIG_X86
> +ÂÂÂÂif ( likely(!has_32bit_shinfo(d)) )
> +ÂÂÂÂÂÂÂÂd->shared_info->native.wc_sec_hi = sec >> 32;
> +ÂÂÂÂelse
> +ÂÂÂÂÂÂÂÂd->shared_info->compat.arch.wc_sec_hi = sec >> 32;
> +#else
> +ÂÂÂÂshared_info(d, wc_sec_hi) = sec >> 32;
> +#endif
> +
> +ÂÂÂÂwmb();
> +ÂÂÂÂ*wc_version = version_update_end(*wc_version);
> +
> +ÂÂÂÂspin_unlock(&wc_lock);
> +}
> +
> +/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
> +void do_settime(u64 secs, unsigned int nsecs, u64 system_time_base)
> +{
> +ÂÂÂÂu64 x;
> +ÂÂÂÂu32 y;
> +ÂÂÂÂstruct domain *d;
> +
> +ÂÂÂÂx = SECONDS(secs) + nsecs - system_time_base;
> +ÂÂÂÂy = do_div(x, 1000000000);
> +
> +ÂÂÂÂspin_lock(&wc_lock);
> +ÂÂÂÂwc_secÂÂ= x;
> +ÂÂÂÂwc_nsec = y;
> +ÂÂÂÂspin_unlock(&wc_lock);
> +
> +ÂÂÂÂrcu_read_lock(&domlist_read_lock);
> +ÂÂÂÂfor_each_domain ( d )
> +ÂÂÂÂÂÂÂÂupdate_domain_wallclock_time(d);
> +ÂÂÂÂrcu_read_unlock(&domlist_read_lock);
> +}
> +
> +/* Return secs after 00:00:00 localtime, 1 January, 1970. */
> +unsigned long get_localtime(struct domain *d)
> +{
> +ÂÂÂÂreturn wc_sec + (wc_nsec + NOW()) / 1000000000ULL
> +ÂÂÂÂÂÂÂÂ+ d->time_offset_seconds;
> +}
> +
> +/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
> +uint64_t get_localtime_us(struct domain *d)
> +{
> +ÂÂÂÂreturn (SECONDS(wc_sec + d->time_offset_seconds) + wc_nsec + NOW())
> +ÂÂÂÂÂÂÂÂÂÂÂ/ 1000UL;
> +}
> +
> +unsigned long get_sec(void)
> +{
> +ÂÂÂÂreturn wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
> +}
> +
> +struct tm wallclock_time(uint64_t *ns)
> +{
> +ÂÂÂÂuint64_t seconds, nsec;
> +
> +ÂÂÂÂif ( !wc_sec )
> +ÂÂÂÂÂÂÂÂreturn (struct tm) { 0 };
> +
> +ÂÂÂÂseconds = NOW() + SECONDS(wc_sec) + wc_nsec;
> +ÂÂÂÂnsec = do_div(seconds, 1000000000);
> +
> +ÂÂÂÂif ( ns )
> +ÂÂÂÂÂÂÂÂ*ns = nsec;
> +
> +ÂÂÂÂreturn gmtime(seconds);
> +}
> diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h
> index da4e8d7..b742746 100644
> --- a/xen/include/xen/time.h
> +++ b/xen/include/xen/time.h
> @@ -60,11 +60,14 @@ struct tm wallclock_time(uint64_t *ns);
> Â/* Chosen so (NOW() + delta) wont overflow without an uptime of 200
> years */
> Â#define STIME_DELTA_MAX ((s_time_t)((uint64_t)~0ull>>2))
> Â
> +/* Explicitly OR with 1 just in case version number gets out of sync. */
> +#define version_update_begin(v) (((v) + 1) | 1)
> +#define version_update_end(v)ÂÂÂ((v) + 1)
> Âextern void update_vcpu_system_time(struct vcpu *v);
> Âextern void update_domain_wallclock_time(struct domain *d);
> Â
> Âextern void do_settime(
> -ÂÂÂÂunsigned long secs, unsigned int nsecs, u64 system_time_base);
> +ÂÂÂÂu64 secs, unsigned int nsecs, u64 system_time_base);
> Â
> Âextern void send_timer_event(struct vcpu *v);
> Â

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.