From patchwork Tue Jan 26 11:21:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sheng Yang X-Patchwork-Id: 75168 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0QBMGcO008883 for ; Tue, 26 Jan 2010 11:22:17 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752309Ab0AZLWP (ORCPT ); Tue, 26 Jan 2010 06:22:15 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752652Ab0AZLWO (ORCPT ); Tue, 26 Jan 2010 06:22:14 -0500 Received: from mga14.intel.com ([143.182.124.37]:3179 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752207Ab0AZLWL (ORCPT ); Tue, 26 Jan 2010 06:22:11 -0500 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 26 Jan 2010 03:22:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.47,316,1257148800"; d="scan'208";a="236875268" Received: from syang10-desktop.sh.intel.com (HELO syang10-desktop) ([10.239.36.165]) by azsmga001.ch.intel.com with ESMTP; 26 Jan 2010 03:22:09 -0800 Received: from yasker by syang10-desktop with local (Exim 4.69) (envelope-from ) id 1NZjTy-0006NX-Ht; Tue, 26 Jan 2010 19:21:18 +0800 From: Sheng Yang To: Avi Kivity , Marcelo Tosatti Cc: Anthony Liguori , Alexander Graf , kvm@vger.kernel.org, qemu-devel@nongnu.org, Sheng Yang Subject: [PATCH v3][uqmaster] kvm: Flush coalesced MMIO buffer periodly Date: Tue, 26 Jan 2010 19:21:16 +0800 Message-Id: <1264504876-24493-1-git-send-email-sheng@linux.intel.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <366919FC-E282-4A23-8D9C-595D8583C97F@suse.de> References: <366919FC-E282-4A23-8D9C-595D8583C97F@suse.de> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org diff --git a/cpu-all.h b/cpu-all.h index 57b69f8..1ccc9a8 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -915,6 +915,8 @@ void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size); void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size); +void qemu_flush_coalesced_mmio_buffer(void); + /*******************************************/ /* host CPU ticks (if available) */ diff --git a/exec.c b/exec.c index 1190591..6875370 100644 --- a/exec.c +++ b/exec.c @@ -2406,6 +2406,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size) kvm_uncoalesce_mmio_region(addr, size); } +void qemu_flush_coalesced_mmio_buffer(void) +{ + if (kvm_enabled()) + kvm_flush_coalesced_mmio_buffer(); +} + ram_addr_t qemu_ram_alloc(ram_addr_t size) { RAMBlock *new_block; diff --git a/kvm-all.c b/kvm-all.c index 15ec38e..f8350c9 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -59,6 +59,9 @@ struct KVMState int vmfd; int regs_modified; int coalesced_mmio; +#ifdef KVM_CAP_COALESCED_MMIO + struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; +#endif int broken_set_mem_region; int migration_log; int vcpu_events; @@ -200,6 +203,12 @@ int kvm_init_vcpu(CPUState *env) goto err; } +#ifdef KVM_CAP_COALESCED_MMIO + if (s->coalesced_mmio && !s->coalesced_mmio_ring) + s->coalesced_mmio_ring = (void *) env->kvm_run + + s->coalesced_mmio * PAGE_SIZE; +#endif + ret = kvm_arch_init_vcpu(env); if (ret == 0) { qemu_register_reset(kvm_reset_vcpu, env); @@ -466,10 +475,10 @@ int kvm_init(int smp_cpus) goto err; } + s->coalesced_mmio = 0; #ifdef KVM_CAP_COALESCED_MMIO s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); -#else - s->coalesced_mmio = 0; + s->coalesced_mmio_ring = NULL; #endif s->broken_set_mem_region = 1; @@ -544,14 +553,12 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size, return 1; } -static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run) +void kvm_flush_coalesced_mmio_buffer(void) { #ifdef KVM_CAP_COALESCED_MMIO KVMState *s = kvm_state; - if (s->coalesced_mmio) { - struct kvm_coalesced_mmio_ring *ring; - - ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE); + if (s->coalesced_mmio_ring) { + struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring; while (ring->first != ring->last) { struct kvm_coalesced_mmio *ent; @@ -609,7 +616,7 @@ int kvm_cpu_exec(CPUState *env) abort(); } - kvm_run_coalesced_mmio(env, run); + kvm_flush_coalesced_mmio_buffer(); ret = 0; /* exit loop */ switch (run->exit_reason) { diff --git a/kvm.h b/kvm.h index 1c93ac5..59cba18 100644 --- a/kvm.h +++ b/kvm.h @@ -53,6 +53,7 @@ void kvm_setup_guest_memory(void *start, size_t size); int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size); +void kvm_flush_coalesced_mmio_buffer(void); int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, target_ulong len, int type); diff --git a/vl.c b/vl.c index 2b0b653..1f0c536 100644 --- a/vl.c +++ b/vl.c @@ -3193,6 +3193,7 @@ static void gui_update(void *opaque) DisplayState *ds = opaque; DisplayChangeListener *dcl = ds->listeners; + qemu_flush_coalesced_mmio_buffer(); dpy_refresh(ds); while (dcl != NULL) { @@ -3208,6 +3209,7 @@ static void nographic_update(void *opaque) { uint64_t interval = GUI_REFRESH_INTERVAL; + qemu_flush_coalesced_mmio_buffer(); qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock)); }