All of lore.kernel.org
 help / color / mirror / Atom feed
From: Milan Pandurov <milanpa@amazon.de>
To: <kvm@vger.kernel.org>
Cc: <pbonzini@redhat.com>, <rkrcmar@redhat.com>, <graf@amazon.de>,
	<borntraeger@de.ibm.com>
Subject: [PATCH 2/2] kvm: Add ioctl for gathering debug counters
Date: Wed, 15 Jan 2020 14:43:03 +0100	[thread overview]
Message-ID: <20200115134303.30668-1-milanpa@amazon.de> (raw)

KVM exposes debug counters through individual debugfs files.
Monitoring these counters requires debugfs to be enabled/accessible for
the application, which might not be always the case.
Additionally, periodic monitoring multiple debugfs files from
userspace requires multiple file open/read/close + atoi conversion
operations, which is not very efficient.

Let's expose new interface to userspace for garhering these
statistics with one ioctl.

Two new ioctl methods are added:
 - KVM_GET_SUPPORTED_DEBUGFS_STAT : Returns list of available counter
 names. Names correspond to the debugfs file names
 - KVM_GET_DEBUGFS_VALUES : Returns list of u64 values each
 corresponding to a value described in KVM_GET_SUPPORTED_DEBUGFS_STAT.

Userspace application can read counter description once using
KVM_GET_SUPPORTED_DEBUGFS_STAT and periodically invoke the
KVM_GET_DEBUGFS_VALUES to get value update.

Signed-off-by: Milan Pandurov <milanpa@amazon.de>

---
Current approach returns all available counters to userspace which might
be an overkill. This can be further extended with an interface in which
userspace provides indicies of counters it is interested in counters
will be filled accordingly.

NOTE: This patch is placed on top of:
https://www.spinics.net/lists/kvm/msg202599.html
---
 include/uapi/linux/kvm.h | 21 ++++++++++++
 virt/kvm/kvm_main.c      | 70 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index f0a16b4adbbd..07ad35ddc14f 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1473,6 +1473,27 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_ARM_SVE */
 #define KVM_ARM_VCPU_FINALIZE	  _IOW(KVMIO,  0xc2, int)
 
+#define KVM_DBG_DESCR_NAME_MAX_SIZE 30
+struct kvm_debugfs_entry_description {
+	char name[KVM_DBG_DESCR_NAME_MAX_SIZE + 1];
+};
+
+struct kvm_debugfs_entries_description {
+	__u32 nentries;
+	struct kvm_debugfs_entry_description entry[0];
+};
+
+struct kvm_debug_stats {
+	__u32 nentries;
+	__u64 values[0];
+};
+
+/* Get description of available debugfs counters */
+#define KVM_GET_SUPPORTED_DEBUGFS_STATS                                        \
+	_IOWR(KVMIO, 0xc2, struct kvm_debugfs_entries_description)
+/* Get values from debugfs */
+#define KVM_GET_DEBUGFS_VALUES _IOWR(KVMIO, 0xc3, struct kvm_debug_stats)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
 	/* Guest initialization commands */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9eb6e081da3a..66b36b7e347e 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -146,6 +146,10 @@ static void kvm_io_bus_destroy(struct kvm_io_bus *bus);
 
 static void mark_page_dirty_in_slot(struct kvm_memory_slot *memslot, gfn_t gfn);
 
+static long kvm_get_debugfs_entry_description(struct kvm *kvm,
+					      void __user *argp);
+static long kvm_get_debugfs_values(struct kvm *kvm, void __user *argp);
+
 __visible bool kvm_rebooting;
 EXPORT_SYMBOL_GPL(kvm_rebooting);
 
