aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorPeter Grehan <grehan@FreeBSD.org>2014-06-25 22:13:35 +0000
committerPeter Grehan <grehan@FreeBSD.org>2014-06-25 22:13:35 +0000
commitcf1d80d88cb159001d567a86eb596efb5a39a72a (patch)
tree5f7fe3e465af3cbccb096242eb1b593c186a5bfd /sys/amd64
parentd2dc06ca16765436a229d28041d5b917bcf2fbc4 (diff)
downloadsrc-cf1d80d88cb159001d567a86eb596efb5a39a72a.tar.gz
src-cf1d80d88cb159001d567a86eb596efb5a39a72a.zip
Expose the amount of resident and wired memory from the guest's vmspace.
This is different than the amount shown for the process e.g. by /usr/bin/top - that is the mappings faulted in by the mmap'd region of guest memory. The values can be fetched with bhyvectl # bhyvectl --get-stats --vm=myvm ... Resident memory 413749248 Wired memory 0 ... vmm_stat.[ch] - Modify the counter code in bhyve to allow direct setting of a counter as opposed to incrementing, and providing a callback to fetch a counter's value. Reviewed by: neel
Notes
Notes: svn path=/head/; revision=267884
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/vmm/vmm.c31
-rw-r--r--sys/amd64/vmm/vmm_stat.c13
-rw-r--r--sys/amd64/vmm/vmm_stat.h39
3 files changed, 78 insertions, 5 deletions
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 8edb3fb47917..c2a9fd1e117e 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1992,3 +1992,34 @@ vm_segment_name(int seg)
("%s: invalid segment encoding %d", __func__, seg));
return (seg_names[seg]);
}
+
+
+/*
+ * Return the amount of in-use and wired memory for the VM. Since
+ * these are global stats, only return the values with for vCPU 0
+ */
+VMM_STAT_DECLARE(VMM_MEM_RESIDENT);
+VMM_STAT_DECLARE(VMM_MEM_WIRED);
+
+static void
+vm_get_rescnt(struct vm *vm, int vcpu, struct vmm_stat_type *stat)
+{
+
+ if (vcpu == 0) {
+ vmm_stat_set(vm, vcpu, VMM_MEM_RESIDENT,
+ PAGE_SIZE * vmspace_resident_count(vm->vmspace));
+ }
+}
+
+static void
+vm_get_wiredcnt(struct vm *vm, int vcpu, struct vmm_stat_type *stat)
+{
+
+ if (vcpu == 0) {
+ vmm_stat_set(vm, vcpu, VMM_MEM_WIRED,
+ PAGE_SIZE * pmap_wired_count(vmspace_pmap(vm->vmspace)));
+ }
+}
+
+VMM_STAT_FUNC(VMM_MEM_RESIDENT, "Resident memory", vm_get_rescnt);
+VMM_STAT_FUNC(VMM_MEM_WIRED, "Wired memory", vm_get_wiredcnt);
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
index ef9f41173fee..9ecf9afd8a81 100644
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -83,12 +83,21 @@ vmm_stat_register(void *arg)
int
vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf)
{
- int i;
+ struct vmm_stat_type *vst;
uint64_t *stats;
+ int i;
if (vcpu < 0 || vcpu >= VM_MAXCPU)
return (EINVAL);
-
+
+ /* Let stats functions update their counters */
+ for (i = 0; i < vst_num_types; i++) {
+ vst = vsttab[i];
+ if (vst->func != NULL)
+ (*vst->func)(vm, vcpu, vst);
+ }
+
+ /* Copy over the stats */
stats = vcpu_stats(vm, vcpu);
for (i = 0; i < vst_num_elems; i++)
buf[i] = stats[i];
diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h
index 6e98965ac270..1640ba37e025 100644
--- a/sys/amd64/vmm/vmm_stat.h
+++ b/sys/amd64/vmm/vmm_stat.h
@@ -42,21 +42,29 @@ enum vmm_stat_scope {
VMM_STAT_SCOPE_AMD, /* AMD SVM specific statistic */
};
+struct vmm_stat_type;
+typedef void (*vmm_stat_func_t)(struct vm *vm, int vcpu,
+ struct vmm_stat_type *stat);
+
struct vmm_stat_type {
int index; /* position in the stats buffer */
int nelems; /* standalone or array */
const char *desc; /* description of statistic */
+ vmm_stat_func_t func;
enum vmm_stat_scope scope;
};
void vmm_stat_register(void *arg);
-#define VMM_STAT_DEFINE(type, nelems, desc, scope) \
+#define VMM_STAT_FDEFINE(type, nelems, desc, func, scope) \
struct vmm_stat_type type[1] = { \
- { -1, nelems, desc, scope } \
+ { -1, nelems, desc, func, scope } \
}; \
SYSINIT(type##_stat, SI_SUB_KLD, SI_ORDER_ANY, vmm_stat_register, type)
+#define VMM_STAT_DEFINE(type, nelems, desc, scope) \
+ VMM_STAT_FDEFINE(type, nelems, desc, NULL, scope)
+
#define VMM_STAT_DECLARE(type) \
extern struct vmm_stat_type type[1]
@@ -67,6 +75,9 @@ void vmm_stat_register(void *arg);
#define VMM_STAT_AMD(type, desc) \
VMM_STAT_DEFINE(type, 1, desc, VMM_STAT_SCOPE_AMD)
+#define VMM_STAT_FUNC(type, desc, func) \
+ VMM_STAT_FDEFINE(type, 1, desc, func, VMM_STAT_SCOPE_ANY)
+
#define VMM_STAT_ARRAY(type, nelems, desc) \
VMM_STAT_DEFINE(type, nelems, desc, VMM_STAT_SCOPE_ANY)
@@ -93,9 +104,22 @@ vmm_stat_array_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
stats[vst->index + statidx] += x;
#endif
}
-
static void __inline
+vmm_stat_array_set(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
+ int statidx, uint64_t val)
+{
+#ifdef VMM_KEEP_STATS
+ uint64_t *stats;
+
+ stats = vcpu_stats(vm, vcpu);
+
+ if (vst->index >= 0 && statidx < vst->nelems)
+ stats[vst->index + statidx] = val;
+#endif
+}
+
+static void __inline
vmm_stat_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t x)
{
@@ -104,6 +128,15 @@ vmm_stat_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t x)
#endif
}
+static void __inline
+vmm_stat_set(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t val)
+{
+
+#ifdef VMM_KEEP_STATS
+ vmm_stat_array_set(vm, vcpu, vst, 0, val);
+#endif
+}
+
VMM_STAT_DECLARE(VCPU_MIGRATIONS);
VMM_STAT_DECLARE(VMEXIT_COUNT);
VMM_STAT_DECLARE(VMEXIT_EXTINT);