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
This commit is contained in:
Peter Grehan 2014-06-25 22:13:35 +00:00
parent d2dc06ca16
commit cf1d80d88c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267884
3 changed files with 78 additions and 5 deletions

View File

@ -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);

View File

@ -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];

View File

@ -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,8 +104,21 @@ 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);