Stefano Stabellini
2011-Nov-18 14:04 UTC
[PATCH 0/3] prevent qemu-xen-traditional from waking up needlessly
Hi all, this small patch series prevents qemu-xen-traditional from waking up needlessly several times a second in order to check some timers. The first patch makes use of a new mechanism to receive buffered io event notifications from Xen, so that qemu doesn''t need to check the buffered io page for data 10 times a sec for the entire life of the VM. The second patch stops qemu-xen-traditional from starting some timers for RTC emulation; they are not needed because the RTC is already emulated in the hypervisor. Finally the last patch increases the default select timeout to 1h: nothing should rely on the select timeout to be 1sec, so we might as well increase it to 1h. Stefano Stabellini (3): xen: introduce an event channel for buffered io event notifications xen: don''t initialize the RTC timers if xen is available increase minimum timeout to 1h hw/mc146818rtc.c | 2 ++ i386-dm/helper2.c | 45 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) Cheers, Stefano
<stefano.stabellini@eu.citrix.com>
2011-Nov-18 14:05 UTC
[PATCH 1/3] xen: introduce an event channel for buffered io event notifications
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Use the newly introduced HVM_PARAM_BUFIOREQ_EVTCHN to receive notifications for buffered io events. After the first notification is received leave the event channel masked and setup a timer to process the rest of the batch. Once we have completed processing the batch, unmask the event channel and delete the timer. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- i386-dm/helper2.c | 41 +++++++++++++++++++++++++++++++++++------ 1 files changed, 35 insertions(+), 6 deletions(-) diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index 481c620..b121e30 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -111,12 +111,15 @@ int send_vcpu = 0; //the evtchn port for polling the notification, evtchn_port_t *ioreq_local_port; +/* evtchn local port for buffered io */ +evtchn_port_t bufioreq_local_port; CPUX86State *cpu_x86_init(const char *cpu_model) { CPUX86State *env; static int inited; int i, rc; + unsigned long bufioreq_evtchn; env = qemu_mallocz(sizeof(CPUX86State)); if (!env) @@ -154,6 +157,19 @@ CPUX86State *cpu_x86_init(const char *cpu_model) } ioreq_local_port[i] = rc; } + rc = xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_EVTCHN, + &bufioreq_evtchn); + if (rc < 0) { + fprintf(logfile, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN error=%d\n", + errno); + return NULL; + } + rc = xc_evtchn_bind_interdomain(xce_handle, domid, (uint32_t)bufioreq_evtchn); + if (rc == -1) { + fprintf(logfile, "bind interdomain ioctl error %d\n", errno); + return NULL; + } + bufioreq_local_port = rc; } return env; @@ -263,6 +279,12 @@ static ioreq_t *cpu_get_ioreq(void) evtchn_port_t port; port = xc_evtchn_pending(xce_handle); + if (port == bufioreq_local_port) { + qemu_mod_timer(buffered_io_timer, + BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock)); + return NULL; + } + if (port != -1) { for ( i = 0; i < vcpus; i++ ) if ( ioreq_local_port[i] == port ) @@ -459,14 +481,16 @@ static void __handle_ioreq(CPUState *env, ioreq_t *req) } } -static void __handle_buffered_iopage(CPUState *env) +static int __handle_buffered_iopage(CPUState *env) { buf_ioreq_t *buf_req = NULL; ioreq_t req; int qw; if (!buffered_io_page) - return; + return 0; + + memset(&req, 0x00, sizeof(req)); while (buffered_io_page->read_pointer ! buffered_io_page->write_pointer) { @@ -493,15 +517,21 @@ static void __handle_buffered_iopage(CPUState *env) xen_mb(); buffered_io_page->read_pointer += qw ? 2 : 1; } + + return req.count; } static void handle_buffered_io(void *opaque) { CPUState *env = opaque; - __handle_buffered_iopage(env); - qemu_mod_timer(buffered_io_timer, BUFFER_IO_MAX_DELAY + - qemu_get_clock(rt_clock)); + if (__handle_buffered_iopage(env)) { + qemu_mod_timer(buffered_io_timer, + BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock)); + } else { + qemu_del_timer(buffered_io_timer); + xc_evtchn_unmask(xce_handle, bufioreq_local_port); + } } static void cpu_handle_ioreq(void *opaque) @@ -561,7 +591,6 @@ int main_loop(void) buffered_io_timer = qemu_new_timer(rt_clock, handle_buffered_io, cpu_single_env); - qemu_mod_timer(buffered_io_timer, qemu_get_clock(rt_clock)); if (evtchn_fd != -1) qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env); -- 1.7.2.5
<stefano.stabellini@eu.citrix.com>
2011-Nov-18 14:05 UTC
[PATCH 2/3] xen: don''t initialize the RTC timers if xen is available
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Xen doesn''t need full RTC emulation in Qemu because the RTC is already emulated by the hypervisor. Hence don''t initialize the RTC timers when Xen is available so that Qemu doesn''t need to wake up needlessly. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- hw/mc146818rtc.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index cb3f56b..253b680 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -542,6 +542,7 @@ RTCState *rtc_init(int base, qemu_irq irq, int base_year) s->base_year = base_year; rtc_set_date_from_host(s); +#ifndef CONFIG_DM s->periodic_timer = qemu_new_timer(vm_clock, rtc_periodic_timer, s); s->second_timer = qemu_new_timer(vm_clock, @@ -551,6 +552,7 @@ RTCState *rtc_init(int base, qemu_irq irq, int base_year) s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); +#endif register_ioport_write(base, 2, 1, cmos_ioport_write, s); register_ioport_read(base, 2, 1, cmos_ioport_read, s); -- 1.7.2.5
<stefano.stabellini@eu.citrix.com>
2011-Nov-18 14:05 UTC
[PATCH 3/3] increase minimum timeout to 1h
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> There is no reason why the minimum timeout should be 10s, it could easily be 1h and we would save lots of cpu cycles. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- i386-dm/helper2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c index b121e30..c6d049c 100644 --- a/i386-dm/helper2.c +++ b/i386-dm/helper2.c @@ -605,8 +605,8 @@ int main_loop(void) /* Wait up to 10 msec. */ main_loop_wait(10); #else - /* Wait up to 10s. */ - main_loop_wait(10000); + /* Wait up to 1h. */ + main_loop_wait(1000*60*60); #endif fprintf(logfile, "device model saving state\n"); -- 1.7.2.5
Ian Jackson
2011-Dec-01 17:56 UTC
Re: [PATCH 0/3] prevent qemu-xen-traditional from waking up needlessly
Stefano Stabellini writes ("[Xen-devel] [PATCH 0/3] prevent qemu-xen-traditional from waking up needlessly"):> this small patch series prevents qemu-xen-traditional from waking up > needlessly several times a second in order to check some timers. > > The first patch makes use of a new mechanism to receive buffered io > event notifications from Xen, so that qemu doesn''t need to check the > buffered io page for data 10 times a sec for the entire life of the VM.I see that the hypervisor patch has gone in, so I have applied 2 and 3 as well. Ian.
Ian Jackson
2012-Apr-03 14:43 UTC
Re: [PATCH 1/3] xen: introduce an event channel for buffered io event notifications
stefano.stabellini@eu.citrix.com writes ("[PATCH 1/3] xen: introduce an event channel for buffered io event notifications"):> From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > > Use the newly introduced HVM_PARAM_BUFIOREQ_EVTCHN to receive > notifications for buffered io events. > After the first notification is received leave the event channel masked > and setup a timer to process the rest of the batch. > Once we have completed processing the batch, unmask the event channel > and delete the timer. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>