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:
parent
d2dc06ca16
commit
cf1d80d88c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267884
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user