@@ -3452,6 +3456,12 @@ static long kvm_vm_ioctl(struct file *filp,
 	case KVM_CHECK_EXTENSION:
 		r = kvm_vm_ioctl_check_extension_generic(kvm, arg);
 		break;
+	case KVM_GET_SUPPORTED_DEBUGFS_STATS:
+		r = kvm_get_debugfs_entry_description(kvm, argp);
+		break;
+	case KVM_GET_DEBUGFS_VALUES:
+		r = kvm_get_debugfs_values(kvm, argp);
+		break;
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}
@@ -4202,6 +4212,66 @@ static const struct file_operations *stat_fops[] = {
 	[KVM_STAT_VM]   = &vm_stat_fops,
 };
 
+static long kvm_get_debugfs_entry_description(struct kvm *kvm,
+					      void __user *argp)
+{
+	struct kvm_debugfs_entries_description *description = argp;
+	struct kvm_stats_debugfs_item *dbgfs_item = debugfs_entries;
+	bool should_copy = true;
+	size_t name_length = 0;
+	__u32 i = 0;
+
+	for (; dbgfs_item->name != NULL; dbgfs_item++, i++) {
+		if (i >= description->nentries)
+			should_copy = false;
+
+		if (should_copy) {
+			name_length = strlen(dbgfs_item->name);
+			name_length =
+				(name_length > KVM_DBG_DESCR_NAME_MAX_SIZE) ?
+					KVM_DBG_DESCR_NAME_MAX_SIZE :
+					name_length;
+
+			copy_to_user(description->entry[i].name,
+				     dbgfs_item->name, name_length);
+			put_user('\0',
+				 description->entry[i].name + name_length);
+		}
+	}
+	put_user(i, &description->nentries);
+	return (should_copy) ? 0 : -ENOMEM;
+}
+
+static long kvm_get_debugfs_values(struct kvm *kvm, void __user *argp)
+{
+	struct kvm_debug_stats *stats = argp;
+	struct kvm_stats_debugfs_item *dbgfs_item = debugfs_entries;
+	bool should_copy = true;
+	__u32 i = 0;
+	__u64 tmp = 0;
+
+	for (; dbgfs_item->name != NULL; dbgfs_item++, i++) {
+		if (i >= stats->nentries)
+			should_copy = false;
+
+		if (should_copy) {
+			switch (dbgfs_item->kind) {
+			case KVM_STAT_VM:
+				kvm_get_stat_per_vm(kvm, dbgfs_item->offset,
+						    &tmp);
+				break;
+			case KVM_STAT_VCPU:
+				kvm_get_stat_per_vcpu(kvm, dbgfs_item->offset,
+						      &tmp);
+				break;
+			}
+			put_user(tmp, stats->values + i);
+		}
+	}
+	put_user(i, &stats->nentries);
+	return (should_copy) ? 0 : -ENOMEM;
+}
+
 static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 {
 	struct kobj_uevent_env *env;
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




             reply	other threads:[~2020-01-15 13:43 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-15 13:43 Milan Pandurov [this message]
2020-01-15 14:04 ` [PATCH 2/2] kvm: Add ioctl for gathering debug counters Alexander Graf
2020-01-15 14:43   ` milanpa
2020-01-15 14:59     ` Alexander Graf
2020-01-17 23:38       ` Paolo Bonzini
2020-01-20 17:53         ` Alexander Graf
2020-01-20 18:57           ` milanpa
2020-01-21 15:38             ` Alexander Graf
2020-01-23 12:08               ` Paolo Bonzini
2020-01-23 12:32                 ` Alexander Graf
2020-01-23 14:19                   ` Paolo Bonzini
2020-01-23 14:45                     ` Alexander Graf
2020-01-23 14:50                       ` Paolo Bonzini
2020-01-23 14:58                         ` Alexander Graf
2020-01-23 15:05                           ` Paolo Bonzini
2020-01-23 15:27                             ` milanpa
2020-01-23 16:15                               ` Paolo Bonzini
2020-01-23 18:31                                 ` milanpa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200115134303.30668-1-milanpa@amazon.de \
    --to=milanpa@amazon.de \
    --cc=borntraeger@de.ibm.com \
    --cc=graf@amazon.de \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.