From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: [PATCH] kvm: Flush coalesced MMIO buffer periodly Date: Sun, 24 Jan 2010 09:35:58 +0200 Message-ID: <4B5BF85E.80602@redhat.com> References: <4B582A45.3020404@redhat.com> <1264126972-29758-1-git-send-email-sheng@linux.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Cc: Marcelo Tosatti , kvm@vger.kernel.org To: Sheng Yang Return-path: Received: from mx1.redhat.com ([209.132.183.28]:5346 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751120Ab0AXHgB (ORCPT ); Sun, 24 Jan 2010 02:36:01 -0500 In-Reply-To: <1264126972-29758-1-git-send-email-sheng@linux.intel.com> Sender: kvm-owner@vger.kernel.org List-ID: On 01/22/2010 04:22 AM, Sheng Yang wrote: > The default action of coalesced MMIO is, cache the writing in buffer, until: > 1. The buffer is full. > 2. Or the exit to QEmu due to other reasons. > > But this would result in a very late writing in some condition. > 1. The each time write to MMIO content is small. > 2. The writing interval is big. > 3. No need for input or accessing other devices frequently. > > This issue was observed in a experimental embbed system. The test image > simply print "test" every 1 seconds. The output in QEmu meets expectation, > but the output in KVM is delayed for seconds. > > Per Avi's suggestion, I hooked a flushing for coalesced MMIO buffer in VGA > update handler. By this way, We don't need vcpu explicit exit to QEmu to > handle this issue. > > Signed-off-by: Sheng Yang > --- > > Like this? > > qemu-kvm.c | 26 ++++++++++++++++++++++++-- > qemu-kvm.h | 6 ++++++ > vl.c | 2 ++ > 3 files changed, 32 insertions(+), 2 deletions(-) > > > > +#ifdef KVM_CAP_COALESCED_MMIO > +void kvm_flush_coalesced_mmio_buffer(void) > +{ > + if (kvm_state->coalesced_mmio_ring) { > + struct kvm_coalesced_mmio_ring *ring = > + kvm_state->coalesced_mmio_ring; > + while (ring->first != ring->last) { > + cpu_physical_memory_rw(ring->coalesced_mmio[ring->first].phys_addr, > +&ring->coalesced_mmio[ring->first].data[0], > + ring->coalesced_mmio[ring->first].len, 1); > + smp_wmb(); > + ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX; > + } > + } > +} > +#endif > + > qemu has a coalesced mmio api, (qemu_register_colaesced_mmio), so please follow it (stubs in exec.c, and implementation in kvm-specific files). Please send the patch against the uq/master branch (which follow upstream). > diff --git a/vl.c b/vl.c > index 9edea10..64902f2 100644 > --- a/vl.c > +++ b/vl.c > @@ -3235,6 +3235,7 @@ static void gui_update(void *opaque) > interval = dcl->gui_timer_interval; > dcl = dcl->next; > } > + kvm_flush_coalesced_mmio_buffer(); > qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock)); > } > Better to do that before the call to dpy_refresh(). > > @@ -3242,6 +3243,7 @@ static void nographic_update(void *opaque) > { > uint64_t interval = GUI_REFRESH_INTERVAL; > > + kvm_flush_coalesced_mmio_buffer(); > qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock)); > } > Any need to do it here? (why does nographic_update use a timer?) -- Do not meddle in the internals of kernels, for they are subtle and quick to panic.