diff options
author | John Baldwin <jhb@FreeBSD.org> | 2022-02-07 22:11:10 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2022-02-07 22:11:10 +0000 |
commit | 64269786170ffd8e3348edea0fc5f5b09b79391e (patch) | |
tree | 60c1e5cf14685f0619cc76ecce06670822fbe6ba /lib/libvmmapi | |
parent | 3f3e4f3c7472640aab998612a2253da95102345a (diff) | |
download | src-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.c | 41 |
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); } |