public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 6/8] x86: KVM guest: hypercall batching
@ 2008-03-02 16:31 Avi Kivity
  2008-03-06  4:26 ` Zhao Forrest
  0 siblings, 1 reply; 3+ messages in thread
From: Avi Kivity @ 2008-03-02 16:31 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: kvm-devel, Marcelo Tosatti

From: Marcelo Tosatti <mtosatti@redhat.com>

Batch pte updates and tlb flushes in lazy MMU mode.

v1->v2:
- report individual hypercall error code, have multicall return number of
processed entries.
- cover entire multicall duration with slots_lock instead of
acquiring/reacquiring.

v2->v3:
- change to one ioctl per paravirt feature

v3->v4:
- adjust to mmu_op
- helper for getting para_state without debug warnings

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
---
 arch/x86/kernel/kvm.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index e28d818..8405984 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -25,6 +25,22 @@
 #include <linux/kvm_para.h>
 #include <linux/cpu.h>
 #include <linux/mm.h>
+#include <linux/hardirq.h>
+
+#define MMU_QUEUE_SIZE 1024
+
+struct kvm_para_state {
+	u8 mmu_queue[MMU_QUEUE_SIZE];
+	int mmu_queue_len;
+	enum paravirt_lazy_mode mode;
+};
+
+static DEFINE_PER_CPU(struct kvm_para_state, para_state);
+
+static struct kvm_para_state *kvm_para_state(void)
+{
+	return &per_cpu(para_state, raw_smp_processor_id());
+}
 
 /*
  * No need for any "IO delay" on KVM
@@ -47,6 +63,28 @@ static void kvm_mmu_op(void *buffer, unsigned len)
 	} while (len);
 }
 
+static void mmu_queue_flush(struct kvm_para_state *state)
+{
+	if (state->mmu_queue_len) {
+		kvm_mmu_op(state->mmu_queue, state->mmu_queue_len);
+		state->mmu_queue_len = 0;
+	}
+}
+
+static void kvm_deferred_mmu_op(void *buffer, int len)
+{
+	struct kvm_para_state *state = kvm_para_state();
+
+	if (state->mode != PARAVIRT_LAZY_MMU) {
+		kvm_mmu_op(buffer, len);
+		return;
+	}
+	if (state->mmu_queue_len + len > sizeof state->mmu_queue)
+		mmu_queue_flush(state);
+	memcpy(state->mmu_queue + state->mmu_queue_len, buffer, len);
+	state->mmu_queue_len += len;
+}
+
 static void kvm_mmu_write(void *dest, u64 val)
 {
 	struct kvm_mmu_op_write_pte wpte = {
@@ -55,7 +93,7 @@ static void kvm_mmu_write(void *dest, u64 val)
 		.pte_val = val,
 	};
 
-	kvm_mmu_op(&wpte, sizeof wpte);
+	kvm_deferred_mmu_op(&wpte, sizeof wpte);
 }
 
 /*
@@ -122,7 +160,7 @@ static void kvm_flush_tlb(void)
 		.header.op = KVM_MMU_OP_FLUSH_TLB,
 	};
 
-	kvm_mmu_op(&ftlb, sizeof ftlb);
+	kvm_deferred_mmu_op(&ftlb, sizeof ftlb);
 }
 
 static void kvm_release_pt(u32 pfn)
@@ -135,6 +173,23 @@ static void kvm_release_pt(u32 pfn)
 	kvm_mmu_op(&rpt, sizeof rpt);
 }
 
+static void kvm_enter_lazy_mmu(void)
+{
+	struct kvm_para_state *state = kvm_para_state();
+
+	paravirt_enter_lazy_mmu();
+	state->mode = paravirt_get_lazy_mode();
+}
+
+static void kvm_leave_lazy_mmu(void)
+{
+	struct kvm_para_state *state = kvm_para_state();
+
+	mmu_queue_flush(state);
+	paravirt_leave_lazy(paravirt_get_lazy_mode());
+	state->mode = paravirt_get_lazy_mode();
+}
+
 static void paravirt_ops_setup(void)
 {
 	pv_info.name = "KVM";
@@ -160,6 +215,9 @@ static void paravirt_ops_setup(void)
 		pv_mmu_ops.flush_tlb_user = kvm_flush_tlb;
 		pv_mmu_ops.release_pt = kvm_release_pt;
 		pv_mmu_ops.release_pd = kvm_release_pt;
+
+		pv_mmu_ops.lazy_mode.enter = kvm_enter_lazy_mmu;
+		pv_mmu_ops.lazy_mode.leave = kvm_leave_lazy_mmu;
 	}
 }
 
-- 
1.5.4.2


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-03-06  7:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-02 16:31 [PATCH 6/8] x86: KVM guest: hypercall batching Avi Kivity
2008-03-06  4:26 ` Zhao Forrest
2008-03-06  7:11   ` Avi Kivity

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox