Align periodic vpts Aligned periodic vpts can improve the HVM guest power consumption a lot, especially while the guest using high HZ such as 1000HZ. This patch aligns all periodic vpts to the period bound by default. It is still possible to cannel the forced alignment via giving the new per-domain config option "vpt_align=0". Signed-off-by: Wei Gang diff -r b999142bca8c tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Fri Jan 09 16:56:54 2009 +0000 +++ b/tools/python/xen/xend/XendConfig.py Fri Feb 13 14:40:36 2009 +0800 @@ -157,6 +157,7 @@ XENAPI_PLATFORM_CFG_TYPES = { 'vncdisplay': int, 'vnclisten': str, 'timer_mode': int, + 'vpt_align': int, 'viridian': int, 'vncpasswd': str, 'vncunused': int, @@ -458,6 +459,8 @@ class XendConfig(dict): self['platform']['rtc_timeoffset'] = 0 if 'hpet' not in self['platform']: self['platform']['hpet'] = 0 + if 'vpt_align' not in self['platform']: + self['platform']['vpt_align'] = 1 if 'loader' not in self['platform']: # Old configs may have hvmloader set as PV_kernel param if self.has_key('PV_kernel') and self['PV_kernel'] != '': diff -r b999142bca8c tools/python/xen/xend/XendConstants.py --- a/tools/python/xen/xend/XendConstants.py Fri Jan 09 16:56:54 2009 +0000 +++ b/tools/python/xen/xend/XendConstants.py Fri Feb 13 14:40:36 2009 +0800 @@ -50,6 +50,7 @@ HVM_PARAM_TIMER_MODE = 10 HVM_PARAM_TIMER_MODE = 10 HVM_PARAM_HPET_ENABLED = 11 HVM_PARAM_ACPI_S_STATE = 14 +HVM_PARAM_VPT_ALIGN = 16 restart_modes = [ "restart", diff -r b999142bca8c tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Fri Jan 09 16:56:54 2009 +0000 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Feb 13 14:40:36 2009 +0800 @@ -2236,6 +2236,12 @@ class XendDomainInfo: if hvm and hpet is not None: xc.hvm_set_param(self.domid, HVM_PARAM_HPET_ENABLED, long(hpet)) + + # Optionally enable periodic vpt aligning + vpt_align = self.info["platform"].get("vpt_align") + if hvm and vpt_align is not None: + xc.hvm_set_param(self.domid, HVM_PARAM_VPT_ALIGN, + long(vpt_align)) # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) diff -r b999142bca8c tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Fri Jan 09 16:56:54 2009 +0000 +++ b/tools/python/xen/xm/create.py Fri Feb 13 14:40:36 2009 +0800 @@ -218,6 +218,10 @@ gopts.var('timer_mode', val='TIMER_MODE' fn=set_int, default=1, use="""Timer mode (0=delay virtual time when ticks are missed; 1=virtual time is always wallclock time.""") + +gopts.var('vpt_align', val='VPT_ALIGN', + fn=set_int, default=1, + use="Enable aligning all periodic vpt to reduce timer interrupts.") gopts.var('viridian', val='VIRIDIAN', fn=set_int, default=0, @@ -889,7 +893,8 @@ def configure_hvm(config_image, vals): 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet', 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check', - 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate' ] + 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate', + 'vpt_align' ] for a in args: if a in vals.__dict__ and vals.__dict__[a] is not None: diff -r b999142bca8c tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Fri Jan 09 16:56:54 2009 +0000 +++ b/tools/python/xen/xm/xenapi_create.py Fri Feb 13 14:40:36 2009 +0800 @@ -1037,6 +1037,7 @@ class sxp2xml: 'usbdevice', 'hpet', 'timer_mode', + 'vpt_align', 'viridian', 'vhpt', 'guest_os_type', diff -r b999142bca8c xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Fri Jan 09 16:56:54 2009 +0000 +++ b/xen/arch/x86/hvm/hvm.c Fri Feb 13 14:40:36 2009 +0800 @@ -306,6 +306,7 @@ int hvm_domain_initialise(struct domain hvm_init_guest_time(d); d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; + d->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] = 1; hvm_init_cacheattr_region_list(d); diff -r b999142bca8c xen/arch/x86/hvm/vpt.c --- a/xen/arch/x86/hvm/vpt.c Fri Jan 09 16:56:54 2009 +0000 +++ b/xen/arch/x86/hvm/vpt.c Fri Feb 13 14:40:36 2009 +0800 @@ -389,8 +389,14 @@ void create_periodic_time( * LAPIC ticks for process accounting can see long sequences of process * ticks incorrectly accounted to interrupt processing. */ - if ( !pt->one_shot && (pt->source == PTSRC_lapic) ) - pt->scheduled += delta >> 1; + if ( !pt->one_shot ) + { + if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] ) + pt->scheduled = align_timer(pt->scheduled, pt->period); + else if ( pt->source == PTSRC_lapic ) + pt->scheduled += delta >> 1; + } + pt->cb = cb; pt->priv = data; diff -r b999142bca8c xen/common/timer.c --- a/xen/common/timer.c Fri Jan 09 16:56:54 2009 +0000 +++ b/xen/common/timer.c Fri Feb 13 14:40:36 2009 +0800 @@ -473,6 +473,13 @@ void process_pending_timers(void) timer_softirq_action(); } +s_time_t align_timer(s_time_t firsttick, uint64_t period) +{ + if ( !period ) + return firsttick; + + return firsttick + (period - 1) - ((firsttick - 1) % period); +} static void dump_timerq(unsigned char key) { diff -r b999142bca8c xen/include/public/hvm/params.h --- a/xen/include/public/hvm/params.h Fri Jan 09 16:56:54 2009 +0000 +++ b/xen/include/public/hvm/params.h Fri Feb 13 14:40:36 2009 +0800 @@ -103,6 +103,9 @@ /* TSS used on Intel when CR0.PE=0. */ #define HVM_PARAM_VM86_TSS 15 -#define HVM_NR_PARAMS 16 +/* Boolean: Enable aligning all periodic vpts to reduce interrupts */ +#define HVM_PARAM_VPT_ALIGN 16 + +#define HVM_NR_PARAMS 17 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff -r b999142bca8c xen/include/xen/timer.h --- a/xen/include/xen/timer.h Fri Jan 09 16:56:54 2009 +0000 +++ b/xen/include/xen/timer.h Fri Feb 13 14:40:36 2009 +0800 @@ -122,6 +122,9 @@ DECLARE_PER_CPU(s_time_t, timer_deadline /* Arch-defined function to reprogram timer hardware for new deadline. */ extern int reprogram_timer(s_time_t timeout); +/* calculate the aligned first tick time for a given periodic timer */ +extern s_time_t align_timer(s_time_t firsttick, uint64_t period); + #endif /* _TIMER_H_ */ /*