diff options
author | Avi Kivity <avi@qumranet.com> | 2007-11-18 09:24:12 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:04 -0500 |
commit | ba1389b7a04de07e6231693b7ebb34f5b5d1a3e6 (patch) | |
tree | 536139f6e1d3a918b13a9c44f2144c52366a55bb | |
parent | f2b5756bb3fbdca912c4890e444c18650389d8ae (diff) |
KVM: Extend stats support for VM stats
This is in addition to the current virtual cpu statistics.
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/kvm.h | 14 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 26 | ||||
-rw-r--r-- | drivers/kvm/x86.c | 39 |
3 files changed, 55 insertions, 24 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 5a8a9af3593a..d3171f9c9c01 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -231,7 +231,7 @@ struct kvm_pio_request { | |||
231 | int rep; | 231 | int rep; |
232 | }; | 232 | }; |
233 | 233 | ||
234 | struct kvm_stat { | 234 | struct kvm_vcpu_stat { |
235 | u32 pf_fixed; | 235 | u32 pf_fixed; |
236 | u32 pf_guest; | 236 | u32 pf_guest; |
237 | u32 tlb_flush; | 237 | u32 tlb_flush; |
@@ -342,7 +342,7 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus, | |||
342 | wait_queue_head_t wq; \ | 342 | wait_queue_head_t wq; \ |
343 | int sigset_active; \ | 343 | int sigset_active; \ |
344 | sigset_t sigset; \ | 344 | sigset_t sigset; \ |
345 | struct kvm_stat stat; \ | 345 | struct kvm_vcpu_stat stat; \ |
346 | KVM_VCPU_MMIO | 346 | KVM_VCPU_MMIO |
347 | 347 | ||
348 | struct kvm_mem_alias { | 348 | struct kvm_mem_alias { |
@@ -361,6 +361,9 @@ struct kvm_memory_slot { | |||
361 | int user_alloc; | 361 | int user_alloc; |
362 | }; | 362 | }; |
363 | 363 | ||
364 | struct kvm_vm_stat { | ||
365 | }; | ||
366 | |||
364 | struct kvm { | 367 | struct kvm { |
365 | struct mutex lock; /* protects everything except vcpus */ | 368 | struct mutex lock; /* protects everything except vcpus */ |
366 | int naliases; | 369 | int naliases; |
@@ -387,6 +390,7 @@ struct kvm { | |||
387 | int round_robin_prev_vcpu; | 390 | int round_robin_prev_vcpu; |
388 | unsigned int tss_addr; | 391 | unsigned int tss_addr; |
389 | struct page *apic_access_page; | 392 | struct page *apic_access_page; |
393 | struct kvm_vm_stat stat; | ||
390 | }; | 394 | }; |
391 | 395 | ||
392 | static inline struct kvm_pic *pic_irqchip(struct kvm *kvm) | 396 | static inline struct kvm_pic *pic_irqchip(struct kvm *kvm) |
@@ -809,9 +813,15 @@ static inline u32 get_rdx_init_val(void) | |||
809 | #define TSS_REDIRECTION_SIZE (256 / 8) | 813 | #define TSS_REDIRECTION_SIZE (256 / 8) |
810 | #define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1) | 814 | #define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1) |
811 | 815 | ||
816 | enum kvm_stat_kind { | ||
817 | KVM_STAT_VM, | ||
818 | KVM_STAT_VCPU, | ||
819 | }; | ||
820 | |||
812 | struct kvm_stats_debugfs_item { | 821 | struct kvm_stats_debugfs_item { |
813 | const char *name; | 822 | const char *name; |
814 | int offset; | 823 | int offset; |
824 | enum kvm_stat_kind kind; | ||
815 | struct dentry *dentry; | 825 | struct dentry *dentry; |
816 | }; | 826 | }; |
817 | extern struct kvm_stats_debugfs_item debugfs_entries[]; | 827 | extern struct kvm_stats_debugfs_item debugfs_entries[]; |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index bde3cf741892..b0b6ff2a8cbe 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -1281,7 +1281,22 @@ static struct notifier_block kvm_cpu_notifier = { | |||
1281 | .priority = 20, /* must be > scheduler priority */ | 1281 | .priority = 20, /* must be > scheduler priority */ |
1282 | }; | 1282 | }; |
1283 | 1283 | ||
1284 | static u64 stat_get(void *_offset) | 1284 | static u64 vm_stat_get(void *_offset) |
1285 | { | ||
1286 | unsigned offset = (long)_offset; | ||
1287 | u64 total = 0; | ||
1288 | struct kvm *kvm; | ||
1289 | |||
1290 | spin_lock(&kvm_lock); | ||
1291 | list_for_each_entry(kvm, &vm_list, vm_list) | ||
1292 | total += *(u32 *)((void *)kvm + offset); | ||
1293 | spin_unlock(&kvm_lock); | ||
1294 | return total; | ||
1295 | } | ||
1296 | |||
1297 | DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n"); | ||
1298 | |||
1299 | static u64 vcpu_stat_get(void *_offset) | ||
1285 | { | 1300 | { |
1286 | unsigned offset = (long)_offset; | 1301 | unsigned offset = (long)_offset; |
1287 | u64 total = 0; | 1302 | u64 total = 0; |
@@ -1300,7 +1315,12 @@ static u64 stat_get(void *_offset) | |||
1300 | return total; | 1315 | return total; |
1301 | } | 1316 | } |
1302 | 1317 | ||
1303 | DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, NULL, "%llu\n"); | 1318 | DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); |
1319 | |||
1320 | static struct file_operations *stat_fops[] = { | ||
1321 | [KVM_STAT_VCPU] = &vcpu_stat_fops, | ||
1322 | [KVM_STAT_VM] = &vm_stat_fops, | ||
1323 | }; | ||
1304 | 1324 | ||
1305 | static void kvm_init_debug(void) | 1325 | static void kvm_init_debug(void) |
1306 | { | 1326 | { |
@@ -1310,7 +1330,7 @@ static void kvm_init_debug(void) | |||
1310 | for (p = debugfs_entries; p->name; ++p) | 1330 | for (p = debugfs_entries; p->name; ++p) |
1311 | p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir, | 1331 | p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir, |
1312 | (void *)(long)p->offset, | 1332 | (void *)(long)p->offset, |
1313 | &stat_fops); | 1333 | stat_fops[p->kind]); |
1314 | } | 1334 | } |
1315 | 1335 | ||
1316 | static void kvm_exit_debug(void) | 1336 | static void kvm_exit_debug(void) |
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c index a46b95b3651c..016abc3357e9 100644 --- a/drivers/kvm/x86.c +++ b/drivers/kvm/x86.c | |||
@@ -42,29 +42,30 @@ | |||
42 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) | 42 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) |
43 | #define EFER_RESERVED_BITS 0xfffffffffffff2fe | 43 | #define EFER_RESERVED_BITS 0xfffffffffffff2fe |
44 | 44 | ||
45 | #define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x) | 45 | #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM |
46 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | ||
46 | 47 | ||
47 | struct kvm_x86_ops *kvm_x86_ops; | 48 | struct kvm_x86_ops *kvm_x86_ops; |
48 | 49 | ||
49 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 50 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
50 | { "pf_fixed", STAT_OFFSET(pf_fixed) }, | 51 | { "pf_fixed", VCPU_STAT(pf_fixed) }, |
51 | { "pf_guest", STAT_OFFSET(pf_guest) }, | 52 | { "pf_guest", VCPU_STAT(pf_guest) }, |
52 | { "tlb_flush", STAT_OFFSET(tlb_flush) }, | 53 | { "tlb_flush", VCPU_STAT(tlb_flush) }, |
53 | { "invlpg", STAT_OFFSET(invlpg) }, | 54 | { "invlpg", VCPU_STAT(invlpg) }, |
54 | { "exits", STAT_OFFSET(exits) }, | 55 | { "exits", VCPU_STAT(exits) }, |
55 | { "io_exits", STAT_OFFSET(io_exits) }, | 56 | { "io_exits", VCPU_STAT(io_exits) }, |
56 | { "mmio_exits", STAT_OFFSET(mmio_exits) }, | 57 | { "mmio_exits", VCPU_STAT(mmio_exits) }, |
57 | { "signal_exits", STAT_OFFSET(signal_exits) }, | 58 | { "signal_exits", VCPU_STAT(signal_exits) }, |
58 | { "irq_window", STAT_OFFSET(irq_window_exits) }, | 59 | { "irq_window", VCPU_STAT(irq_window_exits) }, |
59 | { "halt_exits", STAT_OFFSET(halt_exits) }, | 60 | { "halt_exits", VCPU_STAT(halt_exits) }, |
60 | { "halt_wakeup", STAT_OFFSET(halt_wakeup) }, | 61 | { "halt_wakeup", VCPU_STAT(halt_wakeup) }, |
61 | { "request_irq", STAT_OFFSET(request_irq_exits) }, | 62 | { "request_irq", VCPU_STAT(request_irq_exits) }, |
62 | { "irq_exits", STAT_OFFSET(irq_exits) }, | 63 | { "irq_exits", VCPU_STAT(irq_exits) }, |
63 | { "host_state_reload", STAT_OFFSET(host_state_reload) }, | 64 | { "host_state_reload", VCPU_STAT(host_state_reload) }, |
64 | { "efer_reload", STAT_OFFSET(efer_reload) }, | 65 | { "efer_reload", VCPU_STAT(efer_reload) }, |
65 | { "fpu_reload", STAT_OFFSET(fpu_reload) }, | 66 | { "fpu_reload", VCPU_STAT(fpu_reload) }, |
66 | { "insn_emulation", STAT_OFFSET(insn_emulation) }, | 67 | { "insn_emulation", VCPU_STAT(insn_emulation) }, |
67 | { "insn_emulation_fail", STAT_OFFSET(insn_emulation_fail) }, | 68 | { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) }, |
68 | { NULL } | 69 | { NULL } |
69 | }; | 70 | }; |
70 | 71 | ||