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 <[EMAIL PROTECTED]> -- 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/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel