Date: Fri, 29 Apr 2022 23:12:43 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: ffd150099ca0 - stable/13 - Extend the VMM stats interface to support a dynamic count of statistics. Message-ID: <202204292312.23TNCh2J045020@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=ffd150099ca0fbbecb62814e73dff9388fbe3b87 commit ffd150099ca0fbbecb62814e73dff9388fbe3b87 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2022-02-07 22:11:10 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2022-04-29 23:08:17 +0000 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 (cherry picked from commit 64269786170ffd8e3348edea0fc5f5b09b79391e) --- lib/libvmmapi/vmmapi.c | 41 +++++++++++++++++++++++++++++++++-------- sys/amd64/include/vmm_dev.h | 1 + sys/amd64/vmm/vmm_dev.c | 29 +++++++++++++++++++++++++++-- sys/amd64/vmm/vmm_stat.c | 23 ++++++++++++++++++----- sys/amd64/vmm/vmm_stat.h | 6 ++---- 5 files changed, 81 insertions(+), 19 deletions(-) diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 0543c92f4300..03c2538e226d 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); } diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h index a048e05d4b7c..9ed8f32302ae 100644 --- a/sys/amd64/include/vmm_dev.h +++ b/sys/amd64/include/vmm_dev.h @@ -174,6 +174,7 @@ struct vm_nmi { #define MAX_VM_STATS 64 struct vm_stats { int cpuid; /* in */ + int index; /* in */ int num_entries; /* out */ struct timeval tv; uint64_t statbuf[MAX_VM_STATS]; diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 2ce9470cf6dd..a83c74219fee 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -69,6 +69,18 @@ __FBSDID("$FreeBSD$"); #include "io/vhpet.h" #include "io/vrtc.h" +#ifdef COMPAT_FREEBSD13 +struct vm_stats_old { + int cpuid; /* in */ + int num_entries; /* out */ + struct timeval tv; + uint64_t statbuf[MAX_VM_STATS]; +}; + +#define VM_STATS_OLD \ + _IOWR('v', IOCNUM_VM_STATS, struct vm_stats_old) +#endif + struct devmem_softc { int segid; char *name; @@ -376,6 +388,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; struct vm_nmi *vmnmi; +#ifdef COMPAT_FREEBSD13 + struct vm_stats_old *vmstats_old; +#endif struct vm_stats *vmstats; struct vm_stat_desc *statdesc; struct vm_x2apic *x2apic; @@ -501,11 +516,21 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, statdesc->desc, sizeof(statdesc->desc)); break; } +#ifdef COMPAT_FREEBSD13 + case VM_STATS_OLD: + vmstats_old = (struct vm_stats_old *)data; + getmicrotime(&vmstats_old->tv); + error = vmm_stat_copy(sc->vm, vmstats_old->cpuid, 0, + nitems(vmstats_old->statbuf), + &vmstats_old->num_entries, + vmstats_old->statbuf); + break; +#endif case VM_STATS: { - CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_ELEMS); vmstats = (struct vm_stats *)data; getmicrotime(&vmstats->tv); - error = vmm_stat_copy(sc->vm, vmstats->cpuid, + error = vmm_stat_copy(sc->vm, vmstats->cpuid, vmstats->index, + nitems(vmstats->statbuf), &vmstats->num_entries, vmstats->statbuf); break; } diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c index 89133d4b3868..497db4452f3b 100644 --- a/sys/amd64/vmm/vmm_stat.c +++ b/sys/amd64/vmm/vmm_stat.c @@ -82,15 +82,29 @@ vmm_stat_register(void *arg) } int -vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf) +vmm_stat_copy(struct vm *vm, int vcpu, int index, int count, int *num_stats, + uint64_t *buf) { struct vmm_stat_type *vst; uint64_t *stats; - int i; + int i, tocopy; if (vcpu < 0 || vcpu >= vm_get_maxcpus(vm)) return (EINVAL); + if (index < 0 || count < 0) + return (EINVAL); + + if (index > vst_num_elems) + return (ENOENT); + + if (index == vst_num_elems) { + *num_stats = 0; + return (0); + } + + tocopy = min(vst_num_elems - index, count); + /* Let stats functions update their counters */ for (i = 0; i < vst_num_types; i++) { vst = vsttab[i]; @@ -100,9 +114,8 @@ vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf) /* Copy over the stats */ stats = vcpu_stats(vm, vcpu); - for (i = 0; i < vst_num_elems; i++) - buf[i] = stats[i]; - *num_stats = vst_num_elems; + memcpy(buf, stats + index, tocopy * sizeof(stats[0])); + *num_stats = tocopy; return (0); } diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h index f97743e77fe7..0e9c8db8429d 100644 --- a/sys/amd64/vmm/vmm_stat.h +++ b/sys/amd64/vmm/vmm_stat.h @@ -87,10 +87,8 @@ void *vmm_stat_alloc(void); void vmm_stat_init(void *vp); void vmm_stat_free(void *vp); -/* - * 'buf' should be at least fit 'MAX_VMM_STAT_TYPES' entries - */ -int vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf); +int vmm_stat_copy(struct vm *vm, int vcpu, int index, int count, + int *num_stats, uint64_t *buf); int vmm_stat_desc_copy(int index, char *buf, int buflen); static void __inline
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202204292312.23TNCh2J045020>