Page MenuHomeFreeBSD

D27463.diff
No OneTemporary

D27463.diff

diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -1066,19 +1066,44 @@
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
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -174,6 +174,7 @@
#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
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -69,6 +69,18 @@
#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 @@
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 @@
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.h b/sys/amd64/vmm/vmm_stat.h
--- a/sys/amd64/vmm/vmm_stat.h
+++ b/sys/amd64/vmm/vmm_stat.h
@@ -87,10 +87,8 @@
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
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -82,15 +82,29 @@
}
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 @@
/* 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);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 7, 7:02 PM (20 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16515419
Default Alt Text
D27463.diff (4 KB)

Event Timeline