From owner-svn-src-all@FreeBSD.ORG Fri May 10 02:59:50 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id EE14EB08; Fri, 10 May 2013 02:59:50 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id CDDEE29E; Fri, 10 May 2013 02:59:50 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r4A2xoqH063197; Fri, 10 May 2013 02:59:50 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r4A2xonP063188; Fri, 10 May 2013 02:59:50 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201305100259.r4A2xonP063188@svn.freebsd.org> From: Neel Natu Date: Fri, 10 May 2013 02:59:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r250427 - in head/sys/amd64/vmm: . io X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 May 2013 02:59:51 -0000 Author: neel Date: Fri May 10 02:59:49 2013 New Revision: 250427 URL: http://svnweb.freebsd.org/changeset/base/250427 Log: Support array-type of stats in bhyve. An array-type stat in vmm.ko is defined as follows: VMM_STAT_ARRAY(IPIS_SENT, VM_MAXCPU, "ipis sent to vcpu"); It is incremented as follows: vmm_stat_array_incr(vm, vcpuid, IPIS_SENT, array_index, 1); And output of 'bhyvectl --get-stats' looks like: ipis sent to vcpu[0] 3114 ipis sent to vcpu[1] 0 Reviewed by: grehan Obtained from: NetApp Modified: head/sys/amd64/vmm/io/vlapic.c head/sys/amd64/vmm/vmm_dev.c head/sys/amd64/vmm/vmm_stat.c head/sys/amd64/vmm/vmm_stat.h Modified: head/sys/amd64/vmm/io/vlapic.c ============================================================================== --- head/sys/amd64/vmm/io/vlapic.c Fri May 10 02:57:46 2013 (r250426) +++ head/sys/amd64/vmm/io/vlapic.c Fri May 10 02:59:49 2013 (r250427) @@ -430,6 +430,8 @@ vlapic_fire_timer(struct vlapic *vlapic) } } +static VMM_STAT_ARRAY(IPIS_SENT, VM_MAXCPU, "ipis sent to vcpu"); + static int lapic_process_icr(struct vlapic *vlapic, uint64_t icrval) { @@ -466,9 +468,11 @@ lapic_process_icr(struct vlapic *vlapic, while ((i = cpusetobj_ffs(&dmask)) != 0) { i--; CPU_CLR(i, &dmask); - if (mode == APIC_DELMODE_FIXED) + if (mode == APIC_DELMODE_FIXED) { lapic_set_intr(vlapic->vm, i, vec); - else + vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid, + IPIS_SENT, i, 1); + } else vm_inject_nmi(vlapic->vm, i); } Modified: head/sys/amd64/vmm/vmm_dev.c ============================================================================== --- head/sys/amd64/vmm/vmm_dev.c Fri May 10 02:57:46 2013 (r250426) +++ head/sys/amd64/vmm/vmm_dev.c Fri May 10 02:59:49 2013 (r250427) @@ -235,18 +235,13 @@ vmmdev_ioctl(struct cdev *cdev, u_long c error = vm_run(sc->vm, vmrun); break; case VM_STAT_DESC: { - const char *desc; statdesc = (struct vm_stat_desc *)data; - desc = vmm_stat_desc(statdesc->index); - if (desc != NULL) { - error = 0; - strlcpy(statdesc->desc, desc, sizeof(statdesc->desc)); - } else - error = EINVAL; + error = vmm_stat_desc_copy(statdesc->index, + statdesc->desc, sizeof(statdesc->desc)); break; } case VM_STATS: { - CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_TYPES); + CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_ELEMS); vmstats = (struct vm_stats *)data; getmicrotime(&vmstats->tv); error = vmm_stat_copy(sc->vm, vmstats->cpuid, Modified: head/sys/amd64/vmm/vmm_stat.c ============================================================================== --- head/sys/amd64/vmm/vmm_stat.c Fri May 10 02:57:46 2013 (r250426) +++ head/sys/amd64/vmm/vmm_stat.c Fri May 10 02:59:49 2013 (r250427) @@ -39,8 +39,16 @@ __FBSDID("$FreeBSD$"); #include "vmm_util.h" #include "vmm_stat.h" -static int vstnum; -static struct vmm_stat_type *vsttab[MAX_VMM_STAT_TYPES]; +/* + * 'vst_num_elems' is the total number of addressable statistic elements + * 'vst_num_types' is the number of unique statistic types + * + * It is always true that 'vst_num_elems' is greater than or equal to + * 'vst_num_types'. This is because a stat type may represent more than + * one element (for e.g. VMM_STAT_ARRAY). + */ +static int vst_num_elems, vst_num_types; +static struct vmm_stat_type *vsttab[MAX_VMM_STAT_ELEMS]; static MALLOC_DEFINE(M_VMM_STAT, "vmm stat", "vmm stat"); @@ -59,13 +67,15 @@ vmm_stat_init(void *arg) if (vst->scope == VMM_STAT_SCOPE_AMD && !vmm_is_amd()) return; - if (vstnum >= MAX_VMM_STAT_TYPES) { + if (vst_num_elems + vst->nelems >= MAX_VMM_STAT_ELEMS) { printf("Cannot accomodate vmm stat type \"%s\"!\n", vst->desc); return; } - vst->index = vstnum; - vsttab[vstnum++] = vst; + vst->index = vst_num_elems; + vst_num_elems += vst->nelems; + + vsttab[vst_num_types++] = vst; } int @@ -78,9 +88,9 @@ vmm_stat_copy(struct vm *vm, int vcpu, i return (EINVAL); stats = vcpu_stats(vm, vcpu); - for (i = 0; i < vstnum; i++) + for (i = 0; i < vst_num_elems; i++) buf[i] = stats[i]; - *num_stats = vstnum; + *num_stats = vst_num_elems; return (0); } @@ -89,7 +99,7 @@ vmm_stat_alloc(void) { u_long size; - size = vstnum * sizeof(uint64_t); + size = vst_num_elems * sizeof(uint64_t); return (malloc(size, M_VMM_STAT, M_ZERO | M_WAITOK)); } @@ -100,14 +110,26 @@ vmm_stat_free(void *vp) free(vp, M_VMM_STAT); } -const char * -vmm_stat_desc(int index) +int +vmm_stat_desc_copy(int index, char *buf, int bufsize) { + int i; + struct vmm_stat_type *vst; + + for (i = 0; i < vst_num_types; i++) { + vst = vsttab[i]; + if (index >= vst->index && index < vst->index + vst->nelems) { + if (vst->nelems > 1) { + snprintf(buf, bufsize, "%s[%d]", + vst->desc, index - vst->index); + } else { + strlcpy(buf, vst->desc, bufsize); + } + return (0); /* found it */ + } + } - if (index >= 0 && index < vstnum) - return (vsttab[index]->desc); - else - return (NULL); + return (EINVAL); } /* global statistics */ Modified: head/sys/amd64/vmm/vmm_stat.h ============================================================================== --- head/sys/amd64/vmm/vmm_stat.h Fri May 10 02:57:46 2013 (r250426) +++ head/sys/amd64/vmm/vmm_stat.h Fri May 10 02:59:49 2013 (r250427) @@ -34,7 +34,7 @@ struct vm; -#define MAX_VMM_STAT_TYPES 64 /* arbitrary */ +#define MAX_VMM_STAT_ELEMS 64 /* arbitrary */ enum vmm_stat_scope { VMM_STAT_SCOPE_ANY, @@ -44,15 +44,16 @@ enum vmm_stat_scope { struct vmm_stat_type { int index; /* position in the stats buffer */ + int nelems; /* standalone or array */ const char *desc; /* description of statistic */ enum vmm_stat_scope scope; }; void vmm_stat_init(void *arg); -#define VMM_STAT_DEFINE(type, desc, scope) \ +#define VMM_STAT_DEFINE(type, nelems, desc, scope) \ struct vmm_stat_type type[1] = { \ - { -1, desc, scope } \ + { -1, nelems, desc, scope } \ }; \ SYSINIT(type##_stat, SI_SUB_KLD, SI_ORDER_ANY, vmm_stat_init, type) @@ -60,11 +61,14 @@ void vmm_stat_init(void *arg); extern struct vmm_stat_type type[1] #define VMM_STAT(type, desc) \ - VMM_STAT_DEFINE(type, desc, VMM_STAT_SCOPE_ANY) + VMM_STAT_DEFINE(type, 1, desc, VMM_STAT_SCOPE_ANY) #define VMM_STAT_INTEL(type, desc) \ - VMM_STAT_DEFINE(type, desc, VMM_STAT_SCOPE_INTEL) + VMM_STAT_DEFINE(type, 1, desc, VMM_STAT_SCOPE_INTEL) #define VMM_STAT_AMD(type, desc) \ - VMM_STAT_DEFINE(type, desc, VMM_STAT_SCOPE_AMD) + VMM_STAT_DEFINE(type, 1, desc, VMM_STAT_SCOPE_AMD) + +#define VMM_STAT_ARRAY(type, nelems, desc) \ + VMM_STAT_DEFINE(type, nelems, desc, VMM_STAT_SCOPE_ANY) void *vmm_stat_alloc(void); void vmm_stat_free(void *vp); @@ -73,15 +77,29 @@ 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); -const char *vmm_stat_desc(int index); +int vmm_stat_desc_copy(int index, char *buf, int buflen); + +static void __inline +vmm_stat_array_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, + int statidx, uint64_t x) +{ +#ifdef VMM_KEEP_STATS + uint64_t *stats; + + stats = vcpu_stats(vm, vcpu); + + if (vst->index >= 0 && statidx < vst->nelems) + stats[vst->index + statidx] += x; +#endif +} + static void __inline vmm_stat_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst, uint64_t x) { -#ifdef VMM_KEEP_STATS - uint64_t *stats = vcpu_stats(vm, vcpu); - if (vst->index >= 0) - stats[vst->index] += x; + +#ifdef VMM_KEEP_STATS + vmm_stat_array_incr(vm, vcpu, vst, 0, x); #endif }