* [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* Re: [PATCH] debugfs directory for each VM
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
0 siblings, 1 reply; 3+ messages in thread
From: Avi Kivity @ 2008-03-17 11:35 UTC (permalink / raw)
To: Ryota OZAKI; +Cc: kvm-devel
Ryota OZAKI wrote:
> 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.
>
Nice patch; it's certainly useful to improve per-vm trace capabilities.
It would be nice to keep the summary, since that allows running kvm_stat
with no arguments.
On the other hand, the kvmtrace patchset recently posted adds much more
detailed data; we should probably concentrate on that as a means of
improving performance tracing.
--
error compiling committee.c: too many arguments to function
-------------------------------------------------------------------------
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 [flat|nested] 3+ messages in thread
* Re: [PATCH] debugfs directory for each VM
2008-03-17 11:35 ` Avi Kivity
@ 2008-03-17 17:28 ` Ryota OZAKI
0 siblings, 0 replies; 3+ messages in thread
From: Ryota OZAKI @ 2008-03-17 17:28 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm-devel
Hi Avi,
2008/3/17, Avi Kivity <avi@qumranet.com>:
> Ryota OZAKI wrote:
> > 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.
> >
>
>
> Nice patch; it's certainly useful to improve per-vm trace capabilities.
>
> It would be nice to keep the summary, since that allows running kvm_stat
> with no arguments.
My patch keeps the summary. But it actually breaks a kvm_stat's assumption
so kvm_stat doesn't work under kvm with my patch. I wrote a patch to fix this
problem. See the following patch. (i'm not familiar with python, sorry.)
> On the other hand, the kvmtrace patchset recently posted adds much more
> detailed data; we should probably concentrate on that as a means of
> improving performance tracing.
The patchset is useful for me, too. I will concentrate that as well.
Thanks,
ozaki-r
> --
> error compiling committee.c: too many arguments to function
Signed-off-by: Ryota Ozaki <ozaki.ryota@gmail.com>
--
kvm_stat | 25 ++++++++++++++++++-------
1 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/kvm_stat b/kvm_stat
index 07773b0..e507e62 100755
--- a/kvm_stat
+++ b/kvm_stat
@@ -4,11 +4,15 @@ import curses
import sys, os, time, optparse
class Stats:
- def __init__(self):
- self.base = '/sys/kernel/debug/kvm'
+ def __init__(self, pid = None):
+ if pid:
+ self.base = '/sys/kernel/debug/kvm/' + pid
+ else:
+ self.base = '/sys/kernel/debug/kvm'
self.values = {}
for key in os.listdir(self.base):
- self.values[key] = None
+ if not os.path.isdir(self.base + '/' + key):
+ self.values[key] = None
def get(self):
for key, oldval in self.values.iteritems():
newval = int(file(self.base + '/' + key).read())
@@ -26,7 +30,6 @@ if not os.access('/sys/kernel/debug/kvm', os.F_OK):
print "and ensure the kvm modules are loaded"
sys.exit(1)
-stats = Stats()
label_width = 20
number_width = 10
@@ -73,14 +76,22 @@ def batch(stats):
values = s[key]
print '%-22s%10d%10d' % (key, values[0], values[1])
-options = optparse.OptionParser()
-options.add_option('-1', '--once', '--batch',
+usage = "usage: %prog [options] [<pid>]"
+parser = optparse.OptionParser(usage)
+parser.add_option('-1', '--once', '--batch',
action = 'store_true',
default = False,
dest = 'once',
help = 'run in batch mode for one second',
)
-(options, args) = options.parse_args(sys.argv)
+(options, args) = parser.parse_args(sys.argv)
+
+if len(args) == 1:
+ stats = Stats()
+elif len(args) == 2:
+ stats = Stats(args[1])
+else:
+ parser.error("too many arguments.")
if not options.once:
import curses.wrapper
--
-------------------------------------------------------------------------
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