1*22ce4affSfengbojiang /*-
2*22ce4affSfengbojiang * Copyright (c) 2014-2018 Netflix, Inc.
3*22ce4affSfengbojiang * All rights reserved.
4*22ce4affSfengbojiang *
5*22ce4affSfengbojiang * Redistribution and use in source and binary forms, with or without
6*22ce4affSfengbojiang * modification, are permitted provided that the following conditions
7*22ce4affSfengbojiang * are met:
8*22ce4affSfengbojiang * 1. Redistributions of source code must retain the above copyright
9*22ce4affSfengbojiang * notice, this list of conditions and the following disclaimer.
10*22ce4affSfengbojiang * 2. Redistributions in binary form must reproduce the above copyright
11*22ce4affSfengbojiang * notice, this list of conditions and the following disclaimer in the
12*22ce4affSfengbojiang * documentation and/or other materials provided with the distribution.
13*22ce4affSfengbojiang *
14*22ce4affSfengbojiang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*22ce4affSfengbojiang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*22ce4affSfengbojiang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*22ce4affSfengbojiang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*22ce4affSfengbojiang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*22ce4affSfengbojiang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*22ce4affSfengbojiang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*22ce4affSfengbojiang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*22ce4affSfengbojiang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*22ce4affSfengbojiang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*22ce4affSfengbojiang * SUCH DAMAGE.
25*22ce4affSfengbojiang *
26*22ce4affSfengbojiang * $FreeBSD$
27*22ce4affSfengbojiang */
28*22ce4affSfengbojiang
29*22ce4affSfengbojiang /*
30*22ce4affSfengbojiang * A kernel and user space statistics gathering API + infrastructure.
31*22ce4affSfengbojiang *
32*22ce4affSfengbojiang * Author: Lawrence Stewart <[email protected]>
33*22ce4affSfengbojiang *
34*22ce4affSfengbojiang * Things to ponder:
35*22ce4affSfengbojiang * - Register callbacks for events e.g. counter stat passing a threshold
36*22ce4affSfengbojiang *
37*22ce4affSfengbojiang * - How could this become SIFTRv2? Perhaps publishing records to a ring
38*22ce4affSfengbojiang * mapped between userspace and kernel?
39*22ce4affSfengbojiang *
40*22ce4affSfengbojiang * - Potential stat types:
41*22ce4affSfengbojiang * RATE: events per unit time
42*22ce4affSfengbojiang * TIMESERIES: timestamped records. Stored in voistate?
43*22ce4affSfengbojiang * EWMA: Exponential weighted moving average.
44*22ce4affSfengbojiang *
45*22ce4affSfengbojiang * - How should second order stats work e.g. stat "A" depends on "B"
46*22ce4affSfengbojiang *
47*22ce4affSfengbojiang * - How do variable time windows work e.g. give me per-RTT stats
48*22ce4affSfengbojiang *
49*22ce4affSfengbojiang * - Should the API always require the caller to manage locking? Or should the
50*22ce4affSfengbojiang * API provide optional functionality to lock a blob during operations.
51*22ce4affSfengbojiang *
52*22ce4affSfengbojiang * - Should we continue to store unpacked naturally aligned structs in the
53*22ce4affSfengbojiang * blob or move to packed structs? Relates to inter-host
54*22ce4affSfengbojiang * serialisation/endian issues.
55*22ce4affSfengbojiang */
56*22ce4affSfengbojiang
57*22ce4affSfengbojiang #ifndef _SYS_STATS_H_
58*22ce4affSfengbojiang #define _SYS_STATS_H_
59*22ce4affSfengbojiang
60*22ce4affSfengbojiang #include <sys/limits.h>
61*22ce4affSfengbojiang #ifdef DIAGNOSTIC
62*22ce4affSfengbojiang #include <sys/tree.h>
63*22ce4affSfengbojiang #endif
64*22ce4affSfengbojiang
65*22ce4affSfengbojiang #ifndef _KERNEL
66*22ce4affSfengbojiang /*
67*22ce4affSfengbojiang * XXXLAS: Hacks to enable sharing template creation code between kernel and
68*22ce4affSfengbojiang * userland e.g. tcp_stats.c
69*22ce4affSfengbojiang */
70*22ce4affSfengbojiang #define VNET(n) n
71*22ce4affSfengbojiang #define VNET_DEFINE(t, n) static t n __unused
72*22ce4affSfengbojiang #endif /* ! _KERNEL */
73*22ce4affSfengbojiang
74*22ce4affSfengbojiang #define TPL_MAX_NAME_LEN 64
75*22ce4affSfengbojiang
76*22ce4affSfengbojiang /*
77*22ce4affSfengbojiang * The longest template string spec format i.e. the normative spec format, is:
78*22ce4affSfengbojiang *
79*22ce4affSfengbojiang * "<tplname>":<tplhash>
80*22ce4affSfengbojiang *
81*22ce4affSfengbojiang * Therefore, the max string length of a template string spec is:
82*22ce4affSfengbojiang *
83*22ce4affSfengbojiang * - TPL_MAX_NAME_LEN
84*22ce4affSfengbojiang * - 2 chars for ""
85*22ce4affSfengbojiang * - 1 char for : separating name and hash
86*22ce4affSfengbojiang * - 10 chars for 32bit hash
87*22ce4affSfengbojiang */
88*22ce4affSfengbojiang #define STATS_TPL_MAX_STR_SPEC_LEN (TPL_MAX_NAME_LEN + 13)
89*22ce4affSfengbojiang
90*22ce4affSfengbojiang struct sbuf;
91*22ce4affSfengbojiang struct sysctl_oid;
92*22ce4affSfengbojiang struct sysctl_req;
93*22ce4affSfengbojiang
94*22ce4affSfengbojiang enum sb_str_fmt {
95*22ce4affSfengbojiang SB_STRFMT_FREEFORM = 0,
96*22ce4affSfengbojiang SB_STRFMT_JSON,
97*22ce4affSfengbojiang SB_STRFMT_NUM_FMTS /* +1 to highest numbered format type. */
98*22ce4affSfengbojiang };
99*22ce4affSfengbojiang
100*22ce4affSfengbojiang /* VOI stat types. */
101*22ce4affSfengbojiang enum voi_stype {
102*22ce4affSfengbojiang VS_STYPE_VOISTATE = 0, /* Reserved for internal API use. */
103*22ce4affSfengbojiang VS_STYPE_SUM,
104*22ce4affSfengbojiang VS_STYPE_MAX,
105*22ce4affSfengbojiang VS_STYPE_MIN,
106*22ce4affSfengbojiang VS_STYPE_HIST,
107*22ce4affSfengbojiang VS_STYPE_TDGST,
108*22ce4affSfengbojiang VS_NUM_STYPES /* +1 to highest numbered stat type. */
109*22ce4affSfengbojiang };
110*22ce4affSfengbojiang
111*22ce4affSfengbojiang /*
112*22ce4affSfengbojiang * VOI stat data types used as storage for certain stat types and to marshall
113*22ce4affSfengbojiang * data through various API calls.
114*22ce4affSfengbojiang */
115*22ce4affSfengbojiang enum vsd_dtype {
116*22ce4affSfengbojiang VSD_DTYPE_VOISTATE = 0, /* Reserved for internal API use. */
117*22ce4affSfengbojiang VSD_DTYPE_INT_S32, /* int32_t */
118*22ce4affSfengbojiang VSD_DTYPE_INT_U32, /* uint32_t */
119*22ce4affSfengbojiang VSD_DTYPE_INT_S64, /* int64_t */
120*22ce4affSfengbojiang VSD_DTYPE_INT_U64, /* uint64_t */
121*22ce4affSfengbojiang VSD_DTYPE_INT_SLONG, /* long */
122*22ce4affSfengbojiang VSD_DTYPE_INT_ULONG, /* unsigned long */
123*22ce4affSfengbojiang VSD_DTYPE_Q_S32, /* s32q_t */
124*22ce4affSfengbojiang VSD_DTYPE_Q_U32, /* u32q_t */
125*22ce4affSfengbojiang VSD_DTYPE_Q_S64, /* s64q_t */
126*22ce4affSfengbojiang VSD_DTYPE_Q_U64, /* u64q_t */
127*22ce4affSfengbojiang VSD_DTYPE_CRHIST32, /* continuous range histogram, 32bit buckets */
128*22ce4affSfengbojiang VSD_DTYPE_DRHIST32, /* discrete range histogram, 32bit buckets */
129*22ce4affSfengbojiang VSD_DTYPE_DVHIST32, /* discrete value histogram, 32bit buckets */
130*22ce4affSfengbojiang VSD_DTYPE_CRHIST64, /* continuous range histogram, 64bit buckets */
131*22ce4affSfengbojiang VSD_DTYPE_DRHIST64, /* discrete range histogram, 64bit buckets */
132*22ce4affSfengbojiang VSD_DTYPE_DVHIST64, /* discrete value histogram, 64bit buckets */
133*22ce4affSfengbojiang VSD_DTYPE_TDGSTCLUST32, /* clustering variant t-digest, 32bit buckets */
134*22ce4affSfengbojiang VSD_DTYPE_TDGSTCLUST64, /* clustering variant t-digest, 64bit buckets */
135*22ce4affSfengbojiang VSD_NUM_DTYPES /* +1 to highest numbered data type. */
136*22ce4affSfengbojiang };
137*22ce4affSfengbojiang
138*22ce4affSfengbojiang struct voistatdata_int32 {
139*22ce4affSfengbojiang union {
140*22ce4affSfengbojiang int32_t s32;
141*22ce4affSfengbojiang uint32_t u32;
142*22ce4affSfengbojiang };
143*22ce4affSfengbojiang };
144*22ce4affSfengbojiang
145*22ce4affSfengbojiang struct voistatdata_int64 {
146*22ce4affSfengbojiang union {
147*22ce4affSfengbojiang int64_t s64;
148*22ce4affSfengbojiang uint64_t u64;
149*22ce4affSfengbojiang //counter_u64_t u64pcpu;
150*22ce4affSfengbojiang };
151*22ce4affSfengbojiang };
152*22ce4affSfengbojiang
153*22ce4affSfengbojiang struct voistatdata_intlong {
154*22ce4affSfengbojiang union {
155*22ce4affSfengbojiang long slong;
156*22ce4affSfengbojiang unsigned long ulong;
157*22ce4affSfengbojiang };
158*22ce4affSfengbojiang };
159*22ce4affSfengbojiang
160*22ce4affSfengbojiang struct voistatdata_q32 {
161*22ce4affSfengbojiang union {
162*22ce4affSfengbojiang s32q_t sq32;
163*22ce4affSfengbojiang u32q_t uq32;
164*22ce4affSfengbojiang };
165*22ce4affSfengbojiang };
166*22ce4affSfengbojiang
167*22ce4affSfengbojiang struct voistatdata_q64 {
168*22ce4affSfengbojiang union {
169*22ce4affSfengbojiang s64q_t sq64;
170*22ce4affSfengbojiang u64q_t uq64;
171*22ce4affSfengbojiang };
172*22ce4affSfengbojiang };
173*22ce4affSfengbojiang
174*22ce4affSfengbojiang struct voistatdata_numeric {
175*22ce4affSfengbojiang union {
176*22ce4affSfengbojiang struct {
177*22ce4affSfengbojiang #if BYTE_ORDER == BIG_ENDIAN
178*22ce4affSfengbojiang uint32_t pad;
179*22ce4affSfengbojiang #endif
180*22ce4affSfengbojiang union {
181*22ce4affSfengbojiang int32_t s32;
182*22ce4affSfengbojiang uint32_t u32;
183*22ce4affSfengbojiang };
184*22ce4affSfengbojiang #if BYTE_ORDER == LITTLE_ENDIAN
185*22ce4affSfengbojiang uint32_t pad;
186*22ce4affSfengbojiang #endif
187*22ce4affSfengbojiang } int32;
188*22ce4affSfengbojiang
189*22ce4affSfengbojiang struct {
190*22ce4affSfengbojiang #if BYTE_ORDER == BIG_ENDIAN
191*22ce4affSfengbojiang uint32_t pad;
192*22ce4affSfengbojiang #endif
193*22ce4affSfengbojiang union {
194*22ce4affSfengbojiang s32q_t sq32;
195*22ce4affSfengbojiang u32q_t uq32;
196*22ce4affSfengbojiang };
197*22ce4affSfengbojiang #if BYTE_ORDER == LITTLE_ENDIAN
198*22ce4affSfengbojiang uint32_t pad;
199*22ce4affSfengbojiang #endif
200*22ce4affSfengbojiang } q32;
201*22ce4affSfengbojiang
202*22ce4affSfengbojiang struct {
203*22ce4affSfengbojiang #if BYTE_ORDER == BIG_ENDIAN && LONG_BIT == 32
204*22ce4affSfengbojiang uint32_t pad;
205*22ce4affSfengbojiang #endif
206*22ce4affSfengbojiang union {
207*22ce4affSfengbojiang long slong;
208*22ce4affSfengbojiang unsigned long ulong;
209*22ce4affSfengbojiang };
210*22ce4affSfengbojiang #if BYTE_ORDER == LITTLE_ENDIAN && LONG_BIT == 32
211*22ce4affSfengbojiang uint32_t pad;
212*22ce4affSfengbojiang #endif
213*22ce4affSfengbojiang } intlong;
214*22ce4affSfengbojiang
215*22ce4affSfengbojiang struct voistatdata_int64 int64;
216*22ce4affSfengbojiang struct voistatdata_q64 q64;
217*22ce4affSfengbojiang };
218*22ce4affSfengbojiang };
219*22ce4affSfengbojiang
220*22ce4affSfengbojiang /* Continuous range histogram with 32bit buckets. */
221*22ce4affSfengbojiang struct voistatdata_crhist32 {
222*22ce4affSfengbojiang uint32_t oob;
223*22ce4affSfengbojiang struct {
224*22ce4affSfengbojiang struct voistatdata_numeric lb;
225*22ce4affSfengbojiang uint32_t cnt;
226*22ce4affSfengbojiang } bkts[];
227*22ce4affSfengbojiang };
228*22ce4affSfengbojiang
229*22ce4affSfengbojiang /* Continuous range histogram with 64bit buckets. */
230*22ce4affSfengbojiang struct voistatdata_crhist64 {
231*22ce4affSfengbojiang uint64_t oob;
232*22ce4affSfengbojiang struct {
233*22ce4affSfengbojiang struct voistatdata_numeric lb;
234*22ce4affSfengbojiang uint64_t cnt;
235*22ce4affSfengbojiang } bkts[];
236*22ce4affSfengbojiang };
237*22ce4affSfengbojiang
238*22ce4affSfengbojiang /* Discrete range histogram with 32bit buckets. */
239*22ce4affSfengbojiang struct voistatdata_drhist32 {
240*22ce4affSfengbojiang uint32_t oob;
241*22ce4affSfengbojiang struct {
242*22ce4affSfengbojiang struct voistatdata_numeric lb, ub;
243*22ce4affSfengbojiang uint32_t cnt;
244*22ce4affSfengbojiang } bkts[];
245*22ce4affSfengbojiang };
246*22ce4affSfengbojiang
247*22ce4affSfengbojiang /* Discrete range histogram with 64bit buckets. */
248*22ce4affSfengbojiang struct voistatdata_drhist64 {
249*22ce4affSfengbojiang uint64_t oob;
250*22ce4affSfengbojiang struct {
251*22ce4affSfengbojiang struct voistatdata_numeric lb, ub;
252*22ce4affSfengbojiang uint64_t cnt;
253*22ce4affSfengbojiang } bkts[];
254*22ce4affSfengbojiang };
255*22ce4affSfengbojiang
256*22ce4affSfengbojiang /* Discrete value histogram with 32bit buckets. */
257*22ce4affSfengbojiang struct voistatdata_dvhist32 {
258*22ce4affSfengbojiang uint32_t oob;
259*22ce4affSfengbojiang struct {
260*22ce4affSfengbojiang struct voistatdata_numeric val;
261*22ce4affSfengbojiang uint32_t cnt;
262*22ce4affSfengbojiang } bkts[];
263*22ce4affSfengbojiang };
264*22ce4affSfengbojiang
265*22ce4affSfengbojiang /* Discrete value histogram with 64bit buckets. */
266*22ce4affSfengbojiang struct voistatdata_dvhist64 {
267*22ce4affSfengbojiang uint64_t oob;
268*22ce4affSfengbojiang struct {
269*22ce4affSfengbojiang struct voistatdata_numeric val;
270*22ce4affSfengbojiang uint64_t cnt;
271*22ce4affSfengbojiang } bkts[];
272*22ce4affSfengbojiang };
273*22ce4affSfengbojiang
274*22ce4affSfengbojiang struct voistatdata_hist {
275*22ce4affSfengbojiang union {
276*22ce4affSfengbojiang struct voistatdata_crhist32 crhist32;
277*22ce4affSfengbojiang struct voistatdata_crhist64 crhist64;
278*22ce4affSfengbojiang struct voistatdata_dvhist32 dvhist32;
279*22ce4affSfengbojiang struct voistatdata_dvhist64 dvhist64;
280*22ce4affSfengbojiang struct voistatdata_drhist32 drhist32;
281*22ce4affSfengbojiang struct voistatdata_drhist64 drhist64;
282*22ce4affSfengbojiang };
283*22ce4affSfengbojiang };
284*22ce4affSfengbojiang
285*22ce4affSfengbojiang struct voistatdata_tdgstctd32 {
286*22ce4affSfengbojiang ARB16_ENTRY() ctdlnk;
287*22ce4affSfengbojiang #ifdef DIAGNOSTIC
288*22ce4affSfengbojiang RB_ENTRY(voistatdata_tdgstctd32) rblnk;
289*22ce4affSfengbojiang #endif
290*22ce4affSfengbojiang s32q_t mu;
291*22ce4affSfengbojiang int32_t cnt;
292*22ce4affSfengbojiang };
293*22ce4affSfengbojiang
294*22ce4affSfengbojiang struct voistatdata_tdgstctd64 {
295*22ce4affSfengbojiang ARB16_ENTRY() ctdlnk;
296*22ce4affSfengbojiang #ifdef DIAGNOSTIC
297*22ce4affSfengbojiang RB_ENTRY(voistatdata_tdgstctd64) rblnk;
298*22ce4affSfengbojiang #endif
299*22ce4affSfengbojiang s64q_t mu;
300*22ce4affSfengbojiang int64_t cnt;
301*22ce4affSfengbojiang };
302*22ce4affSfengbojiang
303*22ce4affSfengbojiang struct voistatdata_tdgstctd {
304*22ce4affSfengbojiang union {
305*22ce4affSfengbojiang struct voistatdata_tdgstctd32 tdgstctd32;
306*22ce4affSfengbojiang struct voistatdata_tdgstctd64 tdgstctd64;
307*22ce4affSfengbojiang };
308*22ce4affSfengbojiang };
309*22ce4affSfengbojiang
310*22ce4affSfengbojiang /* Clustering variant, fixed-point t-digest with 32bit mu/counts. */
311*22ce4affSfengbojiang struct voistatdata_tdgstclust32 {
312*22ce4affSfengbojiang uint32_t smplcnt; /* Count of samples. */
313*22ce4affSfengbojiang uint32_t compcnt; /* Count of digest compressions. */
314*22ce4affSfengbojiang #ifdef DIAGNOSTIC
315*22ce4affSfengbojiang RB_HEAD(rbctdth32, voistatdata_tdgstctd32) rbctdtree;
316*22ce4affSfengbojiang #endif
317*22ce4affSfengbojiang /* Array-based red-black tree of centroids. */
318*22ce4affSfengbojiang ARB16_HEAD(ctdth32, voistatdata_tdgstctd32) ctdtree;
319*22ce4affSfengbojiang };
320*22ce4affSfengbojiang
321*22ce4affSfengbojiang /* Clustering variant, fixed-point t-digest with 64bit mu/counts. */
322*22ce4affSfengbojiang struct voistatdata_tdgstclust64 {
323*22ce4affSfengbojiang uint64_t smplcnt; /* Count of samples. */
324*22ce4affSfengbojiang uint32_t compcnt; /* Count of digest compressions. */
325*22ce4affSfengbojiang #ifdef DIAGNOSTIC
326*22ce4affSfengbojiang RB_HEAD(rbctdth64, voistatdata_tdgstctd64) rbctdtree;
327*22ce4affSfengbojiang #endif
328*22ce4affSfengbojiang /* Array-based red-black tree of centroids. */
329*22ce4affSfengbojiang ARB16_HEAD(ctdth64, voistatdata_tdgstctd64) ctdtree;
330*22ce4affSfengbojiang };
331*22ce4affSfengbojiang
332*22ce4affSfengbojiang struct voistatdata_tdgst {
333*22ce4affSfengbojiang union {
334*22ce4affSfengbojiang struct voistatdata_tdgstclust32 tdgstclust32;
335*22ce4affSfengbojiang struct voistatdata_tdgstclust64 tdgstclust64;
336*22ce4affSfengbojiang };
337*22ce4affSfengbojiang };
338*22ce4affSfengbojiang
339*22ce4affSfengbojiang struct voistatdata {
340*22ce4affSfengbojiang union {
341*22ce4affSfengbojiang struct voistatdata_int32 int32;
342*22ce4affSfengbojiang struct voistatdata_int64 int64;
343*22ce4affSfengbojiang struct voistatdata_intlong intlong;
344*22ce4affSfengbojiang struct voistatdata_q32 q32;
345*22ce4affSfengbojiang struct voistatdata_q64 q64;
346*22ce4affSfengbojiang struct voistatdata_crhist32 crhist32;
347*22ce4affSfengbojiang struct voistatdata_crhist64 crhist64;
348*22ce4affSfengbojiang struct voistatdata_dvhist32 dvhist32;
349*22ce4affSfengbojiang struct voistatdata_dvhist64 dvhist64;
350*22ce4affSfengbojiang struct voistatdata_drhist32 drhist32;
351*22ce4affSfengbojiang struct voistatdata_drhist64 drhist64;
352*22ce4affSfengbojiang struct voistatdata_tdgstclust32 tdgstclust32;
353*22ce4affSfengbojiang struct voistatdata_tdgstclust64 tdgstclust64;
354*22ce4affSfengbojiang };
355*22ce4affSfengbojiang };
356*22ce4affSfengbojiang
357*22ce4affSfengbojiang #define VSD_HIST_LBOUND_INF 0x01
358*22ce4affSfengbojiang #define VSD_HIST_UBOUND_INF 0x02
359*22ce4affSfengbojiang struct vss_hist_hlpr_info {
360*22ce4affSfengbojiang enum hist_bkt_alloc {
361*22ce4affSfengbojiang BKT_LIN, /* Linear steps. */
362*22ce4affSfengbojiang BKT_EXP, /* Exponential steps. */
363*22ce4affSfengbojiang BKT_LINEXP, /* Exponential steps, linear sub-steps. */
364*22ce4affSfengbojiang BKT_USR /* User specified buckets. */
365*22ce4affSfengbojiang } scheme;
366*22ce4affSfengbojiang enum vsd_dtype voi_dtype;
367*22ce4affSfengbojiang enum vsd_dtype hist_dtype;
368*22ce4affSfengbojiang uint32_t flags;
369*22ce4affSfengbojiang struct voistatdata_numeric lb;
370*22ce4affSfengbojiang struct voistatdata_numeric ub;
371*22ce4affSfengbojiang union {
372*22ce4affSfengbojiang struct {
373*22ce4affSfengbojiang const uint64_t stepinc;
374*22ce4affSfengbojiang } lin;
375*22ce4affSfengbojiang struct {
376*22ce4affSfengbojiang const uint64_t stepbase;
377*22ce4affSfengbojiang const uint64_t stepexp;
378*22ce4affSfengbojiang } exp;
379*22ce4affSfengbojiang struct {
380*22ce4affSfengbojiang const uint64_t stepbase;
381*22ce4affSfengbojiang const uint64_t linstepdiv;
382*22ce4affSfengbojiang } linexp;
383*22ce4affSfengbojiang struct {
384*22ce4affSfengbojiang const uint16_t nbkts;
385*22ce4affSfengbojiang const struct {
386*22ce4affSfengbojiang struct voistatdata_numeric lb, ub;
387*22ce4affSfengbojiang } *bkts;
388*22ce4affSfengbojiang } usr;
389*22ce4affSfengbojiang };
390*22ce4affSfengbojiang };
391*22ce4affSfengbojiang
392*22ce4affSfengbojiang struct vss_tdgst_hlpr_info {
393*22ce4affSfengbojiang enum vsd_dtype voi_dtype;
394*22ce4affSfengbojiang enum vsd_dtype tdgst_dtype;
395*22ce4affSfengbojiang uint32_t nctds;
396*22ce4affSfengbojiang uint32_t prec;
397*22ce4affSfengbojiang } __aligned(sizeof(void *));
398*22ce4affSfengbojiang
399*22ce4affSfengbojiang struct vss_numeric_hlpr_info {
400*22ce4affSfengbojiang uint32_t prec;
401*22ce4affSfengbojiang };
402*22ce4affSfengbojiang
403*22ce4affSfengbojiang struct vss_hlpr_info {
404*22ce4affSfengbojiang union {
405*22ce4affSfengbojiang struct vss_tdgst_hlpr_info tdgst;
406*22ce4affSfengbojiang struct vss_hist_hlpr_info hist;
407*22ce4affSfengbojiang struct vss_numeric_hlpr_info numeric;
408*22ce4affSfengbojiang };
409*22ce4affSfengbojiang };
410*22ce4affSfengbojiang
411*22ce4affSfengbojiang struct voistatspec;
412*22ce4affSfengbojiang typedef int (*vss_hlpr_fn)(enum vsd_dtype, struct voistatspec *,
413*22ce4affSfengbojiang struct vss_hlpr_info *);
414*22ce4affSfengbojiang
415*22ce4affSfengbojiang struct voistatspec {
416*22ce4affSfengbojiang vss_hlpr_fn hlpr; /* iv helper function. */
417*22ce4affSfengbojiang struct vss_hlpr_info *hlprinfo; /* Helper function context. */
418*22ce4affSfengbojiang struct voistatdata *iv; /* Initialisation value. */
419*22ce4affSfengbojiang size_t vsdsz; /* Size of iv. */
420*22ce4affSfengbojiang uint32_t flags; /* Stat flags. */
421*22ce4affSfengbojiang enum vsd_dtype vs_dtype : 8; /* Stat's dtype. */
422*22ce4affSfengbojiang enum voi_stype stype : 8; /* Stat type. */
423*22ce4affSfengbojiang };
424*22ce4affSfengbojiang
425*22ce4affSfengbojiang extern const char *vs_stype2name[VS_NUM_STYPES];
426*22ce4affSfengbojiang extern const char *vs_stype2desc[VS_NUM_STYPES];
427*22ce4affSfengbojiang extern const char *vsd_dtype2name[VSD_NUM_DTYPES];
428*22ce4affSfengbojiang extern const size_t vsd_dtype2size[VSD_NUM_DTYPES];
429*22ce4affSfengbojiang #define LIM_MIN 0
430*22ce4affSfengbojiang #define LIM_MAX 1
431*22ce4affSfengbojiang extern const struct voistatdata_numeric numeric_limits[2][VSD_DTYPE_Q_U64 + 1];
432*22ce4affSfengbojiang
433*22ce4affSfengbojiang #define TYPEOF_MEMBER(type, member) __typeof(((type *)0)->member)
434*22ce4affSfengbojiang #define TYPEOF_MEMBER_PTR(type, member) __typeof(*(((type *)0)->member))
435*22ce4affSfengbojiang #define SIZEOF_MEMBER(type, member) sizeof(TYPEOF_MEMBER(type, member))
436*22ce4affSfengbojiang
437*22ce4affSfengbojiang /* Cast a pointer to a voistatdata struct of requested type. */
438*22ce4affSfengbojiang #define _VSD(cnst, type, ptr) ((cnst struct voistatdata_##type *)(ptr))
439*22ce4affSfengbojiang #define VSD(type, ptr) _VSD(, type, ptr)
440*22ce4affSfengbojiang #define CONSTVSD(type, ptr) _VSD(const, type, ptr)
441*22ce4affSfengbojiang
442*22ce4affSfengbojiang #define NVSS(vss_slots) (sizeof((vss_slots)) / sizeof(struct voistatspec))
443*22ce4affSfengbojiang #define STATS_VSS(st, vsf, dt, hlp, hlpi) \
444*22ce4affSfengbojiang ((struct voistatspec){ \
445*22ce4affSfengbojiang .stype = (st), \
446*22ce4affSfengbojiang .flags = (vsf), \
447*22ce4affSfengbojiang .vs_dtype = (dt), \
448*22ce4affSfengbojiang .hlpr = (hlp), \
449*22ce4affSfengbojiang .hlprinfo = (hlpi), \
450*22ce4affSfengbojiang })
451*22ce4affSfengbojiang
452*22ce4affSfengbojiang #define STATS_VSS_SUM() STATS_VSS(VS_STYPE_SUM, 0, 0, \
453*22ce4affSfengbojiang (vss_hlpr_fn)&stats_vss_numeric_hlpr, NULL)
454*22ce4affSfengbojiang
455*22ce4affSfengbojiang #define STATS_VSS_MAX() STATS_VSS(VS_STYPE_MAX, 0, 0, \
456*22ce4affSfengbojiang (vss_hlpr_fn)&stats_vss_numeric_hlpr, NULL)
457*22ce4affSfengbojiang
458*22ce4affSfengbojiang #define STATS_VSS_MIN() STATS_VSS(VS_STYPE_MIN, 0, 0, \
459*22ce4affSfengbojiang (vss_hlpr_fn)&stats_vss_numeric_hlpr, NULL)
460*22ce4affSfengbojiang
461*22ce4affSfengbojiang #define STATS_VSS_HIST(htype, hist_hlpr_info) STATS_VSS(VS_STYPE_HIST, 0, \
462*22ce4affSfengbojiang htype, (vss_hlpr_fn)&stats_vss_hist_hlpr, \
463*22ce4affSfengbojiang (struct vss_hlpr_info *)(hist_hlpr_info))
464*22ce4affSfengbojiang
465*22ce4affSfengbojiang #define STATS_VSS_TDIGEST(tdtype, tdgst_hlpr_info) STATS_VSS(VS_STYPE_TDGST, \
466*22ce4affSfengbojiang 0, tdtype, (vss_hlpr_fn)&stats_vss_tdgst_hlpr, \
467*22ce4affSfengbojiang (struct vss_hlpr_info *)(tdgst_hlpr_info))
468*22ce4affSfengbojiang
469*22ce4affSfengbojiang #define TDGST_NCTRS2VSDSZ(tdtype, nctds) (sizeof(struct voistatdata_##tdtype) + \
470*22ce4affSfengbojiang ((nctds) * sizeof(TYPEOF_MEMBER_PTR(struct voistatdata_##tdtype, \
471*22ce4affSfengbojiang ctdtree.arb_nodes))))
472*22ce4affSfengbojiang
473*22ce4affSfengbojiang #define TDGST_HLPR_INFO(dt, nc, nf) \
474*22ce4affSfengbojiang (&(struct vss_tdgst_hlpr_info){ \
475*22ce4affSfengbojiang .tdgst_dtype = (dt), \
476*22ce4affSfengbojiang .nctds = (nc), \
477*22ce4affSfengbojiang .prec = (nf) \
478*22ce4affSfengbojiang })
479*22ce4affSfengbojiang
480*22ce4affSfengbojiang #define STATS_VSS_TDGSTCLUST32(nctds, prec) \
481*22ce4affSfengbojiang STATS_VSS_TDIGEST(VSD_DTYPE_TDGSTCLUST32, \
482*22ce4affSfengbojiang TDGST_HLPR_INFO(VSD_DTYPE_TDGSTCLUST32, nctds, prec))
483*22ce4affSfengbojiang
484*22ce4affSfengbojiang #define STATS_VSS_TDGSTCLUST64(nctds, prec) \
485*22ce4affSfengbojiang STATS_VSS_TDIGEST(VSD_DTYPE_TDGSTCLUST64, \
486*22ce4affSfengbojiang TDGST_HLPR_INFO(VSD_DTYPE_TDGSTCLUST64, nctds, prec))
487*22ce4affSfengbojiang
488*22ce4affSfengbojiang #define HIST_VSDSZ2NBKTS(htype, dsz) \
489*22ce4affSfengbojiang ((dsz - sizeof(struct voistatdata_##htype)) / \
490*22ce4affSfengbojiang sizeof(TYPEOF_MEMBER(struct voistatdata_##htype, bkts[0])))
491*22ce4affSfengbojiang
492*22ce4affSfengbojiang #define HIST_NBKTS2VSDSZ(htype, nbkts) (sizeof(struct voistatdata_##htype) + \
493*22ce4affSfengbojiang ((nbkts) * sizeof(TYPEOF_MEMBER_PTR(struct voistatdata_##htype, bkts))))
494*22ce4affSfengbojiang
495*22ce4affSfengbojiang #define HIST_HLPR_INFO_LIN_FIELDS(si) .lin.stepinc = (si)
496*22ce4affSfengbojiang
497*22ce4affSfengbojiang #define HIST_HLPR_INFO_EXP_FIELDS(sb, se) \
498*22ce4affSfengbojiang .exp.stepbase = (sb), .exp.stepexp = (se)
499*22ce4affSfengbojiang
500*22ce4affSfengbojiang #define HIST_HLPR_INFO_LINEXP_FIELDS(nss, sb) \
501*22ce4affSfengbojiang .linexp.linstepdiv = (nss), .linexp.stepbase = (sb)
502*22ce4affSfengbojiang
503*22ce4affSfengbojiang #define HIST_HLPR_INFO_USR_FIELDS(bbs) \
504*22ce4affSfengbojiang .usr.bkts = (TYPEOF_MEMBER(struct vss_hist_hlpr_info, usr.bkts))(bbs), \
505*22ce4affSfengbojiang .usr.nbkts = (sizeof(bbs) / sizeof(struct voistatdata_numeric[2]))
506*22ce4affSfengbojiang
507*22ce4affSfengbojiang #define HIST_HLPR_INFO(dt, sch, f, lbd, ubd, bkthlpr_fields) \
508*22ce4affSfengbojiang (&(struct vss_hist_hlpr_info){ \
509*22ce4affSfengbojiang .scheme = (sch), \
510*22ce4affSfengbojiang .hist_dtype = (dt), \
511*22ce4affSfengbojiang .flags = (f), \
512*22ce4affSfengbojiang .lb = stats_ctor_vsd_numeric(lbd), \
513*22ce4affSfengbojiang .ub = stats_ctor_vsd_numeric(ubd), \
514*22ce4affSfengbojiang bkthlpr_fields \
515*22ce4affSfengbojiang })
516*22ce4affSfengbojiang
517*22ce4affSfengbojiang #define STATS_VSS_CRHIST32_LIN(lb, ub, stepinc, vsdflags) \
518*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST32, HIST_HLPR_INFO(VSD_DTYPE_CRHIST32, \
519*22ce4affSfengbojiang BKT_LIN, vsdflags, lb, ub, HIST_HLPR_INFO_LIN_FIELDS(stepinc)))
520*22ce4affSfengbojiang #define STATS_VSS_CRHIST64_LIN(lb, ub, stepinc, vsdflags) \
521*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST64, HIST_HLPR_INFO(VSD_DTYPE_CRHIST64, \
522*22ce4affSfengbojiang BKT_LIN, vsdflags, lb, ub, HIST_HLPR_INFO_LIN_FIELDS(stepinc)))
523*22ce4affSfengbojiang
524*22ce4affSfengbojiang #define STATS_VSS_CRHIST32_EXP(lb, ub, stepbase, stepexp, vsdflags) \
525*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST32, HIST_HLPR_INFO(VSD_DTYPE_CRHIST32, \
526*22ce4affSfengbojiang BKT_EXP, vsdflags, lb, ub, HIST_HLPR_INFO_EXP_FIELDS(stepbase, stepexp)))
527*22ce4affSfengbojiang #define STATS_VSS_CRHIST64_EXP(lb, ub, stepbase, stepexp, vsdflags) \
528*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST64, HIST_HLPR_INFO(VSD_DTYPE_CRHIST64, \
529*22ce4affSfengbojiang BKT_EXP, vsdflags, lb, ub, HIST_HLPR_INFO_EXP_FIELDS(stepbase, stepexp)))
530*22ce4affSfengbojiang
531*22ce4affSfengbojiang #define STATS_VSS_CRHIST32_LINEXP(lb, ub, nlinsteps, stepbase, vsdflags) \
532*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST32, HIST_HLPR_INFO(VSD_DTYPE_CRHIST32, \
533*22ce4affSfengbojiang BKT_LINEXP, vsdflags, lb, ub, HIST_HLPR_INFO_LINEXP_FIELDS(nlinsteps, \
534*22ce4affSfengbojiang stepbase)))
535*22ce4affSfengbojiang #define STATS_VSS_CRHIST64_LINEXP(lb, ub, nlinsteps, stepbase, vsdflags) \
536*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST64, HIST_HLPR_INFO(VSD_DTYPE_CRHIST64, \
537*22ce4affSfengbojiang BKT_LINEXP, vsdflags, lb, ub, HIST_HLPR_INFO_LINEXP_FIELDS(nlinsteps, \
538*22ce4affSfengbojiang stepbase)))
539*22ce4affSfengbojiang
540*22ce4affSfengbojiang #define STATS_VSS_CRHIST32_USR(bkts, vsdflags) \
541*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST32, HIST_HLPR_INFO(VSD_DTYPE_CRHIST32, \
542*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(bkts)))
543*22ce4affSfengbojiang #define STATS_VSS_CRHIST64_USR(bkts, vsdflags) \
544*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_CRHIST64, HIST_HLPR_INFO(VSD_DTYPE_CRHIST64, \
545*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(bkts)))
546*22ce4affSfengbojiang
547*22ce4affSfengbojiang #define STATS_VSS_DRHIST32_USR(bkts, vsdflags) \
548*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_DRHIST32, HIST_HLPR_INFO(VSD_DTYPE_DRHIST32, \
549*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(bkts)))
550*22ce4affSfengbojiang #define STATS_VSS_DRHIST64_USR(bkts, vsdflags) \
551*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_DRHIST64, HIST_HLPR_INFO(VSD_DTYPE_DRHIST64, \
552*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(bkts)))
553*22ce4affSfengbojiang
554*22ce4affSfengbojiang #define STATS_VSS_DVHIST32_USR(vals, vsdflags) \
555*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_DVHIST32, HIST_HLPR_INFO(VSD_DTYPE_DVHIST32, \
556*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(vals)))
557*22ce4affSfengbojiang #define STATS_VSS_DVHIST64_USR(vals, vsdflags) \
558*22ce4affSfengbojiang STATS_VSS_HIST(VSD_DTYPE_DVHIST64, HIST_HLPR_INFO(VSD_DTYPE_DVHIST64, \
559*22ce4affSfengbojiang BKT_USR, vsdflags, 0, 0, HIST_HLPR_INFO_USR_FIELDS(vals)))
560*22ce4affSfengbojiang #define DRBKT(lb, ub) { stats_ctor_vsd_numeric(lb), stats_ctor_vsd_numeric(ub) }
561*22ce4affSfengbojiang #define DVBKT(val) DRBKT(val, val)
562*22ce4affSfengbojiang #define CRBKT(lb) DRBKT(lb, lb)
563*22ce4affSfengbojiang #define HBKTS(...) ((struct voistatdata_numeric [][2]){__VA_ARGS__})
564*22ce4affSfengbojiang
565*22ce4affSfengbojiang #define VSD_HIST_FIELD(hist, cnst, hist_dtype, op, field) \
566*22ce4affSfengbojiang (VSD_DTYPE_CRHIST32 == (hist_dtype) ? \
567*22ce4affSfengbojiang op(_VSD(cnst, crhist32, hist)->field) : \
568*22ce4affSfengbojiang (VSD_DTYPE_DRHIST32 == (hist_dtype) ? \
569*22ce4affSfengbojiang op(_VSD(cnst, drhist32, hist)->field) : \
570*22ce4affSfengbojiang (VSD_DTYPE_DVHIST32 == (hist_dtype) ? \
571*22ce4affSfengbojiang op(_VSD(cnst, dvhist32, hist)->field) : \
572*22ce4affSfengbojiang (VSD_DTYPE_CRHIST64 == (hist_dtype) ? \
573*22ce4affSfengbojiang op(_VSD(cnst, crhist64, hist)->field) : \
574*22ce4affSfengbojiang (VSD_DTYPE_DRHIST64 == (hist_dtype) ? \
575*22ce4affSfengbojiang op(_VSD(cnst, drhist64, hist)->field) : \
576*22ce4affSfengbojiang (op(_VSD(cnst, dvhist64, hist)->field)))))))
577*22ce4affSfengbojiang #define VSD_HIST_FIELDVAL(hist, hist_dtype, field) \
578*22ce4affSfengbojiang VSD_HIST_FIELD(hist, , hist_dtype, ,field)
579*22ce4affSfengbojiang #define VSD_CONSTHIST_FIELDVAL(hist, hist_dtype, field) \
580*22ce4affSfengbojiang VSD_HIST_FIELD(hist, const, hist_dtype, ,field)
581*22ce4affSfengbojiang #define VSD_HIST_FIELDPTR(hist, hist_dtype, field) \
582*22ce4affSfengbojiang VSD_HIST_FIELD(hist, , hist_dtype, (void *)&,field)
583*22ce4affSfengbojiang #define VSD_CONSTHIST_FIELDPTR(hist, hist_dtype, field) \
584*22ce4affSfengbojiang VSD_HIST_FIELD(hist, const, hist_dtype, (void *)&,field)
585*22ce4affSfengbojiang
586*22ce4affSfengbojiang #define VSD_CRHIST_FIELD(hist, cnst, hist_dtype, op, field) \
587*22ce4affSfengbojiang (VSD_DTYPE_CRHIST32 == (hist_dtype) ? \
588*22ce4affSfengbojiang op(_VSD(cnst, crhist32, hist)->field) : \
589*22ce4affSfengbojiang op(_VSD(cnst, crhist64, hist)->field))
590*22ce4affSfengbojiang #define VSD_CRHIST_FIELDVAL(hist, hist_dtype, field) \
591*22ce4affSfengbojiang VSD_CRHIST_FIELD(hist, , hist_dtype, , field)
592*22ce4affSfengbojiang #define VSD_CONSTCRHIST_FIELDVAL(hist, hist_dtype, field) \
593*22ce4affSfengbojiang VSD_CRHIST_FIELD(hist, const, hist_dtype, , field)
594*22ce4affSfengbojiang #define VSD_CRHIST_FIELDPTR(hist, hist_dtype, field) \
595*22ce4affSfengbojiang VSD_CRHIST_FIELD(hist, , hist_dtype, &, field)
596*22ce4affSfengbojiang #define VSD_CONSTCRHIST_FIELDPTR(hist, hist_dtype, field) \
597*22ce4affSfengbojiang VSD_CRHIST_FIELD(hist, const, hist_dtype, &, field)
598*22ce4affSfengbojiang
599*22ce4affSfengbojiang #define VSD_DRHIST_FIELD(hist, cnst, hist_dtype, op, field) \
600*22ce4affSfengbojiang (VSD_DTYPE_DRHIST32 == (hist_dtype) ? \
601*22ce4affSfengbojiang op(_VSD(cnst, drhist32, hist)->field) : \
602*22ce4affSfengbojiang op(_VSD(cnst, drhist64, hist)->field))
603*22ce4affSfengbojiang #define VSD_DRHIST_FIELDVAL(hist, hist_dtype, field) \
604*22ce4affSfengbojiang VSD_DRHIST_FIELD(hist, , hist_dtype, , field)
605*22ce4affSfengbojiang #define VSD_CONSTDRHIST_FIELDVAL(hist, hist_dtype, field) \
606*22ce4affSfengbojiang VSD_DRHIST_FIELD(hist, const, hist_dtype, , field)
607*22ce4affSfengbojiang #define VSD_DRHIST_FIELDPTR(hist, hist_dtype, field) \
608*22ce4affSfengbojiang VSD_DRHIST_FIELD(hist, , hist_dtype, &, field)
609*22ce4affSfengbojiang #define VSD_CONSTDRHIST_FIELDPTR(hist, hist_dtype, field) \
610*22ce4affSfengbojiang VSD_DRHIST_FIELD(hist, const, hist_dtype, &, field)
611*22ce4affSfengbojiang
612*22ce4affSfengbojiang #define VSD_DVHIST_FIELD(hist, cnst, hist_dtype, op, field) \
613*22ce4affSfengbojiang (VSD_DTYPE_DVHIST32 == (hist_dtype) ? \
614*22ce4affSfengbojiang op(_VSD(cnst, dvhist32, hist)->field) : \
615*22ce4affSfengbojiang op(_VSD(cnst, dvhist64, hist)->field))
616*22ce4affSfengbojiang #define VSD_DVHIST_FIELDVAL(hist, hist_dtype, field) \
617*22ce4affSfengbojiang VSD_DVHIST_FIELD(hist, , hist_dtype, , field)
618*22ce4affSfengbojiang #define VSD_CONSTDVHIST_FIELDVAL(hist, hist_dtype, field) \
619*22ce4affSfengbojiang VSD_DVHIST_FIELD(hist, const, hist_dtype, , field)
620*22ce4affSfengbojiang #define VSD_DVHIST_FIELDPTR(hist, hist_dtype, field) \
621*22ce4affSfengbojiang VSD_DVHIST_FIELD(hist, , hist_dtype, &, field)
622*22ce4affSfengbojiang #define VSD_CONSTDVHIST_FIELDPTR(hist, hist_dtype, field) \
623*22ce4affSfengbojiang VSD_DVHIST_FIELD(hist, const, hist_dtype, &, field)
624*22ce4affSfengbojiang
625*22ce4affSfengbojiang #define STATS_ABI_V1 1
626*22ce4affSfengbojiang struct statsblobv1;
627*22ce4affSfengbojiang
628*22ce4affSfengbojiang enum sb_endianness {
629*22ce4affSfengbojiang SB_UE = 0, /* Unknown endian. */
630*22ce4affSfengbojiang SB_LE, /* Little endian. */
631*22ce4affSfengbojiang SB_BE /* Big endian. */
632*22ce4affSfengbojiang };
633*22ce4affSfengbojiang
634*22ce4affSfengbojiang struct statsblob {
635*22ce4affSfengbojiang uint8_t abi;
636*22ce4affSfengbojiang uint8_t endian;
637*22ce4affSfengbojiang uint16_t flags;
638*22ce4affSfengbojiang uint16_t maxsz;
639*22ce4affSfengbojiang uint16_t cursz;
640*22ce4affSfengbojiang uint8_t opaque[];
641*22ce4affSfengbojiang } __aligned(sizeof(void *));
642*22ce4affSfengbojiang
643*22ce4affSfengbojiang struct metablob {
644*22ce4affSfengbojiang char *tplname;
645*22ce4affSfengbojiang uint32_t tplhash;
646*22ce4affSfengbojiang struct voi_meta {
647*22ce4affSfengbojiang char *name;
648*22ce4affSfengbojiang char *desc;
649*22ce4affSfengbojiang } *voi_meta;
650*22ce4affSfengbojiang };
651*22ce4affSfengbojiang
652*22ce4affSfengbojiang struct statsblob_tpl {
653*22ce4affSfengbojiang struct metablob *mb; /* Template metadata */
654*22ce4affSfengbojiang struct statsblob *sb; /* Template schema */
655*22ce4affSfengbojiang };
656*22ce4affSfengbojiang
657*22ce4affSfengbojiang struct stats_tpl_sample_rate {
658*22ce4affSfengbojiang /* XXXLAS: Storing slot_id assumes templates are never removed. */
659*22ce4affSfengbojiang int32_t tpl_slot_id;
660*22ce4affSfengbojiang uint32_t tpl_sample_pct;
661*22ce4affSfengbojiang };
662*22ce4affSfengbojiang
663*22ce4affSfengbojiang /* Template sample rates list management callback actions. */
664*22ce4affSfengbojiang enum stats_tpl_sr_cb_action {
665*22ce4affSfengbojiang TPL_SR_UNLOCKED_GET,
666*22ce4affSfengbojiang TPL_SR_RLOCKED_GET,
667*22ce4affSfengbojiang TPL_SR_RUNLOCK,
668*22ce4affSfengbojiang TPL_SR_PUT
669*22ce4affSfengbojiang };
670*22ce4affSfengbojiang
671*22ce4affSfengbojiang /*
672*22ce4affSfengbojiang * Callback function pointer passed as arg1 to stats_tpl_sample_rates(). ctx is
673*22ce4affSfengbojiang * a heap-allocated, zero-initialised blob of contextual memory valid during a
674*22ce4affSfengbojiang * single stats_tpl_sample_rates() call and sized per the value passed as arg2.
675*22ce4affSfengbojiang * Returns 0 on success, an errno on error.
676*22ce4affSfengbojiang * - When called with "action == TPL_SR_*_GET", return the subsystem's rates
677*22ce4affSfengbojiang * list ptr and count, locked or unlocked as requested.
678*22ce4affSfengbojiang * - When called with "action == TPL_SR_RUNLOCK", unlock the subsystem's rates
679*22ce4affSfengbojiang * list ptr and count. Pair with a prior "action == TPL_SR_RLOCKED_GET" call.
680*22ce4affSfengbojiang * - When called with "action == TPL_SR_PUT, update the subsystem's rates list
681*22ce4affSfengbojiang * ptr and count to the sysctl processed values and return the inactive list
682*22ce4affSfengbojiang * details in rates/nrates for garbage collection by stats_tpl_sample_rates().
683*22ce4affSfengbojiang */
684*22ce4affSfengbojiang typedef int (*stats_tpl_sr_cb_t)(enum stats_tpl_sr_cb_action action,
685*22ce4affSfengbojiang struct stats_tpl_sample_rate **rates, int *nrates, void *ctx);
686*22ce4affSfengbojiang
687*22ce4affSfengbojiang /* Flags related to iterating over a stats blob. */
688*22ce4affSfengbojiang #define SB_IT_FIRST_CB 0x0001
689*22ce4affSfengbojiang #define SB_IT_LAST_CB 0x0002
690*22ce4affSfengbojiang #define SB_IT_FIRST_VOI 0x0004
691*22ce4affSfengbojiang #define SB_IT_LAST_VOI 0x0008
692*22ce4affSfengbojiang #define SB_IT_FIRST_VOISTAT 0x0010
693*22ce4affSfengbojiang #define SB_IT_LAST_VOISTAT 0x0020
694*22ce4affSfengbojiang #define SB_IT_NULLVOI 0x0040
695*22ce4affSfengbojiang #define SB_IT_NULLVOISTAT 0x0080
696*22ce4affSfengbojiang
697*22ce4affSfengbojiang struct sb_visit {
698*22ce4affSfengbojiang struct voistatdata *vs_data;
699*22ce4affSfengbojiang uint32_t tplhash;
700*22ce4affSfengbojiang uint32_t flags;
701*22ce4affSfengbojiang int16_t voi_id;
702*22ce4affSfengbojiang int16_t vs_dsz;
703*22ce4affSfengbojiang uint16_t vs_errs;
704*22ce4affSfengbojiang enum vsd_dtype voi_dtype : 8;
705*22ce4affSfengbojiang enum vsd_dtype vs_dtype : 8;
706*22ce4affSfengbojiang int8_t vs_stype;
707*22ce4affSfengbojiang };
708*22ce4affSfengbojiang
709*22ce4affSfengbojiang /* Stats blob iterator callback called for each struct voi. */
710*22ce4affSfengbojiang typedef int (*stats_blob_visitcb_t)(struct sb_visit *sbv, void *usrctx);
711*22ce4affSfengbojiang
712*22ce4affSfengbojiang /* ABI specific functions. */
713*22ce4affSfengbojiang int stats_v1_tpl_alloc(const char *name, uint32_t flags);
714*22ce4affSfengbojiang int stats_v1_tpl_add_voistats(uint32_t tpl_id, int32_t voi_id,
715*22ce4affSfengbojiang const char *voi_name, enum vsd_dtype voi_dtype, uint32_t nvss,
716*22ce4affSfengbojiang struct voistatspec *vss, uint32_t flags);
717*22ce4affSfengbojiang int stats_v1_blob_init(struct statsblobv1 *sb, uint32_t tpl_id, uint32_t flags);
718*22ce4affSfengbojiang struct statsblobv1 * stats_v1_blob_alloc(uint32_t tpl_id, uint32_t flags);
719*22ce4affSfengbojiang int stats_v1_blob_clone(struct statsblobv1 **dst, size_t dstmaxsz,
720*22ce4affSfengbojiang struct statsblobv1 *src, uint32_t flags);
721*22ce4affSfengbojiang void stats_v1_blob_destroy(struct statsblobv1 *sb);
722*22ce4affSfengbojiang #define SB_CLONE_RSTSRC 0x0001 /* Reset src blob if clone successful. */
723*22ce4affSfengbojiang #define SB_CLONE_ALLOCDST 0x0002 /* Allocate src->cursz memory for dst. */
724*22ce4affSfengbojiang #define SB_CLONE_USRDSTNOFAULT 0x0004 /* Clone to wired userspace dst. */
725*22ce4affSfengbojiang #define SB_CLONE_USRDST 0x0008 /* Clone to unwired userspace dst. */
726*22ce4affSfengbojiang int stats_v1_blob_snapshot(struct statsblobv1 **dst, size_t dstmaxsz,
727*22ce4affSfengbojiang struct statsblobv1 *src, uint32_t flags);
728*22ce4affSfengbojiang #define SB_TOSTR_OBJDUMP 0x00000001
729*22ce4affSfengbojiang #define SB_TOSTR_META 0x00000002 /* Lookup metablob and render metadata */
730*22ce4affSfengbojiang int stats_v1_blob_tostr(struct statsblobv1 *sb, struct sbuf *buf,
731*22ce4affSfengbojiang enum sb_str_fmt fmt, uint32_t flags);
732*22ce4affSfengbojiang int stats_v1_blob_visit(struct statsblobv1 *sb, stats_blob_visitcb_t func,
733*22ce4affSfengbojiang void *usrctx);
734*22ce4affSfengbojiang /* VOI related function flags. */
735*22ce4affSfengbojiang #define SB_VOI_RELUPDATE 0x00000001 /* voival is relative to previous value. */
736*22ce4affSfengbojiang int stats_v1_voi_update(struct statsblobv1 *sb, int32_t voi_id,
737*22ce4affSfengbojiang enum vsd_dtype voi_dtype, struct voistatdata *voival, uint32_t flags);
738*22ce4affSfengbojiang int stats_v1_voistat_fetch_dptr(struct statsblobv1 *sb, int32_t voi_id,
739*22ce4affSfengbojiang enum voi_stype stype, enum vsd_dtype *retdtype, struct voistatdata **retvsd,
740*22ce4affSfengbojiang size_t *retvsdsz);
741*22ce4affSfengbojiang
742*22ce4affSfengbojiang /* End ABI specific functions. */
743*22ce4affSfengbojiang
744*22ce4affSfengbojiang /* ABI agnostic functions. */
745*22ce4affSfengbojiang int stats_vss_hlpr_init(enum vsd_dtype voi_dtype, uint32_t nvss,
746*22ce4affSfengbojiang struct voistatspec *vss);
747*22ce4affSfengbojiang void stats_vss_hlpr_cleanup(uint32_t nvss, struct voistatspec *vss);
748*22ce4affSfengbojiang int stats_vss_hist_hlpr(enum vsd_dtype voi_dtype, struct voistatspec *vss,
749*22ce4affSfengbojiang struct vss_hist_hlpr_info *info);
750*22ce4affSfengbojiang int stats_vss_numeric_hlpr(enum vsd_dtype voi_dtype, struct voistatspec *vss,
751*22ce4affSfengbojiang struct vss_numeric_hlpr_info *info);
752*22ce4affSfengbojiang int stats_vss_tdgst_hlpr(enum vsd_dtype voi_dtype, struct voistatspec *vss,
753*22ce4affSfengbojiang struct vss_tdgst_hlpr_info *info);
754*22ce4affSfengbojiang int stats_tpl_fetch(int tpl_id, struct statsblob_tpl **tpl);
755*22ce4affSfengbojiang int stats_tpl_fetch_allocid(const char *name, uint32_t hash);
756*22ce4affSfengbojiang int stats_tpl_id2name(uint32_t tpl_id, char *buf, size_t len);
757*22ce4affSfengbojiang int stats_tpl_sample_rates(struct sysctl_oid *oidp, void *arg1, intmax_t arg2,
758*22ce4affSfengbojiang struct sysctl_req *req);
759*22ce4affSfengbojiang int stats_tpl_sample_rollthedice(struct stats_tpl_sample_rate *rates,
760*22ce4affSfengbojiang int nrates, void *seed_bytes, size_t seed_len);
761*22ce4affSfengbojiang int stats_voistatdata_tostr(const struct voistatdata *vsd,
762*22ce4affSfengbojiang enum vsd_dtype voi_dtype, enum vsd_dtype vsd_dtype, size_t vsd_sz,
763*22ce4affSfengbojiang enum sb_str_fmt fmt, struct sbuf *buf, int objdump);
764*22ce4affSfengbojiang
765*22ce4affSfengbojiang static inline struct voistatdata_numeric
stats_ctor_vsd_numeric(uint64_t val)766*22ce4affSfengbojiang stats_ctor_vsd_numeric(uint64_t val)
767*22ce4affSfengbojiang {
768*22ce4affSfengbojiang struct voistatdata_numeric tmp;
769*22ce4affSfengbojiang
770*22ce4affSfengbojiang tmp.int64.u64 = val;
771*22ce4affSfengbojiang
772*22ce4affSfengbojiang return (tmp);
773*22ce4affSfengbojiang }
774*22ce4affSfengbojiang
775*22ce4affSfengbojiang static inline int
stats_tpl_alloc(const char * name,uint32_t flags)776*22ce4affSfengbojiang stats_tpl_alloc(const char *name, uint32_t flags)
777*22ce4affSfengbojiang {
778*22ce4affSfengbojiang
779*22ce4affSfengbojiang return (stats_v1_tpl_alloc(name, flags));
780*22ce4affSfengbojiang }
781*22ce4affSfengbojiang
782*22ce4affSfengbojiang static inline int
stats_tpl_add_voistats(uint32_t tpl_id,int32_t voi_id,const char * voi_name,enum vsd_dtype voi_dtype,uint32_t nvss,struct voistatspec * vss,uint32_t flags)783*22ce4affSfengbojiang stats_tpl_add_voistats(uint32_t tpl_id, int32_t voi_id, const char *voi_name,
784*22ce4affSfengbojiang enum vsd_dtype voi_dtype, uint32_t nvss, struct voistatspec *vss,
785*22ce4affSfengbojiang uint32_t flags)
786*22ce4affSfengbojiang {
787*22ce4affSfengbojiang int ret;
788*22ce4affSfengbojiang
789*22ce4affSfengbojiang if ((ret = stats_vss_hlpr_init(voi_dtype, nvss, vss)) == 0) {
790*22ce4affSfengbojiang ret = stats_v1_tpl_add_voistats(tpl_id, voi_id, voi_name,
791*22ce4affSfengbojiang voi_dtype, nvss, vss, flags);
792*22ce4affSfengbojiang }
793*22ce4affSfengbojiang stats_vss_hlpr_cleanup(nvss, vss);
794*22ce4affSfengbojiang
795*22ce4affSfengbojiang return (ret);
796*22ce4affSfengbojiang }
797*22ce4affSfengbojiang
798*22ce4affSfengbojiang static inline int
stats_blob_init(struct statsblob * sb,uint32_t tpl_id,uint32_t flags)799*22ce4affSfengbojiang stats_blob_init(struct statsblob *sb, uint32_t tpl_id, uint32_t flags)
800*22ce4affSfengbojiang {
801*22ce4affSfengbojiang
802*22ce4affSfengbojiang return (stats_v1_blob_init((struct statsblobv1 *)sb, tpl_id, flags));
803*22ce4affSfengbojiang }
804*22ce4affSfengbojiang
805*22ce4affSfengbojiang static inline struct statsblob *
stats_blob_alloc(uint32_t tpl_id,uint32_t flags)806*22ce4affSfengbojiang stats_blob_alloc(uint32_t tpl_id, uint32_t flags)
807*22ce4affSfengbojiang {
808*22ce4affSfengbojiang
809*22ce4affSfengbojiang return ((struct statsblob *)stats_v1_blob_alloc(tpl_id, flags));
810*22ce4affSfengbojiang }
811*22ce4affSfengbojiang
812*22ce4affSfengbojiang static inline int
stats_blob_clone(struct statsblob ** dst,size_t dstmaxsz,struct statsblob * src,uint32_t flags)813*22ce4affSfengbojiang stats_blob_clone(struct statsblob **dst, size_t dstmaxsz, struct statsblob *src,
814*22ce4affSfengbojiang uint32_t flags)
815*22ce4affSfengbojiang {
816*22ce4affSfengbojiang
817*22ce4affSfengbojiang return (stats_v1_blob_clone((struct statsblobv1 **)dst, dstmaxsz,
818*22ce4affSfengbojiang (struct statsblobv1 *)src, flags));
819*22ce4affSfengbojiang }
820*22ce4affSfengbojiang
821*22ce4affSfengbojiang static inline void
stats_blob_destroy(struct statsblob * sb)822*22ce4affSfengbojiang stats_blob_destroy(struct statsblob *sb)
823*22ce4affSfengbojiang {
824*22ce4affSfengbojiang
825*22ce4affSfengbojiang stats_v1_blob_destroy((struct statsblobv1 *)sb);
826*22ce4affSfengbojiang }
827*22ce4affSfengbojiang
828*22ce4affSfengbojiang static inline int
stats_blob_visit(struct statsblob * sb,stats_blob_visitcb_t func,void * usrctx)829*22ce4affSfengbojiang stats_blob_visit(struct statsblob *sb, stats_blob_visitcb_t func, void *usrctx)
830*22ce4affSfengbojiang {
831*22ce4affSfengbojiang
832*22ce4affSfengbojiang return (stats_v1_blob_visit((struct statsblobv1 *)sb, func, usrctx));
833*22ce4affSfengbojiang }
834*22ce4affSfengbojiang
835*22ce4affSfengbojiang static inline int
stats_blob_tostr(struct statsblob * sb,struct sbuf * buf,enum sb_str_fmt fmt,uint32_t flags)836*22ce4affSfengbojiang stats_blob_tostr(struct statsblob *sb, struct sbuf *buf,
837*22ce4affSfengbojiang enum sb_str_fmt fmt, uint32_t flags)
838*22ce4affSfengbojiang {
839*22ce4affSfengbojiang
840*22ce4affSfengbojiang return (stats_v1_blob_tostr((struct statsblobv1 *)sb, buf, fmt, flags));
841*22ce4affSfengbojiang }
842*22ce4affSfengbojiang
843*22ce4affSfengbojiang static inline int
stats_voistat_fetch_dptr(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,enum vsd_dtype * retdtype,struct voistatdata ** retvsd,size_t * retvsdsz)844*22ce4affSfengbojiang stats_voistat_fetch_dptr(struct statsblob *sb, int32_t voi_id,
845*22ce4affSfengbojiang enum voi_stype stype, enum vsd_dtype *retdtype, struct voistatdata **retvsd,
846*22ce4affSfengbojiang size_t *retvsdsz)
847*22ce4affSfengbojiang {
848*22ce4affSfengbojiang
849*22ce4affSfengbojiang return (stats_v1_voistat_fetch_dptr((struct statsblobv1 *)sb,
850*22ce4affSfengbojiang voi_id, stype, retdtype, retvsd, retvsdsz));
851*22ce4affSfengbojiang }
852*22ce4affSfengbojiang
853*22ce4affSfengbojiang static inline int
stats_voistat_fetch_s64(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,int64_t * ret)854*22ce4affSfengbojiang stats_voistat_fetch_s64(struct statsblob *sb, int32_t voi_id,
855*22ce4affSfengbojiang enum voi_stype stype, int64_t *ret)
856*22ce4affSfengbojiang {
857*22ce4affSfengbojiang struct voistatdata *vsd;
858*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
859*22ce4affSfengbojiang int error;
860*22ce4affSfengbojiang
861*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
862*22ce4affSfengbojiang NULL)))
863*22ce4affSfengbojiang return (error);
864*22ce4affSfengbojiang else if (VSD_DTYPE_INT_S64 != vs_dtype)
865*22ce4affSfengbojiang return (EFTYPE);
866*22ce4affSfengbojiang
867*22ce4affSfengbojiang *ret = vsd->int64.s64;
868*22ce4affSfengbojiang return (0);
869*22ce4affSfengbojiang }
870*22ce4affSfengbojiang
871*22ce4affSfengbojiang static inline int
stats_voistat_fetch_u64(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,uint64_t * ret)872*22ce4affSfengbojiang stats_voistat_fetch_u64(struct statsblob *sb, int32_t voi_id,
873*22ce4affSfengbojiang enum voi_stype stype, uint64_t *ret)
874*22ce4affSfengbojiang {
875*22ce4affSfengbojiang struct voistatdata *vsd;
876*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
877*22ce4affSfengbojiang int error;
878*22ce4affSfengbojiang
879*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
880*22ce4affSfengbojiang NULL)))
881*22ce4affSfengbojiang return (error);
882*22ce4affSfengbojiang else if (VSD_DTYPE_INT_U64 != vs_dtype)
883*22ce4affSfengbojiang return (EFTYPE);
884*22ce4affSfengbojiang
885*22ce4affSfengbojiang *ret = vsd->int64.u64;
886*22ce4affSfengbojiang return (0);
887*22ce4affSfengbojiang }
888*22ce4affSfengbojiang
889*22ce4affSfengbojiang static inline int
stats_voistat_fetch_s32(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,int32_t * ret)890*22ce4affSfengbojiang stats_voistat_fetch_s32(struct statsblob *sb, int32_t voi_id,
891*22ce4affSfengbojiang enum voi_stype stype, int32_t *ret)
892*22ce4affSfengbojiang {
893*22ce4affSfengbojiang struct voistatdata *vsd;
894*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
895*22ce4affSfengbojiang int error;
896*22ce4affSfengbojiang
897*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
898*22ce4affSfengbojiang NULL)))
899*22ce4affSfengbojiang return (error);
900*22ce4affSfengbojiang else if (VSD_DTYPE_INT_S32 != vs_dtype)
901*22ce4affSfengbojiang return (EFTYPE);
902*22ce4affSfengbojiang
903*22ce4affSfengbojiang *ret = vsd->int32.s32;
904*22ce4affSfengbojiang return (0);
905*22ce4affSfengbojiang }
906*22ce4affSfengbojiang
907*22ce4affSfengbojiang static inline int
stats_voistat_fetch_u32(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,uint32_t * ret)908*22ce4affSfengbojiang stats_voistat_fetch_u32(struct statsblob *sb, int32_t voi_id,
909*22ce4affSfengbojiang enum voi_stype stype, uint32_t *ret)
910*22ce4affSfengbojiang {
911*22ce4affSfengbojiang struct voistatdata *vsd;
912*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
913*22ce4affSfengbojiang int error;
914*22ce4affSfengbojiang
915*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
916*22ce4affSfengbojiang NULL)))
917*22ce4affSfengbojiang return (error);
918*22ce4affSfengbojiang else if (VSD_DTYPE_INT_U32 != vs_dtype)
919*22ce4affSfengbojiang return (EFTYPE);
920*22ce4affSfengbojiang
921*22ce4affSfengbojiang *ret = vsd->int32.u32;
922*22ce4affSfengbojiang return (0);
923*22ce4affSfengbojiang }
924*22ce4affSfengbojiang
925*22ce4affSfengbojiang static inline int
stats_voistat_fetch_slong(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,long * ret)926*22ce4affSfengbojiang stats_voistat_fetch_slong(struct statsblob *sb, int32_t voi_id,
927*22ce4affSfengbojiang enum voi_stype stype, long *ret)
928*22ce4affSfengbojiang {
929*22ce4affSfengbojiang struct voistatdata *vsd;
930*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
931*22ce4affSfengbojiang int error;
932*22ce4affSfengbojiang
933*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
934*22ce4affSfengbojiang NULL)))
935*22ce4affSfengbojiang return (error);
936*22ce4affSfengbojiang else if (VSD_DTYPE_INT_SLONG != vs_dtype)
937*22ce4affSfengbojiang return (EFTYPE);
938*22ce4affSfengbojiang
939*22ce4affSfengbojiang *ret = vsd->intlong.slong;
940*22ce4affSfengbojiang return (0);
941*22ce4affSfengbojiang }
942*22ce4affSfengbojiang
943*22ce4affSfengbojiang static inline int
stats_voistat_fetch_ulong(struct statsblob * sb,int32_t voi_id,enum voi_stype stype,unsigned long * ret)944*22ce4affSfengbojiang stats_voistat_fetch_ulong(struct statsblob *sb, int32_t voi_id,
945*22ce4affSfengbojiang enum voi_stype stype, unsigned long *ret)
946*22ce4affSfengbojiang {
947*22ce4affSfengbojiang struct voistatdata *vsd;
948*22ce4affSfengbojiang enum vsd_dtype vs_dtype;
949*22ce4affSfengbojiang int error;
950*22ce4affSfengbojiang
951*22ce4affSfengbojiang if ((error = stats_voistat_fetch_dptr(sb, voi_id, stype, &vs_dtype, &vsd,
952*22ce4affSfengbojiang NULL)))
953*22ce4affSfengbojiang return (error);
954*22ce4affSfengbojiang else if (VSD_DTYPE_INT_ULONG != vs_dtype)
955*22ce4affSfengbojiang return (EFTYPE);
956*22ce4affSfengbojiang
957*22ce4affSfengbojiang *ret = vsd->intlong.ulong;
958*22ce4affSfengbojiang return (0);
959*22ce4affSfengbojiang }
960*22ce4affSfengbojiang
961*22ce4affSfengbojiang static inline int
stats_blob_snapshot(struct statsblob ** dst,size_t dstmaxsz,struct statsblob * src,uint32_t flags)962*22ce4affSfengbojiang stats_blob_snapshot(struct statsblob **dst, size_t dstmaxsz,
963*22ce4affSfengbojiang struct statsblob *src, uint32_t flags)
964*22ce4affSfengbojiang {
965*22ce4affSfengbojiang
966*22ce4affSfengbojiang return (stats_v1_blob_snapshot((struct statsblobv1 **)dst, dstmaxsz,
967*22ce4affSfengbojiang (struct statsblobv1 *)src, flags));
968*22ce4affSfengbojiang }
969*22ce4affSfengbojiang
970*22ce4affSfengbojiang static inline int
stats_voi_update_abs_s32(struct statsblob * sb,int32_t voi_id,int32_t voival)971*22ce4affSfengbojiang stats_voi_update_abs_s32(struct statsblob *sb, int32_t voi_id, int32_t voival)
972*22ce4affSfengbojiang {
973*22ce4affSfengbojiang
974*22ce4affSfengbojiang if (sb == NULL)
975*22ce4affSfengbojiang return (0);
976*22ce4affSfengbojiang
977*22ce4affSfengbojiang struct voistatdata tmp;
978*22ce4affSfengbojiang tmp.int32.s32 = voival;
979*22ce4affSfengbojiang
980*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
981*22ce4affSfengbojiang VSD_DTYPE_INT_S32, &tmp, 0));
982*22ce4affSfengbojiang }
983*22ce4affSfengbojiang
984*22ce4affSfengbojiang static inline int
stats_voi_update_rel_s32(struct statsblob * sb,int32_t voi_id,int32_t voival)985*22ce4affSfengbojiang stats_voi_update_rel_s32(struct statsblob *sb, int32_t voi_id, int32_t voival)
986*22ce4affSfengbojiang {
987*22ce4affSfengbojiang
988*22ce4affSfengbojiang if (sb == NULL)
989*22ce4affSfengbojiang return (0);
990*22ce4affSfengbojiang
991*22ce4affSfengbojiang struct voistatdata tmp;
992*22ce4affSfengbojiang tmp.int32.s32 = voival;
993*22ce4affSfengbojiang
994*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
995*22ce4affSfengbojiang VSD_DTYPE_INT_S32, &tmp, SB_VOI_RELUPDATE));
996*22ce4affSfengbojiang }
997*22ce4affSfengbojiang
998*22ce4affSfengbojiang static inline int
stats_voi_update_abs_u32(struct statsblob * sb,int32_t voi_id,uint32_t voival)999*22ce4affSfengbojiang stats_voi_update_abs_u32(struct statsblob *sb, int32_t voi_id, uint32_t voival)
1000*22ce4affSfengbojiang {
1001*22ce4affSfengbojiang
1002*22ce4affSfengbojiang if (sb == NULL)
1003*22ce4affSfengbojiang return (0);
1004*22ce4affSfengbojiang
1005*22ce4affSfengbojiang struct voistatdata tmp;
1006*22ce4affSfengbojiang tmp.int32.u32 = voival;
1007*22ce4affSfengbojiang
1008*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1009*22ce4affSfengbojiang VSD_DTYPE_INT_U32, &tmp, 0));
1010*22ce4affSfengbojiang }
1011*22ce4affSfengbojiang
1012*22ce4affSfengbojiang static inline int
stats_voi_update_rel_u32(struct statsblob * sb,int32_t voi_id,uint32_t voival)1013*22ce4affSfengbojiang stats_voi_update_rel_u32(struct statsblob *sb, int32_t voi_id, uint32_t voival)
1014*22ce4affSfengbojiang {
1015*22ce4affSfengbojiang
1016*22ce4affSfengbojiang if (sb == NULL)
1017*22ce4affSfengbojiang return (0);
1018*22ce4affSfengbojiang
1019*22ce4affSfengbojiang struct voistatdata tmp;
1020*22ce4affSfengbojiang tmp.int32.u32 = voival;
1021*22ce4affSfengbojiang
1022*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1023*22ce4affSfengbojiang VSD_DTYPE_INT_U32, &tmp, SB_VOI_RELUPDATE));
1024*22ce4affSfengbojiang }
1025*22ce4affSfengbojiang
1026*22ce4affSfengbojiang static inline int
stats_voi_update_abs_s64(struct statsblob * sb,int32_t voi_id,int64_t voival)1027*22ce4affSfengbojiang stats_voi_update_abs_s64(struct statsblob *sb, int32_t voi_id, int64_t voival)
1028*22ce4affSfengbojiang {
1029*22ce4affSfengbojiang
1030*22ce4affSfengbojiang if (sb == NULL)
1031*22ce4affSfengbojiang return (0);
1032*22ce4affSfengbojiang
1033*22ce4affSfengbojiang struct voistatdata tmp;
1034*22ce4affSfengbojiang tmp.int64.s64 = voival;
1035*22ce4affSfengbojiang
1036*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1037*22ce4affSfengbojiang VSD_DTYPE_INT_S64, &tmp, 0));
1038*22ce4affSfengbojiang }
1039*22ce4affSfengbojiang
1040*22ce4affSfengbojiang static inline int
stats_voi_update_rel_s64(struct statsblob * sb,int32_t voi_id,int64_t voival)1041*22ce4affSfengbojiang stats_voi_update_rel_s64(struct statsblob *sb, int32_t voi_id, int64_t voival)
1042*22ce4affSfengbojiang {
1043*22ce4affSfengbojiang
1044*22ce4affSfengbojiang if (sb == NULL)
1045*22ce4affSfengbojiang return (0);
1046*22ce4affSfengbojiang
1047*22ce4affSfengbojiang struct voistatdata tmp;
1048*22ce4affSfengbojiang tmp.int64.s64 = voival;
1049*22ce4affSfengbojiang
1050*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1051*22ce4affSfengbojiang VSD_DTYPE_INT_S64, &tmp, SB_VOI_RELUPDATE));
1052*22ce4affSfengbojiang }
1053*22ce4affSfengbojiang
1054*22ce4affSfengbojiang static inline int
stats_voi_update_abs_u64(struct statsblob * sb,int32_t voi_id,uint64_t voival)1055*22ce4affSfengbojiang stats_voi_update_abs_u64(struct statsblob *sb, int32_t voi_id, uint64_t voival)
1056*22ce4affSfengbojiang {
1057*22ce4affSfengbojiang
1058*22ce4affSfengbojiang if (sb == NULL)
1059*22ce4affSfengbojiang return (0);
1060*22ce4affSfengbojiang
1061*22ce4affSfengbojiang struct voistatdata tmp;
1062*22ce4affSfengbojiang tmp.int64.u64 = voival;
1063*22ce4affSfengbojiang
1064*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1065*22ce4affSfengbojiang VSD_DTYPE_INT_U64, &tmp, 0));
1066*22ce4affSfengbojiang }
1067*22ce4affSfengbojiang
1068*22ce4affSfengbojiang static inline int
stats_voi_update_rel_u64(struct statsblob * sb,int32_t voi_id,uint64_t voival)1069*22ce4affSfengbojiang stats_voi_update_rel_u64(struct statsblob *sb, int32_t voi_id, uint64_t voival)
1070*22ce4affSfengbojiang {
1071*22ce4affSfengbojiang
1072*22ce4affSfengbojiang if (sb == NULL)
1073*22ce4affSfengbojiang return (0);
1074*22ce4affSfengbojiang
1075*22ce4affSfengbojiang struct voistatdata tmp;
1076*22ce4affSfengbojiang tmp.int64.u64 = voival;
1077*22ce4affSfengbojiang
1078*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1079*22ce4affSfengbojiang VSD_DTYPE_INT_U64, &tmp, SB_VOI_RELUPDATE));
1080*22ce4affSfengbojiang }
1081*22ce4affSfengbojiang
1082*22ce4affSfengbojiang static inline int
stats_voi_update_abs_slong(struct statsblob * sb,int32_t voi_id,long voival)1083*22ce4affSfengbojiang stats_voi_update_abs_slong(struct statsblob *sb, int32_t voi_id, long voival)
1084*22ce4affSfengbojiang {
1085*22ce4affSfengbojiang
1086*22ce4affSfengbojiang if (sb == NULL)
1087*22ce4affSfengbojiang return (0);
1088*22ce4affSfengbojiang
1089*22ce4affSfengbojiang struct voistatdata tmp;
1090*22ce4affSfengbojiang tmp.intlong.slong = voival;
1091*22ce4affSfengbojiang
1092*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1093*22ce4affSfengbojiang VSD_DTYPE_INT_SLONG, &tmp, 0));
1094*22ce4affSfengbojiang }
1095*22ce4affSfengbojiang
1096*22ce4affSfengbojiang static inline int
stats_voi_update_rel_slong(struct statsblob * sb,int32_t voi_id,long voival)1097*22ce4affSfengbojiang stats_voi_update_rel_slong(struct statsblob *sb, int32_t voi_id, long voival)
1098*22ce4affSfengbojiang {
1099*22ce4affSfengbojiang
1100*22ce4affSfengbojiang if (sb == NULL)
1101*22ce4affSfengbojiang return (0);
1102*22ce4affSfengbojiang
1103*22ce4affSfengbojiang struct voistatdata tmp;
1104*22ce4affSfengbojiang tmp.intlong.slong = voival;
1105*22ce4affSfengbojiang
1106*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1107*22ce4affSfengbojiang VSD_DTYPE_INT_SLONG, &tmp, SB_VOI_RELUPDATE));
1108*22ce4affSfengbojiang }
1109*22ce4affSfengbojiang
1110*22ce4affSfengbojiang static inline int
stats_voi_update_abs_ulong(struct statsblob * sb,int32_t voi_id,unsigned long voival)1111*22ce4affSfengbojiang stats_voi_update_abs_ulong(struct statsblob *sb, int32_t voi_id,
1112*22ce4affSfengbojiang unsigned long voival)
1113*22ce4affSfengbojiang {
1114*22ce4affSfengbojiang
1115*22ce4affSfengbojiang if (sb == NULL)
1116*22ce4affSfengbojiang return (0);
1117*22ce4affSfengbojiang
1118*22ce4affSfengbojiang struct voistatdata tmp;
1119*22ce4affSfengbojiang tmp.intlong.ulong = voival;
1120*22ce4affSfengbojiang
1121*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1122*22ce4affSfengbojiang VSD_DTYPE_INT_ULONG, &tmp, 0));
1123*22ce4affSfengbojiang }
1124*22ce4affSfengbojiang
1125*22ce4affSfengbojiang static inline int
stats_voi_update_rel_ulong(struct statsblob * sb,int32_t voi_id,unsigned long voival)1126*22ce4affSfengbojiang stats_voi_update_rel_ulong(struct statsblob *sb, int32_t voi_id,
1127*22ce4affSfengbojiang unsigned long voival)
1128*22ce4affSfengbojiang {
1129*22ce4affSfengbojiang
1130*22ce4affSfengbojiang if (sb == NULL)
1131*22ce4affSfengbojiang return (0);
1132*22ce4affSfengbojiang
1133*22ce4affSfengbojiang struct voistatdata tmp;
1134*22ce4affSfengbojiang tmp.intlong.ulong = voival;
1135*22ce4affSfengbojiang
1136*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1137*22ce4affSfengbojiang VSD_DTYPE_INT_ULONG, &tmp, SB_VOI_RELUPDATE));
1138*22ce4affSfengbojiang }
1139*22ce4affSfengbojiang
1140*22ce4affSfengbojiang static inline int
stats_voi_update_abs_sq32(struct statsblob * sb,int32_t voi_id,s32q_t voival)1141*22ce4affSfengbojiang stats_voi_update_abs_sq32(struct statsblob *sb, int32_t voi_id, s32q_t voival)
1142*22ce4affSfengbojiang {
1143*22ce4affSfengbojiang
1144*22ce4affSfengbojiang if (sb == NULL)
1145*22ce4affSfengbojiang return (0);
1146*22ce4affSfengbojiang
1147*22ce4affSfengbojiang struct voistatdata tmp;
1148*22ce4affSfengbojiang tmp.q32.sq32 = voival;
1149*22ce4affSfengbojiang
1150*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1151*22ce4affSfengbojiang VSD_DTYPE_Q_S32, &tmp, 0));
1152*22ce4affSfengbojiang }
1153*22ce4affSfengbojiang
1154*22ce4affSfengbojiang static inline int
stats_voi_update_rel_sq32(struct statsblob * sb,int32_t voi_id,s32q_t voival)1155*22ce4affSfengbojiang stats_voi_update_rel_sq32(struct statsblob *sb, int32_t voi_id, s32q_t voival)
1156*22ce4affSfengbojiang {
1157*22ce4affSfengbojiang
1158*22ce4affSfengbojiang if (sb == NULL)
1159*22ce4affSfengbojiang return (0);
1160*22ce4affSfengbojiang
1161*22ce4affSfengbojiang struct voistatdata tmp;
1162*22ce4affSfengbojiang tmp.q32.sq32 = voival;
1163*22ce4affSfengbojiang
1164*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1165*22ce4affSfengbojiang VSD_DTYPE_Q_S32, &tmp, SB_VOI_RELUPDATE));
1166*22ce4affSfengbojiang }
1167*22ce4affSfengbojiang
1168*22ce4affSfengbojiang static inline int
stats_voi_update_abs_uq32(struct statsblob * sb,int32_t voi_id,u32q_t voival)1169*22ce4affSfengbojiang stats_voi_update_abs_uq32(struct statsblob *sb, int32_t voi_id, u32q_t voival)
1170*22ce4affSfengbojiang {
1171*22ce4affSfengbojiang
1172*22ce4affSfengbojiang if (sb == NULL)
1173*22ce4affSfengbojiang return (0);
1174*22ce4affSfengbojiang
1175*22ce4affSfengbojiang struct voistatdata tmp;
1176*22ce4affSfengbojiang tmp.q32.uq32 = voival;
1177*22ce4affSfengbojiang
1178*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1179*22ce4affSfengbojiang VSD_DTYPE_Q_U32, &tmp, 0));
1180*22ce4affSfengbojiang }
1181*22ce4affSfengbojiang
1182*22ce4affSfengbojiang static inline int
stats_voi_update_rel_uq32(struct statsblob * sb,int32_t voi_id,u32q_t voival)1183*22ce4affSfengbojiang stats_voi_update_rel_uq32(struct statsblob *sb, int32_t voi_id, u32q_t voival)
1184*22ce4affSfengbojiang {
1185*22ce4affSfengbojiang
1186*22ce4affSfengbojiang if (sb == NULL)
1187*22ce4affSfengbojiang return (0);
1188*22ce4affSfengbojiang
1189*22ce4affSfengbojiang struct voistatdata tmp;
1190*22ce4affSfengbojiang tmp.q32.uq32 = voival;
1191*22ce4affSfengbojiang
1192*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1193*22ce4affSfengbojiang VSD_DTYPE_Q_U32, &tmp, SB_VOI_RELUPDATE));
1194*22ce4affSfengbojiang }
1195*22ce4affSfengbojiang
1196*22ce4affSfengbojiang static inline int
stats_voi_update_abs_sq64(struct statsblob * sb,int32_t voi_id,s64q_t voival)1197*22ce4affSfengbojiang stats_voi_update_abs_sq64(struct statsblob *sb, int32_t voi_id, s64q_t voival)
1198*22ce4affSfengbojiang {
1199*22ce4affSfengbojiang
1200*22ce4affSfengbojiang if (sb == NULL)
1201*22ce4affSfengbojiang return (0);
1202*22ce4affSfengbojiang
1203*22ce4affSfengbojiang struct voistatdata tmp;
1204*22ce4affSfengbojiang tmp.q64.sq64 = voival;
1205*22ce4affSfengbojiang
1206*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1207*22ce4affSfengbojiang VSD_DTYPE_Q_S64, &tmp, 0));
1208*22ce4affSfengbojiang }
1209*22ce4affSfengbojiang
1210*22ce4affSfengbojiang static inline int
stats_voi_update_rel_sq64(struct statsblob * sb,int32_t voi_id,s64q_t voival)1211*22ce4affSfengbojiang stats_voi_update_rel_sq64(struct statsblob *sb, int32_t voi_id, s64q_t voival)
1212*22ce4affSfengbojiang {
1213*22ce4affSfengbojiang
1214*22ce4affSfengbojiang if (sb == NULL)
1215*22ce4affSfengbojiang return (0);
1216*22ce4affSfengbojiang
1217*22ce4affSfengbojiang struct voistatdata tmp;
1218*22ce4affSfengbojiang tmp.q64.sq64 = voival;
1219*22ce4affSfengbojiang
1220*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1221*22ce4affSfengbojiang VSD_DTYPE_Q_S64, &tmp, SB_VOI_RELUPDATE));
1222*22ce4affSfengbojiang }
1223*22ce4affSfengbojiang
1224*22ce4affSfengbojiang static inline int
stats_voi_update_abs_uq64(struct statsblob * sb,int32_t voi_id,u64q_t voival)1225*22ce4affSfengbojiang stats_voi_update_abs_uq64(struct statsblob *sb, int32_t voi_id, u64q_t voival)
1226*22ce4affSfengbojiang {
1227*22ce4affSfengbojiang
1228*22ce4affSfengbojiang if (sb == NULL)
1229*22ce4affSfengbojiang return (0);
1230*22ce4affSfengbojiang
1231*22ce4affSfengbojiang struct voistatdata tmp;
1232*22ce4affSfengbojiang tmp.q64.uq64 = voival;
1233*22ce4affSfengbojiang
1234*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1235*22ce4affSfengbojiang VSD_DTYPE_Q_U64, &tmp, 0));
1236*22ce4affSfengbojiang }
1237*22ce4affSfengbojiang
1238*22ce4affSfengbojiang static inline int
stats_voi_update_rel_uq64(struct statsblob * sb,int32_t voi_id,u64q_t voival)1239*22ce4affSfengbojiang stats_voi_update_rel_uq64(struct statsblob *sb, int32_t voi_id, u64q_t voival)
1240*22ce4affSfengbojiang {
1241*22ce4affSfengbojiang
1242*22ce4affSfengbojiang if (sb == NULL)
1243*22ce4affSfengbojiang return (0);
1244*22ce4affSfengbojiang
1245*22ce4affSfengbojiang struct voistatdata tmp;
1246*22ce4affSfengbojiang tmp.q64.uq64 = voival;
1247*22ce4affSfengbojiang
1248*22ce4affSfengbojiang return (stats_v1_voi_update((struct statsblobv1 *)sb, voi_id,
1249*22ce4affSfengbojiang VSD_DTYPE_Q_U64, &tmp, SB_VOI_RELUPDATE));
1250*22ce4affSfengbojiang }
1251*22ce4affSfengbojiang
1252*22ce4affSfengbojiang /* End ABI agnostic functions. */
1253*22ce4affSfengbojiang
1254*22ce4affSfengbojiang #endif /* _SYS_STATS_H_ */
1255