The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/stats.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 70bc2eecbfbfcf8befe839f606801321


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.