Commit ce35ef27 authored by Suraj Jitindar Singh's avatar Suraj Jitindar Singh Committed by Paolo Bonzini

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: default avatarSuraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
parent 868a32f3
...@@ -595,7 +595,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd) ...@@ -595,7 +595,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
stat_data->kvm = kvm; stat_data->kvm = kvm;
stat_data->offset = p->offset; stat_data->offset = p->offset;
kvm->debugfs_stat_data[p - debugfs_entries] = stat_data; kvm->debugfs_stat_data[p - debugfs_entries] = stat_data;
if (!debugfs_create_file(p->name, 0444, if (!debugfs_create_file(p->name, 0644,
kvm->debugfs_dentry, kvm->debugfs_dentry,
stat_data, stat_data,
stat_fops_per_vm[p->kind])) stat_fops_per_vm[p->kind]))
...@@ -3663,11 +3663,23 @@ static int vm_stat_get_per_vm(void *data, u64 *val) ...@@ -3663,11 +3663,23 @@ static int vm_stat_get_per_vm(void *data, u64 *val)
return 0; return 0;
} }
static int vm_stat_clear_per_vm(void *data, u64 val)
{
struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
if (val)
return -EINVAL;
*(ulong *)((void *)stat_data->kvm + stat_data->offset) = 0;
return 0;
}
static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file) static int vm_stat_get_per_vm_open(struct inode *inode, struct file *file)
{ {
__simple_attr_check_format("%llu\n", 0ull); __simple_attr_check_format("%llu\n", 0ull);
return kvm_debugfs_open(inode, file, vm_stat_get_per_vm, return kvm_debugfs_open(inode, file, vm_stat_get_per_vm,
NULL, "%llu\n"); vm_stat_clear_per_vm, "%llu\n");
} }
static const struct file_operations vm_stat_get_per_vm_fops = { static 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,11 +3705,26 @@ static int vcpu_stat_get_per_vm(void *data, u64 *val)
return 0; return 0;
} }
static int vcpu_stat_clear_per_vm(void *data, u64 val)
{
int i;
struct kvm_stat_data *stat_data = (struct kvm_stat_data *)data;
struct kvm_vcpu *vcpu;
if (val)
return -EINVAL;
kvm_for_each_vcpu(i, vcpu, stat_data->kvm)
*(u64 *)((void *)vcpu + stat_data->offset) = 0;
return 0;
}
static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file) static int vcpu_stat_get_per_vm_open(struct inode *inode, struct file *file)
{ {
__simple_attr_check_format("%llu\n", 0ull); __simple_attr_check_format("%llu\n", 0ull);
return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm, return kvm_debugfs_open(inode, file, vcpu_stat_get_per_vm,
NULL, "%llu\n"); vcpu_stat_clear_per_vm, "%llu\n");
} }
static const struct file_operations vcpu_stat_get_per_vm_fops = { static const struct file_operations vcpu_stat_get_per_vm_fops = {
...@@ -3732,7 +3759,26 @@ static int vm_stat_get(void *_offset, u64 *val) ...@@ -3732,7 +3759,26 @@ static int vm_stat_get(void *_offset, u64 *val)
return 0; return 0;
} }
DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, NULL, "%llu\n"); static int vm_stat_clear(void *_offset, u64 val)
{
unsigned offset = (long)_offset;
struct kvm *kvm;
struct kvm_stat_data stat_tmp = {.offset = offset};
if (val)
return -EINVAL;
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
stat_tmp.kvm = kvm;
vm_stat_clear_per_vm((void *)&stat_tmp, 0);
}
spin_unlock(&kvm_lock);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(vm_stat_fops, vm_stat_get, vm_stat_clear, "%llu\n");
static int vcpu_stat_get(void *_offset, u64 *val) static int vcpu_stat_get(void *_offset, u64 *val)
{ {
...@@ -3752,7 +3798,27 @@ static int vcpu_stat_get(void *_offset, u64 *val) ...@@ -3752,7 +3798,27 @@ static int vcpu_stat_get(void *_offset, u64 *val)
return 0; return 0;
} }
DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); static int vcpu_stat_clear(void *_offset, u64 val)
{
unsigned offset = (long)_offset;
struct kvm *kvm;
struct kvm_stat_data stat_tmp = {.offset = offset};
if (val)
return -EINVAL;
spin_lock(&kvm_lock);
list_for_each_entry(kvm, &vm_list, vm_list) {
stat_tmp.kvm = kvm;
vcpu_stat_clear_per_vm((void *)&stat_tmp, 0);
}
spin_unlock(&kvm_lock);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, vcpu_stat_clear,
"%llu\n");
static const struct file_operations *stat_fops[] = { static const struct file_operations *stat_fops[] = {
[KVM_STAT_VCPU] = &vcpu_stat_fops, [KVM_STAT_VCPU] = &vcpu_stat_fops,
...@@ -3770,7 +3836,7 @@ static int kvm_init_debug(void) ...@@ -3770,7 +3836,7 @@ static int kvm_init_debug(void)
kvm_debugfs_num_entries = 0; kvm_debugfs_num_entries = 0;
for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) { for (p = debugfs_entries; p->name; ++p, kvm_debugfs_num_entries++) {
if (!debugfs_create_file(p->name, 0444, kvm_debugfs_dir, if (!debugfs_create_file(p->name, 0644, kvm_debugfs_dir,
(void *)(long)p->offset, (void *)(long)p->offset,
stat_fops[p->kind])) stat_fops[p->kind]))
goto out_dir; goto out_dir;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment