From mboxrd@z Thu Jan 1 00:00:00 1970 From: Qin Li Subject: Re: Could you please answer some questions regarding Solaris PVHVM pvclock support. Date: Wed, 26 Feb 2014 19:52:26 +0800 Message-ID: <530DD57A.8010709@oracle.com> References: <52D6566C.5050302@oracle.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6448543515923308066==" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Stefano Stabellini Cc: xen-devel@lists.xensource.com, Roger Pau Monne List-Id: xen-devel@lists.xenproject.org This is a multi-part message in MIME format. --===============6448543515923308066== Content-Type: multipart/alternative; boundary="------------090008050007090005050903" This is a multi-part message in MIME format. --------------090008050007090005050903 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit ? 2014/1/16 20:17, Stefano Stabellini ??: >> . For a PV-on-HVM guest OS, the "shared_info->vcpu_info->vcpu_time_info" >> >is already visiable. Does guest OS still need any action to ask >> >hypervisor to update this piece of memory periodically? > I don't think you need to ask the hypervisor to update vcpu_time_info > periodically, what gave you that idea? Hi Stefano, Now, I see it's the hypervisor that will update vcpu_time_info, but another thing confuse me: HVM guest has time drift issue because TSC on different vCPU could be out-of-sync, especially after domain suspend/resume. But how pvclock actually fix this issue? Let's see how FreeBSD port calculate the system time: ================== static uint64_t get_nsec_offset(struct vcpu_time_info *tinfo) { return (scale_delta*(rdtsc() -* tinfo->tsc_timestamp, tinfo->tsc_to_system_mul, tinfo->tsc_shift)); } /** * \brief Get the current time, in nanoseconds, since the hypervisor booted. * * \note This function returns the current CPU's idea of this value, unless * it happens to be less than another CPU's previously determined value. */ static uint64_t xen_fetch_vcpu_time(void) { struct vcpu_time_info dst; struct vcpu_time_info *src; uint32_t pre_version; uint64_t now; volatile uint64_t last; struct vcpu_info *vcpu = DPCPU_GET(vcpu_info); src = &vcpu->time; critical_enter(); do { pre_version = xen_fetch_vcpu_tinfo(&dst, src); barrier(); now = dst.system_time + *get_nsec_offset(&dst);* barrier(); } while (pre_version != src->version); /* * Enforce a monotonically increasing clock time across all * VCPUs. If our time is too old, use the last time and return. * Otherwise, try to update the last time. */ do { last = last_time; if (last > now) { now = last; break; } } while (!atomic_cmpset_64(&last_time, last, now)); critical_exit(); return (now); } ================================== I guest linux guest will do the same thing, rdtsc() fetch current timestamp from current running vCPU, TSC out-of-sync issue is still there. It seems to me pvclock finally fix the time drift issue just because the workaround enforced as above, right? Thanks, Michael --------------090008050007090005050903 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
于 2014/1/16 20:17, Stefano Stabellini 写道:
. For a PV-on-HVM guest OS, the "shared_info->vcpu_info->vcpu_time_info"
> is already visiable. Does guest OS still need any action to ask
> hypervisor to update this piece of memory periodically?
I don't think you need to ask the hypervisor to update vcpu_time_info
periodically, what gave you that idea?
Hi Stefano,

Now, I see it's the hypervisor that will update vcpu_time_info, but another thing confuse me:
HVM guest has time drift issue because TSC on different vCPU could be out-of-sync, especially after domain suspend/resume.
But how pvclock actually fix this issue? Let's see how FreeBSD port calculate the system time:

==================
static uint64_t
get_nsec_offset(struct vcpu_time_info *tinfo)
{

    return (scale_delta(rdtsc() - tinfo->tsc_timestamp,
        tinfo->tsc_to_system_mul, tinfo->tsc_shift));
}

/**
 * \brief Get the current time, in nanoseconds, since the hypervisor booted.
 *
 * \note This function returns the current CPU's idea of this value, unless
 *       it happens to be less than another CPU's previously determined value.
 */
static uint64_t
xen_fetch_vcpu_time(void)
{
    struct vcpu_time_info dst;
    struct vcpu_time_info *src;
    uint32_t pre_version;
    uint64_t now;
    volatile uint64_t last;
    struct vcpu_info *vcpu = DPCPU_GET(vcpu_info);

    src = &vcpu->time;

    critical_enter();
    do {
        pre_version = xen_fetch_vcpu_tinfo(&dst, src);
        barrier();
        now = dst.system_time + get_nsec_offset(&dst);
        barrier();
    } while (pre_version != src->version);

    /*
     * Enforce a monotonically increasing clock time across all
     * VCPUs.  If our time is too old, use the last time and return.
     * Otherwise, try to update the last time.
     */
    do {
        last = last_time;
        if (last > now) {
            now = last;
            break;
        }
    } while (!atomic_cmpset_64(&last_time, last, now));

    critical_exit();

    return (now);
}
==================================

I guest linux guest will do the same thing, rdtsc() fetch current timestamp from current running vCPU, TSC out-of-sync issue is still there.
It seems to me pvclock finally fix the time drift issue just because the workaround enforced as above, right?

Thanks,
Michael
 

--------------090008050007090005050903-- --===============6448543515923308066== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============6448543515923308066==--