All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <Laurent.Vivier@bull.net>
To: kvm-devel@lists.sourceforge.net
Cc: Ingo Molnar <mingo@elte.hu>,
	Rusty Russell <rusty@rustcorp.com.au>,
	virtualization <virtualization@lists.linux-foundation.org>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH/RFC 4/4]Modify KVM to use the "account modifiers"
Date: Thu, 16 Aug 2007 17:59:01 +0200	[thread overview]
Message-ID: <46C47445.5070403@bull.net> (raw)
In-Reply-To: <46C472D2.7000702@bull.net>

[-- Attachment #1: Type: text/plain, Size: 339 bytes --]

[PATCH 4/4] Modify KVM to use the "account modifiers". KVM can now measure time
consumed by a Virtual Machine on a per-cpu basis and modify kernel statistics to
report this value.

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
-- 
------------- Laurent.Vivier@bull.net  --------------
          "Software is hard" - Donald Knuth

[-- Attachment #2: kvm_accounting_modifiers --]
[-- Type: text/plain, Size: 5907 bytes --]

Index: kvm/drivers/kvm/kvm.h
===================================================================
--- kvm.orig/drivers/kvm/kvm.h	2007-08-16 16:21:42.000000000 +0200
+++ kvm/drivers/kvm/kvm.h	2007-08-16 16:27:00.000000000 +0200
@@ -408,6 +408,10 @@
 	struct file *filp;
 	struct kvm_io_bus mmio_bus;
 	struct kvm_io_bus pio_bus;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	struct account_modifier account_modifier;
+	ktime_t vtime[NR_CPUS];
+#endif
 };
 
 struct descriptor_table {
@@ -589,6 +593,20 @@
 
 int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+static inline ktime_t kvm_guest_enter(void)
+{
+	return ktime_get();
+}
+
+static inline void kvm_guest_exit(struct kvm *kvm, ktime_t enter)
+{
+	ktime_t delta = ktime_sub(ktime_get(), enter);
+	kvm->vtime[smp_processor_id()] =
+		ktime_add(kvm->vtime[smp_processor_id()], delta);
+}
+#endif
+
 static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
 				     u32 error_code)
 {
Index: kvm/drivers/kvm/kvm_main.c
===================================================================
--- kvm.orig/drivers/kvm/kvm_main.c	2007-08-16 16:21:42.000000000 +0200
+++ kvm/drivers/kvm/kvm_main.c	2007-08-16 16:40:28.000000000 +0200
@@ -33,6 +33,7 @@
 #include <linux/file.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
+#include <linux/kernel_stat.h>
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/smp.h>
@@ -57,6 +58,9 @@
 EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
 
 static __read_mostly struct preempt_ops kvm_preempt_ops;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+static __read_mostly struct account_ops kvm_account_ops;
+#endif
 
 #define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x)
 
@@ -285,6 +289,42 @@
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_uninit);
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+static inline
+struct kvm *account_modifier_to_kvm(struct account_modifier *am)
+{
+	return container_of(am, struct kvm, account_modifier);
+}
+
+static cputime_t kvm_account_system_modifier(struct account_modifier *modifier,
+					     struct task_struct *curr,
+					     int hardirq_offset,
+					     cputime_t cputime)
+{
+	struct kvm *kvm = account_modifier_to_kvm(modifier);
+	ktime_t kmsec = ktime_set(0, NSEC_PER_MSEC);
+	cputime_t cmsec = msecs_to_cputime(1);
+	ktime_t vtime = kvm->vtime[smp_processor_id()];
+
+	while ((ktime_to_ns(vtime) >= NSEC_PER_MSEC) &&
+	       (cputime_to_msecs(cputime) >= 1)) {
+		kvm->vtime[smp_processor_id()] = ktime_sub(vtime, kmsec);
+
+		curr->utime = cputime_add(curr->utime, cmsec);
+		curr->gtime = cputime_add(curr->gtime, cmsec);
+
+		kstat_this_cpu.cpustat.guest = cputime64_add(kstat_this_cpu.cpustat.guest,
+						cputime_to_cputime64(cmsec));
+		kstat_this_cpu.cpustat.user = cputime64_add(kstat_this_cpu.cpustat.user,
+						cputime_to_cputime64(cmsec));
+
+		cputime = cputime_sub(cputime, cmsec);
+	}
+
+	return cputime;
+}
+#endif
+
 static struct kvm *kvm_create_vm(void)
 {
 	struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
@@ -299,6 +339,15 @@
 	spin_lock(&kvm_lock);
 	list_add(&kvm->vm_list, &vm_list);
 	spin_unlock(&kvm_lock);
+
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_account_ops.user_time = NULL;
+	kvm_account_ops.system_time = kvm_account_system_modifier;
+
+	account_modifier_init(&kvm->account_modifier, &kvm_account_ops);
+	account_modifier_register(&kvm->account_modifier);
+#endif
+
 	return kvm;
 }
 
@@ -376,6 +425,9 @@
 	spin_lock(&kvm_lock);
 	list_del(&kvm->vm_list);
 	spin_unlock(&kvm_lock);
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	account_modifier_unregister(&kvm->account_modifier);
+#endif
 	kvm_io_bus_destroy(&kvm->pio_bus);
 	kvm_io_bus_destroy(&kvm->mmio_bus);
 	kvm_free_vcpus(kvm);
Index: kvm/drivers/kvm/svm.c
===================================================================
--- kvm.orig/drivers/kvm/svm.c	2007-08-16 16:21:42.000000000 +0200
+++ kvm/drivers/kvm/svm.c	2007-08-16 16:29:41.000000000 +0200
@@ -1392,6 +1392,9 @@
 	u16 gs_selector;
 	u16 ldt_selector;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 again:
 	r = kvm_mmu_reload(vcpu);
@@ -1404,6 +1407,9 @@
 	clgi();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    svm_flush_tlb(vcpu);
@@ -1536,6 +1542,9 @@
 #endif
 		: "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 
 	if (vcpu->fpu_active) {
Index: kvm/drivers/kvm/vmx.c
===================================================================
--- kvm.orig/drivers/kvm/vmx.c	2007-08-16 16:21:42.000000000 +0200
+++ kvm/drivers/kvm/vmx.c	2007-08-16 16:30:24.000000000 +0200
@@ -2052,6 +2052,9 @@
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u8 fail;
 	int r;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	ktime_t now;
+#endif
 
 preempted:
 	if (vcpu->guest_debug.enabled)
@@ -2078,6 +2081,9 @@
 	local_irq_disable();
 
 	vcpu->guest_mode = 1;
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	now = kvm_guest_enter();
+#endif
 	if (vcpu->requests)
 		if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
 		    vmx_flush_tlb(vcpu);
@@ -2198,6 +2204,9 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+#ifdef CONFIG_ACCOUNT_MODIFIERS
+	kvm_guest_exit(vcpu->kvm, now);
+#endif
 	vcpu->guest_mode = 0;
 	local_irq_enable();
 
Index: kvm/drivers/kvm/Kconfig
===================================================================
--- kvm.orig/drivers/kvm/Kconfig	2007-08-16 16:21:42.000000000 +0200
+++ kvm/drivers/kvm/Kconfig	2007-08-16 16:21:44.000000000 +0200
@@ -41,4 +41,10 @@
 	  Provides support for KVM on AMD processors equipped with the AMD-V
 	  (SVM) extensions.
 
+config ACCOUNT_MODIFIERS
+        bool "Virtual Machine accounting support"
+	depends on KVM
+	---help---
+	  Allows to account CPU time used by the Virtual Machines.
+
 endif # VIRTUALIZATION

  parent reply	other threads:[~2007-08-16 15:59 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <46C4719A.2060308@bull.net>
2007-08-16 15:57 ` [PATCH/RFC 1/4]Introduce a new field "guest" in cpustat Laurent Vivier
2007-08-16 15:57 ` Laurent Vivier
     [not found] ` <46C4720F.7030304@bull.net>
2007-08-16 15:57   ` [PATCH/RFC 2/4]Introduce a new field "guest" in task_struct Laurent Vivier
2007-08-16 15:57   ` Laurent Vivier
     [not found]   ` <46C4725A.4070607@bull.net>
2007-08-16 15:58     ` [PATCH/RFC 3/4]Introduce "account modifiers" mechanism Laurent Vivier
2007-08-16 15:58     ` Laurent Vivier
2007-08-16 22:39       ` Rusty Russell
2007-08-17  7:35         ` Laurent Vivier
2007-08-17  7:35           ` Laurent Vivier
2007-08-17  8:30           ` Rusty Russell
2007-08-17  8:30             ` Rusty Russell
2007-08-17  9:16             ` Laurent Vivier
2007-08-17  9:16             ` Laurent Vivier
2007-08-17  9:16               ` Laurent Vivier
2007-08-17 11:51               ` [PATCH/RFC 3/4, second shot]Introduce "account_guest_time" Laurent Vivier
2007-08-17 11:51               ` Laurent Vivier
2007-08-17 11:51                 ` Laurent Vivier
2007-08-17 11:54                 ` [PATCH/RFC 4/4, second shot]KVM uses "account_guest_time()" Laurent Vivier
2007-08-17 11:54                 ` Laurent Vivier
2007-08-17 13:03                   ` [kvm-devel] " Avi Kivity
2007-08-17 13:03                   ` Avi Kivity
2007-08-17 13:03                     ` Avi Kivity
2007-08-17 13:16                     ` [kvm-devel] " Laurent Vivier
2007-08-17 13:16                       ` Laurent Vivier
2007-08-19  7:39                       ` [kvm-devel] " Avi Kivity
2007-08-19  7:39                         ` Avi Kivity
2007-08-19  7:39                       ` [kvm-devel] " Avi Kivity
2007-08-17 13:16                     ` Laurent Vivier
2007-08-17 12:59                 ` [kvm-devel] [PATCH/RFC 3/4, second shot]Introduce "account_guest_time" Avi Kivity
2007-08-17 12:59                 ` Avi Kivity
2007-08-17 12:55               ` [kvm-devel] [PATCH/RFC 3/4]Introduce "account modifiers" mechanism Avi Kivity
2007-08-17 12:55                 ` Avi Kivity
2007-08-17 13:08                 ` [kvm-devel] " Laurent Vivier
2007-08-17 13:08                   ` Laurent Vivier
2007-08-17 13:32                   ` [kvm-devel] " Christian Borntraeger
2007-08-17 13:32                     ` Christian Borntraeger
2007-08-17 13:32                   ` [kvm-devel] " Christian Borntraeger
2007-08-19  7:41                   ` Avi Kivity
2007-08-19  7:41                     ` Avi Kivity
2007-08-19  7:41                   ` [kvm-devel] " Avi Kivity
2007-08-17 13:08                 ` Laurent Vivier
2007-08-17 14:12                 ` Laurent Vivier
2007-08-17 14:12                 ` Laurent Vivier
2007-08-17 14:12                   ` Laurent Vivier
2007-08-19  7:38                   ` [kvm-devel] " Avi Kivity
2007-08-19  7:38                   ` Avi Kivity
2007-08-19  7:38                     ` Avi Kivity
2007-08-20  7:30                     ` [kvm-devel] " Laurent Vivier
2007-08-20  7:30                     ` Laurent Vivier
2007-08-20  7:30                       ` Laurent Vivier
2007-08-20  7:55                       ` [kvm-devel] " Avi Kivity
2007-08-20  7:55                         ` Avi Kivity
2007-08-20  7:55                       ` [kvm-devel] " Avi Kivity
2007-08-17 12:55               ` Avi Kivity
2007-08-17  8:30           ` Rusty Russell
2007-08-17  7:35         ` Laurent Vivier
2007-08-16 22:39       ` Rusty Russell
     [not found]     ` <46C472D2.7000702@bull.net>
2007-08-16 15:59       ` Laurent Vivier [this message]
2007-08-16 15:59       ` [PATCH/RFC 4/4]Modify KVM to use the "account modifiers" Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46C47445.5070403@bull.net \
    --to=laurent.vivier@bull.net \
    --cc=kvm-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=rusty@rustcorp.com.au \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.