summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2016-10-18 22:49:47 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2016-11-02 16:32:17 -0400
commitce35ef27d4b751706f76c48d32a7b0d27f2d2d19 (patch)
tree9c1e63ba478cb2de6d7cacd1c28e7f013651d1d1 /virt
parent868a32f327e34b82f2b087228fbb7df176c246e9 (diff)
kvm/stats: Update kvm stats to clear on write to their debugfs entry
Various kvm vm and vcpu stats are provided via debugfs entries. Currently there is no way to reset these stats back to zero. Add the ability to clear (reset back to zero) these stats on a per stat basis by writing to the debugfs files. Only a write value of 0 is accepted. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/kvm_main.c78
1 files changed, 72 insertions, 6 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d92c3d5b0fbe..b44edd85011a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -595,7 +595,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
595 stat_data->kvm = kvm; 595 stat_data->kvm = kvm;
596 stat_data->offset = p->offset; 596 stat_data->offset = p->offset;
597 kvm->debugfs_stat_data[p - debugfs_entries] = stat_data; 597 kvm->debugfs_stat_data[p - debugfs_entries] = stat_data;
598 if (!debugfs_create_file(p->name, 0444, 598 if (!debugfs_create_file(p->name, 0644,
599 kvm->debugfs_dentry, 599 kvm->debugfs_dentry,
600 stat_data, 600 stat_data,
601 stat_fops_per_vm[p->kind])) 601 stat_fops_per_vm[p->kind]))
@@ -3663,11 +3663,23 @@ static int vm_stat_get_per_vm(void *data, u64 *val)
3663 return 0; 3663 return 0;
3664} 3664}
3665 3665
3666static int vm_stat_clear_per_vm(void *data, u64 val)
3667{
3668 struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
3669
3670 if (val)
3671 return -EINVAL;
3672
3673 *(ulong *)((void *)stat_data->kvm + stat_data->offset) = 0;
3674
3675 return 0;
3676}
3677
3666static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file) 3678static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file)
3667{ 3679{
3668 __simple_attr_check_format("%llu\n", 0ull); 3680 __simple_attr_check_format("%llu\n", 0ull);
3669 return kvm_debugfs_open(inode, file, vm_stat_get_per_vm, 3681 return kvm_debugfs_open(inode, file, vm_stat_get_per_vm,
3670 NULL, "%llu\n"); 3682 vm_stat_clear_per_vm, "%llu\n");
3671} 3683}
3672 3684
3673static const struct file_operations vm_stat_get_per_vm_fops = { 3685static const struct file_operations vm_stat_get_per_vm_fops = {
@@ -3693,11 +3705,26 @@ static int vcpu_stat_get_per_vm(void *data, u64 *val)
3693 return 0; 3705 return 0;
3694} 3706}
3695 3707
3708static int vcpu_stat_clear_per_vm(void *data, u64 val)
3709{
3710 int i;
3711 struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
3712 struct kvm_vcpu *vcpu;
3713
3714 if (val)
3715 return -EINVAL;
3716
3717 kvm_for_each_vcpu(i, vcpu, stat_data->kvm)
3718 *(u64 *)((void *)vcpu + stat_data->offset) = 0;
3719
3720 return 0;
3721}
3722
3696static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file) 3723static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file)
3697{ 3724{
3698 __simple_attr_check_format("%llu\n", 0ull); 3725 __simple_attr_check_format("%llu\n", 0ull);
3699 return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm, 3726 return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm,
3700 NULL, "%llu\n"); 3727 vcpu_stat_clear_per_vm, "%llu\n");
3701} 3728}
3702 3729
3703static const struct file_operations vcpu_stat_get_per_vm_fops = { 3730static const struct file_operations vcpu_stat_get_per_vm_fops = {
@@ -3732,7 +3759,26 @@ static int vm_stat_get(void *_offset, u64 *val)
3732 return 0; 3759 return 0;
3733} 3760}
3734 3761
3735DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n"); 3762static int vm_stat_clear(void *_offset, u64 val)
3763{
3764 unsigned offset = (long)_offset;
3765 struct kvm *kvm;
3766 struct kvm_stat_data stat_tmp = {.offset = offset};
3767
3768 if (val)
3769 return -EINVAL;
3770
3771 spin_lock(&kvm_lock);
3772 list_for_each_entry(kvm, &vm_list, vm_list) {
3773 stat_tmp.kvm = kvm;
3774 vm_stat_clear_per_vm((void *)&stat_tmp, 0);
3775 }
3776 spin_unlock(&kvm_lock);
3777
3778 return 0;
3779}
3780
3781DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, vm_stat_clear, "%llu\n");
3736 3782
3737static int vcpu_stat_get(void *_offset, u64 *val) 3783static int vcpu_stat_get(void *_offset, u64 *val)
3738{ 3784{
@@ -3752,7 +3798,27 @@ static int vcpu_stat_get(void *_offset, u64 *val)
3752 return 0; 3798 return 0;
3753} 3799}
3754 3800
3755DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); 3801static int vcpu_stat_clear(void *_offset, u64 val)
3802{
3803 unsigned offset = (long)_offset;
3804 struct kvm *kvm;
3805 struct kvm_stat_data stat_tmp = {.offset = offset};
3806
3807 if (val)
3808 return -EINVAL;
3809
3810 spin_lock(&kvm_lock);
3811 list_for_each_entry(kvm, &vm_list, vm_list) {
3812 stat_tmp.kvm = kvm;
3813 vcpu_stat_clear_per_vm((void *)&stat_tmp, 0);
3814 }
3815 spin_unlock(&kvm_lock);
3816
3817 return 0;
3818}
3819
3820DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, vcpu_stat_clear,
3821 "%llu\n");
3756 3822
3757static const struct file_operations *stat_fops[] = { 3823static const struct file_operations *stat_fops[] = {
3758 [KVM_STAT_VCPU] = &vcpu_stat_fops, 3824 [KVM_STAT_VCPU] = &vcpu_stat_fops,
@@ -3770,7 +3836,7 @@ static int kvm_init_debug(void)
3770 3836
3771 kvm_debugfs_num_entries = 0; 3837 kvm_debugfs_num_entries = 0;
3772 for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) { 3838 for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) {
3773 if (!debugfs_create_file(p->name, 0444, kvm_debugfs_dir, 3839 if (!debugfs_create_file(p->name, 0644, kvm_debugfs_dir,
3774 (void *)(long)p->offset, 3840 (void *)(long)p->offset,
3775 stat_fops[p->kind])) 3841 stat_fops[p->kind]))
3776 goto out_dir; 3842 goto out_dir;