aboutsummaryrefslogtreecommitdiff
path: root/lib/libvmmapi
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-02-07 22:11:10 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2022-02-07 22:11:10 +0000
commit64269786170ffd8e3348edea0fc5f5b09b79391e (patch)
tree60c1e5cf14685f0619cc76ecce06670822fbe6ba /lib/libvmmapi
parent3f3e4f3c7472640aab998612a2253da95102345a (diff)
downloadsrc-64269786170ffd8e3348edea0fc5f5b09b79391e.tar.gz
src-64269786170ffd8e3348edea0fc5f5b09b79391e.zip
Extend the VMM stats interface to support a dynamic count of statistics.
- Add a starting index to 'struct vmstats' and change the VM_STATS ioctl to fetch the 64 stats starting at that index. A compat shim for <= 13 continues to fetch only the first 64 stats. - Extend vm_get_stats() in libvmmapi to use a loop and a static thread local buffer which grows to hold the stats needed. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D27463
Diffstat (limited to 'lib/libvmmapi')
-rw-r--r--lib/libvmmapi/vmmapi.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
index a2d26b1b33b9..0291e4a10c33 100644
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -1066,19 +1066,44 @@ uint64_t *
vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv,
int *ret_entries)
{
- int error;
-
- static struct vm_stats vmstats;
-
+ static _Thread_local uint64_t *stats_buf;
+ static _Thread_local u_int stats_count;
+ uint64_t *new_stats;
+ struct vm_stats vmstats;
+ u_int count, index;
+ bool have_stats;
+
+ have_stats = false;
vmstats.cpuid = vcpu;
+ count = 0;
+ for (index = 0;; index += nitems(vmstats.statbuf)) {
+ vmstats.index = index;
+ if (ioctl(ctx->fd, VM_STATS, &vmstats) != 0)
+ break;
+ if (stats_count < index + vmstats.num_entries) {
+ new_stats = realloc(stats_buf,
+ (index + vmstats.num_entries) * sizeof(uint64_t));
+ if (new_stats == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ stats_count = index + vmstats.num_entries;
+ stats_buf = new_stats;
+ }
+ memcpy(stats_buf + index, vmstats.statbuf,
+ vmstats.num_entries * sizeof(uint64_t));
+ count += vmstats.num_entries;
+ have_stats = true;
- error = ioctl(ctx->fd, VM_STATS, &vmstats);
- if (error == 0) {
+ if (vmstats.num_entries != nitems(vmstats.statbuf))
+ break;
+ }
+ if (have_stats) {
if (ret_entries)
- *ret_entries = vmstats.num_entries;
+ *ret_entries = count;
if (ret_tv)
*ret_tv = vmstats.tv;
- return (vmstats.statbuf);
+ return (stats_buf);
} else
return (NULL);
}