[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |