1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 2011 NetApp, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #ifndef _DEV_VMM_STAT_H_
33 #define _DEV_VMM_STAT_H_
34
35 struct vm;
36
37 #define MAX_VMM_STAT_ELEMS 64 /* arbitrary */
38
39 struct vmm_stat_type;
40 typedef void (*vmm_stat_func_t)(struct vcpu *vcpu,
41 struct vmm_stat_type *stat);
42 typedef bool (*vmm_stat_func_pred_t)(void);
43
44 struct vmm_stat_type {
45 int index; /* position in the stats buffer */
46 int nelems; /* standalone or array */
47 const char *desc; /* description of statistic */
48 vmm_stat_func_t func;
49 vmm_stat_func_pred_t pred; /* predicate to check during registration */
50 };
51
52 void vmm_stat_register(void *arg);
53
54 #define VMM_STAT_FDEFINE(type, _nelems, _desc, _func, _pred) \
55 struct vmm_stat_type type[1] = { \
56 { \
57 .index = -1, \
58 .nelems = _nelems, \
59 .desc = _desc, \
60 .func = _func, \
61 .pred = _pred, \
62 } \
63 }; \
64 SYSINIT(type##_stat, SI_SUB_KLD, SI_ORDER_ANY, vmm_stat_register, type)
65
66 #define VMM_STAT_DEFINE(type, nelems, desc, pred) \
67 VMM_STAT_FDEFINE(type, nelems, desc, NULL, pred)
68
69 #define VMM_STAT_DECLARE(type) \
70 extern struct vmm_stat_type type[1]
71
72 #define VMM_STAT(type, desc) \
73 VMM_STAT_DEFINE(type, 1, desc, NULL)
74
75 #define VMM_STAT_FUNC(type, desc, func) \
76 VMM_STAT_FDEFINE(type, 1, desc, func, NULL)
77
78 #define VMM_STAT_ARRAY(type, nelems, desc) \
79 VMM_STAT_DEFINE(type, nelems, desc, NULL)
80
81 void *vmm_stat_alloc(void);
82 void vmm_stat_init(void *vp);
83 void vmm_stat_free(void *vp);
84
85 int vmm_stat_copy(struct vcpu *vcpu, int index, int count,
86 int *num_stats, uint64_t *buf);
87 int vmm_stat_desc_copy(int index, char *buf, int buflen);
88
89 static void __inline
vmm_stat_array_incr(struct vcpu * vcpu,struct vmm_stat_type * vst,int statidx,uint64_t x)90 vmm_stat_array_incr(struct vcpu *vcpu, struct vmm_stat_type *vst, int statidx,
91 uint64_t x)
92 {
93 #ifdef VMM_KEEP_STATS
94 uint64_t *stats;
95
96 stats = vcpu_stats(vcpu);
97
98 if (vst->index >= 0 && statidx < vst->nelems)
99 stats[vst->index + statidx] += x;
100 #endif
101 }
102
103 static void __inline
vmm_stat_array_set(struct vcpu * vcpu,struct vmm_stat_type * vst,int statidx,uint64_t val)104 vmm_stat_array_set(struct vcpu *vcpu, struct vmm_stat_type *vst, int statidx,
105 uint64_t val)
106 {
107 #ifdef VMM_KEEP_STATS
108 uint64_t *stats;
109
110 stats = vcpu_stats(vcpu);
111
112 if (vst->index >= 0 && statidx < vst->nelems)
113 stats[vst->index + statidx] = val;
114 #endif
115 }
116
117 static void __inline
vmm_stat_incr(struct vcpu * vcpu,struct vmm_stat_type * vst,uint64_t x)118 vmm_stat_incr(struct vcpu *vcpu, struct vmm_stat_type *vst, uint64_t x)
119 {
120
121 #ifdef VMM_KEEP_STATS
122 vmm_stat_array_incr(vcpu, vst, 0, x);
123 #endif
124 }
125
126 static void __inline
vmm_stat_set(struct vcpu * vcpu,struct vmm_stat_type * vst,uint64_t val)127 vmm_stat_set(struct vcpu *vcpu, struct vmm_stat_type *vst, uint64_t val)
128 {
129
130 #ifdef VMM_KEEP_STATS
131 vmm_stat_array_set(vcpu, vst, 0, val);
132 #endif
133 }
134
135 #endif /* !_DEV_VMM_STAT_H_ */
136