public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] debugfs directory for each VM
@ 2008-03-10 12:02 Ryota OZAKI
  2008-03-17 11:35 ` Avi Kivity
  0 siblings, 1 reply; 3+ messages in thread
From: Ryota OZAKI @ 2008-03-10 12:02 UTC (permalink / raw)
  To: kvm-devel

Hi all,

This patch allows a VM to have own directory on debugfs,
that contains statics only for the VM. Each directory
is identified by the pid of the VM (ie qemu).

I tried this patch under several host kernel versions,
.22, .23, and .24, and confirmed things work out well.

Thanks,
ozaki-r

Signed-off-by: Ryota Ozaki <ozaki.ryota@gmail.com>
--
 arch/x86/kvm/x86.c       |    5 ++-
 include/linux/kvm_host.h |    8 ++++
 virt/kvm/kvm_main.c      |   81 ++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 82 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 5339ab1..7cab8a6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -53,8 +53,8 @@ static u64 __read_mostly efer_reserved_bits =
0xfffffffffffffafeULL;
 static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;
 #endif

-#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
-#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
+#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM, NULL
+#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, NULL

 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
 				    struct kvm_cpuid_entry2 __user *entries);
@@ -93,6 +93,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ NULL }
 };

+size_t debugfs_entries_size =
sizeof(debugfs_entries)/sizeof(debugfs_entries[0]);

 unsigned long segment_base(u16 selector)
 {
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 958e003..037bab1 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -43,6 +43,11 @@
 struct kvm_vcpu;
 extern struct kmem_cache *kvm_vcpu_cache;

+struct kvm_debugfs {
+	struct dentry *dentry;
+	struct kvm_stats_debugfs_item *debugfs_entries;
+};
+
 struct kvm_guest_debug {
 	int enabled;
 	unsigned long bp[4];
@@ -127,6 +132,7 @@ struct kvm {
 	struct kvm_io_bus pio_bus;
 	struct kvm_vm_stat stat;
 	struct kvm_arch arch;
+	struct kvm_debugfs debugfs;
 };

 /* The guest did something we don't support. */
@@ -304,7 +310,9 @@ struct kvm_stats_debugfs_item {
 	int offset;
 	enum kvm_stat_kind kind;
 	struct dentry *dentry;
+	struct kvm *kvm;
 };
 extern struct kvm_stats_debugfs_item debugfs_entries[];
+extern size_t debugfs_entries_size;

 #endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 30bf832..357f827 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -60,6 +60,8 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_cache);
 static __read_mostly struct preempt_ops kvm_preempt_ops;

 static struct dentry *debugfs_dir;
+static void kvm_debugfs_init(struct kvm *kvm);
+static void kvm_debugfs_destroy(struct kvm *kvm);

 static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
 			   unsigned long arg);
@@ -192,6 +194,7 @@ static struct kvm *kvm_create_vm(void)
 	kvm_io_bus_init(&kvm->pio_bus);
 	mutex_init(&kvm->lock);
 	kvm_io_bus_init(&kvm->mmio_bus);
+	kvm_debugfs_init(kvm);
 	init_rwsem(&kvm->slots_lock);
 	spin_lock(&kvm_lock);
 	list_add(&kvm->vm_list, &vm_list);
@@ -236,6 +239,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
 	spin_lock(&kvm_lock);
 	list_del(&kvm->vm_list);
 	spin_unlock(&kvm_lock);
+	kvm_debugfs_destroy(kvm);
 	kvm_io_bus_destroy(&kvm->pio_bus);
 	kvm_io_bus_destroy(&kvm->mmio_bus);
 	kvm_arch_destroy_vm(kvm);
@@ -1248,36 +1252,48 @@ static struct notifier_block kvm_cpu_notifier = {
 	.priority = 20, /* must be > scheduler priority */
 };

-static int vm_stat_get(void *_offset, u64 *val)
+static int vm_stat_get(void *_item, u64 *val)
 {
-	unsigned offset = (long)_offset;
-	struct kvm *kvm;
+	unsigned offset = (long)((struct kvm_stats_debugfs_item *)_item)->offset;
+	struct kvm *kvm = ((struct kvm_stats_debugfs_item *)_item)->kvm;

 	*val = 0;
 	spin_lock(&kvm_lock);
-	list_for_each_entry(kvm, &vm_list, vm_list)
-		*val += *(u32 *)((void *)kvm + offset);
+	if (kvm) {
+		*val = *(u32 *)((void *)kvm + offset);
+	} else {
+		list_for_each_entry(kvm, &vm_list, vm_list)
+			*val += *(u32 *)((void *)kvm + offset);
+	}
 	spin_unlock(&kvm_lock);
 	return 0;
 }

 DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n");

-static int vcpu_stat_get(void *_offset, u64 *val)
+static int vcpu_stat_get(void *_item, u64 *val)
 {
-	unsigned offset = (long)_offset;
-	struct kvm *kvm;
+	unsigned offset = (long)((struct kvm_stats_debugfs_item *)_item)->offset;
+	struct kvm *kvm = ((struct kvm_stats_debugfs_item *)_item)->kvm;
 	struct kvm_vcpu *vcpu;
 	int i;

 	*val = 0;
 	spin_lock(&kvm_lock);
-	list_for_each_entry(kvm, &vm_list, vm_list)
+	if (kvm) {
 		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
 			vcpu = kvm->vcpus[i];
 			if (vcpu)
 				*val += *(u32 *)((void *)vcpu + offset);
 		}
+	} else {
+		list_for_each_entry(kvm, &vm_list, vm_list)
+			for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+				vcpu = kvm->vcpus[i];
+				if (vcpu)
+					*val += *(u32 *)((void *)vcpu + offset);
+			}
+	}
 	spin_unlock(&kvm_lock);
 	return 0;
 }
@@ -1296,7 +1312,7 @@ static void kvm_init_debug(void)
 	debugfs_dir = debugfs_create_dir("kvm", NULL);
 	for (p = debugfs_entries; p->name; ++p)
 		p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir,
-						(void *)(long)p->offset,
+						(void *)p,
 						stat_fops[p->kind]);
 }

@@ -1309,6 +1325,51 @@ static void kvm_exit_debug(void)
 	debugfs_remove(debugfs_dir);
 }

+#define PROC_NUMBUF 13 /* from fs/proc/base.c */
+
+static void kvm_debugfs_init(struct kvm *kvm)
+{
+	struct kvm_stats_debugfs_item *p;
+	struct kvm_debugfs *kvm_debugfs = &kvm->debugfs;
+	struct dentry *dir;
+	char pid[PROC_NUMBUF];
+
+	sprintf(pid, "%d", pid_nr(task_pid(current)));
+	dir = debugfs_create_dir(pid, debugfs_dir);
+	if (dir == NULL) {
+		return;
+	}
+
+	p = kmalloc(sizeof(struct
kvm_stats_debugfs_item)*debugfs_entries_size, GFP_KERNEL);
+	if (p == NULL) {
+		debugfs_remove(dir);
+		return;
+	}
+	memcpy(p, debugfs_entries, sizeof(struct
kvm_stats_debugfs_item)*debugfs_entries_size);
+	
+	kvm_debugfs->dentry = dir;
+	kvm_debugfs->debugfs_entries = p;
+	for (; p->name; ++p) {
+		p->kvm = kvm;
+		p->dentry = debugfs_create_file(p->name, 0444, dir,
+						(void *)p,
+						stat_fops[p->kind]);
+	}
+	return;
+}
+
+static void kvm_debugfs_destroy(struct kvm *kvm)
+{
+	struct kvm_stats_debugfs_item *p;
+	struct kvm_debugfs *debugfs = &kvm->debugfs;
+
+	p = debugfs->debugfs_entries;
+	for (; p->name; ++p)
+		debugfs_remove(p->dentry);
+	debugfs_remove(debugfs->dentry);
+	kfree(debugfs->debugfs_entries);
+}
+
 static int kvm_suspend(struct sys_device *dev, pm_message_t state)
 {
 	hardware_disable(NULL);
--

-------------------------------------------------------------------------
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-17 17:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-10 12:02 [PATCH] debugfs directory for each VM Ryota OZAKI
2008-03-17 11:35 ` Avi Kivity
2008-03-17 17:28   ` Ryota OZAKI

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