Hey, Over the last weeks, there has been some discussion regarding paravirt lpj calculation for kvm. Here's my shot at that. KVM hypervisor already put the right value in our pvclock structures, as part of the xen compatibility efforts. So the first patch moves the respective xen code to pvclock.c (since we'll be doing the same calculation anyway), while the second, implements functions for kvm that makes use of it. Turns out that only implementing a pv get_tsc_khz is not enough, since it will only do the right thing for cpu0, which is not what we desire. So we set preset_lpj. Recall this code is run before arch parameter setup, so if we pass lpj=xx in the command line, it'll still work. Have a good (paravirtual) time!
KVM intends to use paravirt code to calibrate khz. Xen current code will do just fine. So as a first step, factor out code to pvclock.c. Signed-off-by: Glauber Costa <gcosta at redhat.com> --- arch/x86/kernel/pvclock.c | 12 ++++++++++++ arch/x86/xen/time.c | 11 ++--------- include/asm-x86/pvclock.h | 1 + 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 05fbe9a..1c54b5f 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -97,6 +97,18 @@ static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst, return dst->version; } +unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) +{ + u64 tsc_khz = 1000000ULL << 32; + + do_div(tsc_khz, src->tsc_to_system_mul); + if (src->tsc_shift < 0) + tsc_khz <<= -src->tsc_shift; + else + tsc_khz >>= src->tsc_shift; + return tsc_khz; +} + cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) { struct pvclock_shadow_time shadow; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 685b774..1eb88fe 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -200,17 +200,10 @@ unsigned long long xen_sched_clock(void) /* Get the TSC speed from Xen */ unsigned long xen_tsc_khz(void) { - u64 xen_khz = 1000000ULL << 32; - const struct pvclock_vcpu_time_info *info + struct pvclock_vcpu_time_info *info &HYPERVISOR_shared_info->vcpu_info[0].time; - do_div(xen_khz, info->tsc_to_system_mul); - if (info->tsc_shift < 0) - xen_khz <<= -info->tsc_shift; - else - xen_khz >>= info->tsc_shift; - - return xen_khz; + return pvclock_tsc_khz(info); } static cycle_t xen_clocksource_read(void) diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h index 85b1bba..28783bc 100644 --- a/include/asm-x86/pvclock.h +++ b/include/asm-x86/pvclock.h @@ -6,6 +6,7 @@ /* some helper functions for xen and kvm pv clock sources */ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); +unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct pvclock_vcpu_time_info *vcpu, struct timespec *ts); -- 1.5.5.1
Hi,> Turns out that only implementing a pv get_tsc_khz is not enough, since > it will only do the right thing for cpu0, which is not what we desire. > > So we set preset_lpj. Recall this code is run before arch parameter setup, > so if we pass lpj=xx in the command line, it'll still work.Hmm, why kvm needs the preset_lpj thing and xen doesn't? cheers, Gerd -- http://kraxel.fedorapeople.org/xenner/
Glauber Costa wrote:> Hey, > > Over the last weeks, there has been some discussion regarding paravirt > lpj calculation for kvm. Here's my shot at that. > > KVM hypervisor already put the right value in our pvclock structures, > as part of the xen compatibility efforts. > > So the first patch moves the respective xen code to pvclock.c (since > we'll be doing the same calculation anyway), while the second, implements > functions for kvm that makes use of it. > > Turns out that only implementing a pv get_tsc_khz is not enough, since > it will only do the right thing for cpu0, which is not what we desire. > > So we set preset_lpj. Recall this code is run before arch parameter setup, > so if we pass lpj=xx in the command line, it'll still work. > > Have a good (paravirtual) time! > >I only have this email out of the patchset. Please resend. -- error compiling committee.c: too many arguments to function
Resending, as avi seem to have missed the patches.
KVM intends to use paravirt code to calibrate khz. Xen current code will do just fine. So as a first step, factor out code to pvclock.c. Signed-off-by: Glauber Costa <gcosta at redhat.com> --- arch/x86/kernel/pvclock.c | 12 ++++++++++++ arch/x86/xen/time.c | 11 ++--------- include/asm-x86/pvclock.h | 1 + 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 05fbe9a..1c54b5f 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -97,6 +97,18 @@ static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst, return dst->version; } +unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) +{ + u64 tsc_khz = 1000000ULL << 32; + + do_div(tsc_khz, src->tsc_to_system_mul); + if (src->tsc_shift < 0) + tsc_khz <<= -src->tsc_shift; + else + tsc_khz >>= src->tsc_shift; + return tsc_khz; +} + cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) { struct pvclock_shadow_time shadow; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 685b774..1eb88fe 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -200,17 +200,10 @@ unsigned long long xen_sched_clock(void) /* Get the TSC speed from Xen */ unsigned long xen_tsc_khz(void) { - u64 xen_khz = 1000000ULL << 32; - const struct pvclock_vcpu_time_info *info + struct pvclock_vcpu_time_info *info &HYPERVISOR_shared_info->vcpu_info[0].time; - do_div(xen_khz, info->tsc_to_system_mul); - if (info->tsc_shift < 0) - xen_khz <<= -info->tsc_shift; - else - xen_khz >>= info->tsc_shift; - - return xen_khz; + return pvclock_tsc_khz(info); } static cycle_t xen_clocksource_read(void) diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h index 85b1bba..28783bc 100644 --- a/include/asm-x86/pvclock.h +++ b/include/asm-x86/pvclock.h @@ -6,6 +6,7 @@ /* some helper functions for xen and kvm pv clock sources */ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); +unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct pvclock_vcpu_time_info *vcpu, struct timespec *ts); -- 1.5.5.1