1.\" 2.\" Copyright (c) 2016-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.\" without modification, immediately at the beginning of the file. 11.\" 2. The name of the author may not be used to endorse or promote products 12.\" derived from this software without specific prior written permission. 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 FOR 18.\" 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.Dd December 2, 2019 27.Dt STATS 3 28.Os 29.Sh NAME 30.Nm stats 31.Nd statistics gathering 32.Sh LIBRARY 33.Lb libstats 34.Sh SYNOPSIS 35.In sys/arb.h 36.In sys/qmath.h 37.In sys/stats.h 38.Ss Stats Blob Template Management Functions 39.Ft int 40.Fo stats_tpl_alloc 41.Fa "const char *name" 42.Fa "uint32_t flags" 43.Fc 44.Ft int 45.Fo stats_tpl_fetch_allocid 46.Fa "const char *name" 47.Fa "uint32_t hash" 48.Fc 49.Ft int 50.Fo stats_tpl_fetch 51.Fa "int tpl_id" 52.Fa "struct statsblob_tpl **tpl" 53.Fc 54.Ft int 55.Fo stats_tpl_id2name 56.Fa "uint32_t tpl_id" 57.Fa "char *buf" 58.Fa "size_t len" 59.Fc 60.Ft int 61.Fo stats_tpl_sample_rates 62.Fa "SYSCTL_HANDLER_ARGS" 63.Fc 64.Ft int 65.Fo stats_tpl_sample_rollthedice 66.Fa "struct stats_tpl_sample_rate *rates" 67.Fa "int nrates" 68.Fa "void *seed_bytes" 69.Fa "size_t seed_len" 70.Fc 71.Ft struct voistatspec 72.Fo STATS_VSS_SUM 73.Fc 74.Ft struct voistatspec 75.Fo STATS_VSS_MAX 76.Fc 77.Ft struct voistatspec 78.Fo STATS_VSS_MIN 79.Fc 80.Ft struct voistatspec 81.Fo STATS_VSS_CRHIST<32|64>_LIN 82.Fa "lb" 83.Fa "ub" 84.Fa "stepinc" 85.Fa "vsdflags" 86.Fc 87.Ft struct voistatspec 88.Fo STATS_VSS_CRHIST<32|64>_EXP 89.Fa "lb" 90.Fa "ub" 91.Fa "stepbase" 92.Fa "stepexp" 93.Fa "vsdflags" 94.Fc 95.Ft struct voistatspec 96.Fo "STATS_VSS_CRHIST<32|64>_LINEXP" 97.Fa "lb" 98.Fa "ub" 99.Fa "nlinsteps" 100.Fa "stepbase" 101.Fa "vsdflags" 102.Fc 103.Ft struct voistatspec 104.Fo "STATS_VSS_CRHIST<32|64>_USR" 105.Fa Sy "HBKTS" Ns Pq Sy "CRBKT" Ns ( Em "lb" ) , "..." Pc , 106.Fa "vsdflags" 107.Fc 108.Ft struct voistatspec 109.Fo "STATS_VSS_DRHIST<32|64>_USR" 110.Fa Sy "HBKTS" Ns Pq Sy "DRBKT" Ns ( Em "lb" , "ub" ) , "..." Pc , 111.Fa "vsdflags" 112.Fc 113.Ft struct voistatspec 114.Fo "STATS_VSS_DVHIST<32|64>_USR" 115.Fa Sy "HBKTS" Ns Pq Sy "DVBKT" Ns ( Em "val" ) , "..." Pc , 116.Fa "vsdflags" 117.Fc 118.Ft struct voistatspec 119.Fo STATS_VSS_TDGSTCLUST<32|64> 120.Fa "nctroids" 121.Fa "prec" 122.Fc 123.Ft int 124.Fo stats_tpl_add_voistats 125.Fa "uint32_t tpl_id" 126.Fa "int32_t voi_id" 127.Fa "const char *voi_name" 128.Fa "enum vsd_dtype voi_dtype" 129.Fa "uint32_t nvss" 130.Fa "struct voistatspec *vss" 131.Fa "uint32_t flags" 132.Fc 133.Ss Stats Blob Data Gathering Functions 134.Ft int 135.Fo stats_voi_update_<abs|rel>_<dtype> 136.Fa "struct statsblob *sb" 137.Fa "int32_t voi_id" 138.Fa "<dtype> voival" 139.Fc 140.Ss Stats Blob Utility Functions 141.Ft struct statsblob * 142.Fo stats_blob_alloc 143.Fa "uint32_t tpl_id" 144.Fa "uint32_t flags" 145.Fc 146.Ft int 147.Fo stats_blob_init 148.Fa "struct statsblob *sb" 149.Fa "uint32_t tpl_id" 150.Fa "uint32_t flags" 151.Fc 152.Ft int 153.Fo stats_blob_clone 154.Fa "struct statsblob **dst" 155.Fa "size_t dstmaxsz" 156.Fa "struct statsblob *src" 157.Fa "uint32_t flags" 158.Fc 159.Ft void 160.Fo stats_blob_destroy 161.Fa "struct statsblob *sb" 162.Fc 163.Ft int 164.Fo stats_voistat_fetch_dptr 165.Fa "struct statsblob *sb" 166.Fa "int32_t voi_id" 167.Fa "enum voi_stype stype" 168.Fa "enum vsd_dtype *retdtype" 169.Fa "struct voistatdata **retvsd" 170.Fa "size_t *retvsdsz" 171.Fc 172.Ft int 173.Fo stats_voistat_fetch_<dtype> 174.Fa "struct statsblob *sb" 175.Fa "int32_t voi_id" 176.Fa "enum voi_stype stype" 177.Fa "<dtype> *ret" 178.Fc 179.Ft int 180.Fo stats_blob_snapshot 181.Fa "struct statsblob **dst" 182.Fa "size_t dstmaxsz" 183.Fa "struct statsblob *src" 184.Fa "uint32_t flags" 185.Fc 186.Ft int 187.Fo stats_blob_tostr 188.Fa "struct statsblob *sb" 189.Fa "struct sbuf *buf" 190.Fa "enum sb_str_fmt fmt" 191.Fa "uint32_t flags" 192.Fc 193.Ft int 194.Fo stats_voistatdata_tostr 195.Fa "const struct voistatdata *vsd" 196.Fa "enum vsd_dtype dtype" 197.Fa "enum sb_str_fmt fmt" 198.Fa "struct sbuf *buf" 199.Fa "int objdump" 200.Fc 201.Ft typedef int 202.Fn "\*(lp*stats_blob_visitcb_t\*(rp" "struct sb_visit *sbv" "void *usrctx" 203.Ft int 204.Fo stats_blob_visit 205.Fa "struct statsblob *sb" 206.Fa "stats_blob_visitcb_t func" 207.Fa "void *usrctx" 208.Fc 209.Sh DESCRIPTION 210The 211.Nm 212framework facilitates real-time kernel and user space statistics gathering. 213The framework is built around the 214.Dq statsblob , 215an object embedded within a contiguous memory allocation that is mostly opaque 216to consumers and stores all required state. 217A 218.Dq statsblob 219object can itself be embedded within other objects either directly or indirectly 220using a pointer. 221.Pp 222Objects or subsystems for which statistics are to be gathered are initialized 223from a template 224.Dq statsblob , 225which acts as the blueprint for an arbitrary set of 226Variables Of Interest (VOIs) and their associated statistics. 227Each template defines a schema plus associated metadata, which are kept separate 228to minimize the memory footprint of blobs. 229.Pp 230Data gathering hook functions added at appropriate locations within the code 231base of interest feed VOI data into the framework for processing. 232.Pp 233Each 234.Dq statsblob , 235consists of a 236.Vt struct statsblob 237header and opaque internal blob structure per the following diagram: 238.Bd -literal -offset indent 239--------------------------------------------------------- 240| struct | uint8_t | 241| statsblob | opaque[] | 242--------------------------------------------------------- 243.Ed 244.Pp 245The publicly visible 8-byte header is defined as: 246.Bd -literal -offset indent 247struct statsblob { 248 uint8_t abi; 249 uint8_t endian; 250 uint16_t flags; 251 uint16_t maxsz; 252 uint16_t cursz; 253 uint8_t opaque[]; 254}; 255.Ed 256.Pp 257.Va abi 258specifies which API version the blob's 259.Va opaque 260internals conform to 261.Pq Dv STATS_ABI_V1 is the only version currently defined . 262.Va endian 263specifies the endianness of the blob's fields 264.Po 265.Dv SB_LE 266for little endian, 267.Dv SB_BE 268for big endian, or 269.Dv SB_UE 270for unknown endianness 271.Pc . 272.Va cursz 273specifies the size of the blob, while 274.Va maxsz 275specifies the size of the underlying memory allocation in which the 276blob is embedded. 277Both 278.Va cursz 279and 280.Va maxsz 281default to units of bytes, unless a flag is set in 282.Va flags 283that dictates otherwise. 284.Pp 285Templates are constructed by associating arbitrary VOI IDs with a set of 286statistics, where each statistic is specified using a 287.Vt struct voistatspec 288per the definition below: 289.Bd -literal -offset indent 290struct voistatspec { 291 vss_hlpr_fn hlpr; 292 struct vss_hlpr_info *hlprinfo; 293 struct voistatdata *iv; 294 size_t vsdsz; 295 uint32_t flags; 296 enum vsd_dtype vs_dtype : 8; 297 enum voi_stype stype : 8; 298}; 299.Ed 300.Pp 301It is generally expected that consumers will not work with 302.Vt struct voistatspec 303directly, and instead use the 304.Fn STATS_VSS_* 305helper macros. 306.Pp 307The 308.Nm 309framework offers the following statistics for association with VOIs: 310.Bl -tag -width ".Dv VS_STYPE_TDGST" 311.It Dv VS_STYPE_SUM 312The sum of VOI values. 313.It Dv VS_STYPE_MAX 314The maximum VOI value. 315.It Dv VS_STYPE_MIN 316The minimum VOI value. 317.It Dv VS_STYPE_HIST 318A static bucket histogram of VOI values, including a count of 319.Dq out-of-band/bucket Dc 320values which did not match any bucket. 321Histograms can be specified as 322.Dq Em C Ns ontinuous Em R Ns ange Dc 323.Pq CRHIST Pc , 324.Dq Em D Ns iscrete Em R Ns ange Dc 325.Pq DRHIST Pc 326or 327.Dq Em D Ns iscrete Em V Ns alue Dc 328.Pq DVHIST Pc , 329with 32 or 64 bit bucket counters, depending on the VOI semantics. 330.It Dv VS_STYPE_TDGST 331A dynamic bucket histogram of VOI values based on the t-digest method 332.Po refer to the t-digest paper in the 333.Sx SEE ALSO 334section below 335.Pc . 336.El 337.Pp 338A 339.Dq visitor software design pattern Ns 340-like scheme is employed to facilitate iterating over a blob's data without 341concern for the blob's structure. 342The data provided to visitor callback functions is encapsulated in 343.Vt struct sb_visit 344per the definition below: 345.Bd -literal -offset indent 346struct sb_visit { 347 struct voistatdata *vs_data; 348 uint32_t tplhash; 349 uint32_t flags; 350 int16_t voi_id; 351 int16_t vs_dsz; 352 enum vsd_dtype voi_dtype : 8; 353 enum vsd_dtype vs_dtype : 8; 354 int8_t vs_stype; 355 uint16_t vs_errs; 356}; 357.Ed 358.Pp 359The 360.Fn stats_tpl_sample_rates 361and 362.Fn stats_tpl_sample_rollthedice 363functions utilize 364.Vt struct stats_tpl_sample_rate 365to encapsulate per-template sample rate information per the definition below: 366.Bd -literal -offset indent 367struct stats_tpl_sample_rate { 368 int32_t tpl_slot_id; 369 uint32_t tpl_sample_pct; 370}; 371.Ed 372.Pp 373The 374.Va tpl_slot_id 375member holds the template's slot ID obtained from 376.Fn stats_tpl_alloc 377or 378.Fn stats_tpl_fetch_allocid . 379The 380.Va tpl_sample_pct 381member holds the template's sample rate as an integer percentage in the range 382[0,100]. 383.Pp 384The 385.Vt stats_tpl_sr_cb_t 386conformant function pointer that is required as the 387.Fa arg1 388of 389.Fn stats_tpl_sample_rates 390is defined as: 391.Bd -literal -offset indent 392enum stats_tpl_sr_cb_action { 393 TPL_SR_UNLOCKED_GET, 394 TPL_SR_RLOCKED_GET, 395 TPL_SR_RUNLOCK, 396 TPL_SR_PUT 397}; 398typedef int (*stats_tpl_sr_cb_t)(enum stats_tpl_sr_cb_action action, 399 struct stats_tpl_sample_rate **rates, int *nrates, void *ctx); 400.Ed 401.Pp 402It is required that a conformant function: 403.Bl -dash 404.It 405Return an appropriate 406.Xr errno 2 407on error, otherwise 0. 408.It 409When called with 410.Qq action == TPL_SR_*_GET , 411return the subsystem's rates list ptr and count, locked or unlocked as 412requested. 413.It 414When called with 415.Qq action == TPL_SR_RUNLOCK , 416unlock the subsystem's rates list ptr and count. 417Pair with a prior 418.Qq action == TPL_SR_RLOCKED_GET 419call. 420.It 421When called with 422.Qq action == TPL_SR_PUT , 423update the subsystem's rates list ptr and count to the sysctl processed values 424and return the inactive list details in 425.Fa rates 426and 427.Fa nrates 428for garbage collection by 429.Fn stats_tpl_sample_rates . 430.El 431.Pp 432Where templates need to be referenced via textual means, for example via a MIB 433variable, the following string based template spec formats can be used: 434.Bl -enum 435.It 436.Qq <tplname> Qc Ns 437:<tplhash> 438.Ns , for example 439.Qq TCP_DEFAULT Qc Ns 440:1731235399 441.It 442.Qq <tplname> Qc 443.Ns , for example 444.Qq TCP_DEFAULT Qc 445.It 446:<tplhash> 447.Ns , for example 448:1731235399 449.El 450.Pp 451The first form is the normative spec format generated by the framework, while 452the second and third forms are convenience formats primarily for user input. 453The use of inverted commas around the template name is optional. 454.Ss MIB Variables 455The in-kernel 456.Nm 457framework exposes the following framework-specific variables in the 458.Va kern.stats 459branch of the 460.Xr sysctl 3 461MIB. 462.Bl -tag -width "templates" 463.It templates 464Read-only CSV list of registered templates in normative template spec form. 465.El 466.Ss Template Management Functions 467The 468.Fn stats_tpl_alloc 469function allocates a new template with the specified unique name and returns its 470runtime-stable template slot ID for use with other API functions. 471The 472.Fa flags 473argument is currently unused. 474.Pp 475The 476.Fn stats_tpl_fetch_allocid 477function returns the runtime-stable template slot ID of any registered template 478matching the specified name and hash. 479.Pp 480The 481.Fn stats_tpl_fetch 482function returns the pointer to the registered template object at the specified 483template slot ID. 484.Pp 485The 486.Fn stats_tpl_id2name 487function returns the name of the registered template object at the specified 488template slot ID. 489.Pp 490The 491.Fn stats_tpl_sample_rates 492function provides a generic handler for template sample rates management and 493reporting via 494.Xr sysctl 3 495MIB variables. 496Subsystems can use this function to create a subsystem-specific 497.Xr SYSCTL_PROC 9 498MIB variable that manages and reports subsystem-specific template sampling 499rates. 500Subsystems must supply a 501.Vt stats_tpl_sr_cb_t 502conformant function pointer as the sysctl's 503.Fa arg1 , 504which is a callback used to interact with the subsystem's stats template sample 505rates list. 506Subsystems can optionally specify the sysctl's 507.Fa arg2 508as non-zero, which causes a zero-initialized allocation of arg2-sized contextual 509memory to be heap-allocated and passed in to all subsystem callbacks made during 510the operation of 511.Fn stats_tpl_sample_rates . 512.Pp 513The 514.Fn stats_tpl_sample_rollthedice 515function makes a weighted random template selection from the supplied array of 516template sampling rates. 517The cumulative percentage of all sampling rates should not exceed 100. 518If no seed is supplied, a PRNG is used to generate a true random number so that 519every selection is independent. 520If a seed is supplied, selection will be made randomly across different seeds, but 521deterministically given the same seed. 522.Pp 523The 524.Fn stats_tpl_add_voistats 525function is used to add a VOI and associated set of statistics to the registered 526template object at the specified template slot ID. 527The set of statistics is passed as an array of 528.Vt struct voistatspec 529which can be initialized using the 530.Fn STATS_VSS_* 531helper macros or manually for non-standard use cases. 532For static 533.Fa vss 534arrays, the 535.Fa nvss 536count of array elements can be determined by passing 537.Fa vss 538to the 539.Fn NVSS 540macro. 541The 542.Dv SB_VOI_RELUPDATE 543flag can be passed to configure the VOI for use with 544.Fn stats_voi_update_rel_<dtype> , 545which entails maintaining an extra 8 bytes of state in the blob at each update. 546.Ss Data Gathering Functions 547The 548.Fn stats_voi_update_abs_<dtype> 549and 550.Fn stats_voi_update_rel_<dtype> 551functions both update all the statistics associated with the VOI identified by 552.Fa voi_id . 553The 554.Dq abs 555call uses 556.Fa voival 557as an absolute value, whereas the 558.Dq rel 559call uses 560.Fa voival 561as a value relative to that of the previous update function call, by adding it 562to the previous value and using the result for the update. 563Relative updates are only possible for VOIs that were added to the template with 564the 565.Dv SB_VOI_RELUPDATE 566flag specified to 567.Fn stats_tpl_add_voistats . 568.Ss Utility Functions 569The 570.Fn stats_blob_alloc 571function allocates and initializes a new blob based on the registered template 572object at the specified template slot ID. 573.Pp 574The 575.Fn stats_blob_init 576function initializes a new blob in an existing memory allocation based on the 577registered template object at the specified template slot ID. 578.Pp 579The 580.Fn stats_blob_clone 581function duplicates the 582.Fa src 583blob into 584.Fa dst , 585leaving only the 586.Va maxsz 587field of 588.Fa dst 589untouched. 590The 591.Dv SB_CLONE_ALLOCDST 592flag can be passed to instruct the function to allocate a new blob of 593appropriate size into which to clone 594.Fa src , 595storing the new pointer in 596.Fa *dst . 597The 598.Dv SB_CLONE_USRDSTNOFAULT 599or 600.Dv SB_CLONE_USRDST 601flags can be set to respectively signal that 602.Xr copyout_nofault 9 603or 604.Xr copyout 9 605should be used because 606.Fa *dst 607is a user space address. 608.Pp 609The 610.Fn stats_blob_snapshot 611function calls 612.Fn stats_blob_clone 613to obtain a copy of 614.Fa src 615and then performs any additional functions required to produce a coherent 616blob snapshot. 617The flags interpreted by 618.Fn stats_blob_clone 619also apply to 620.Fn stats_blob_snapshot . 621Additionally, the 622.Dv SB_CLONE_RSTSRC 623flag can be used to effect a reset of the 624.Fa src 625blob's statistics after a snapshot is successfully taken. 626.Pp 627The 628.Fn stats_blob_destroy 629function destroys a blob previously created with 630.Fn stats_blob_alloc , 631.Fn stats_blob_clone 632or 633.Fn stats_blob_snapshot . 634.Pp 635The 636.Fn stats_blob_visit 637function allows the caller to iterate over the contents of a blob. 638The callback function 639.Fa func 640is called for every VOI and statistic in the blob, passing a 641.Vt struct sb_visit 642and the user context argument 643.Fa usrctx 644to the callback function. 645The 646.Fa sbv 647passed to the callback function may have one or more of the following flags set 648in the 649.Va flags 650struct member to provide useful metadata about the iteration: 651.Dv SB_IT_FIRST_CB , 652.Dv SB_IT_LAST_CB , 653.Dv SB_IT_FIRST_VOI , 654.Dv SB_IT_LAST_VOI , 655.Dv SB_IT_FIRST_VOISTAT , 656.Dv SB_IT_LAST_VOISTAT , 657.Dv SB_IT_NULLVOI 658and 659.Dv SB_IT_NULLVOISTAT . 660Returning a non-zero value from the callback function terminates the iteration. 661.Pp 662The 663.Fn stats_blob_tostr 664renders a string representation of a blob into the 665.Xr sbuf 9 666.Fa buf . 667Currently supported render formats are 668.Dv SB_STRFMT_FREEFORM 669and 670.Dv SB_STRFMT_JSON . 671The 672.Dv SB_TOSTR_OBJDUMP 673flag can be passed to render version specific opaque implementation detail for 674debugging or string-to-binary blob reconstruction purposes. 675The 676.Dv SB_TOSTR_META 677flag can be passed to render template metadata into the string representation, 678using the blob's template hash to lookup the corresponding template. 679.Pp 680The 681.Fn stats_voistatdata_tostr 682renders a string representation of an individual statistic's data into the 683.Xr sbuf 9 684.Fa buf . 685The same render formats supported by the 686.Fn stats_blob_tostr 687function can be specified, and the 688.Fa objdump 689boolean has the same meaning as the 690.Dv SB_TOSTR_OBJDUMP 691flag. 692.Pp 693The 694.Fn stats_voistat_fetch_dptr 695function returns an internal blob pointer to the specified 696.Fa stype 697statistic data for the VOI 698.Fa voi_id . 699The 700.Fn stats_voistat_fetch_<dtype> 701functions are convenience wrappers around 702.Fn stats_voistat_fetch_dptr 703to perform the extraction for simple data types. 704.Sh IMPLEMENTATION NOTES 705The following notes apply to STATS_ABI_V1 format statsblobs. 706.Ss Space-Time Complexity 707Blobs are laid out as three distinct memory regions following the header: 708.Bd -literal -offset indent 709------------------------------------------------------ 710| struct | struct | struct | struct | 711| statsblobv1 | voi [] | voistat [] | voistatdata [] | 712------------------------------------------------------ 713.Ed 714.Pp 715Blobs store VOI and statistic blob state 716.Po 7178 bytes for 718.Vt struct voi 719and 8 bytes for 720.Vt struct voistat 721respectively 722.Pc 723in sparse arrays, using the 724.Fa voi_id 725and 726.Vt enum voi_stype 727as array indices. 728This allows O(1) access to any voi/voistat pair in the blob, at the expense of 7298 bytes of wasted memory per vacant slot for templates which do not specify 730contiguously numbered VOIs and/or statistic types. 731Data storage for statistics is only allocated for non-vacant slot pairs. 732.Pp 733To provide a concrete example, a blob with the following specification: 734.Bl -dash 735.It 736Two VOIs; ID 0 and 2; added to the template in that order 737.It 738VOI 0 is of data type 739.Vt int64_t , 740is configured with 741.Dv SB_VOI_RELUPDATE 742to enable support for relative updates using 743.Fn stats_voi_update_rel_<dtype> , 744and has a 745.Dv VS_STYPE_MIN 746statistic associated with it. 747.It 748VOI 2 is of data type 749.Vt uint32_t 750with 751.Dv VS_STYPE_SUM 752and 753.Dv VS_STYPE_MAX 754statistics associated with it. 755.El 756.Pp 757would have the following memory layout: 758.Bd -literal 759-------------------------------------- 760| header | struct statsblobv1, 32 bytes 761|------------------------------------| 762| voi[0] | struct voi, 8 bytes 763| voi[1] (vacant) | struct voi, 8 bytes 764| voi[2] | struct voi, 8 bytes 765|------------------------------------| 766| voi[2]voistat[VOISTATE] (vacant) | struct voistat, 8 bytes 767| voi[2]voistat[SUM] | struct voistat, 8 bytes 768| voi[2]voistat[MAX] | struct voistat, 8 bytes 769| voi[0]voistat[VOISTATE] | struct voistat, 8 bytes 770| voi[0]voistat[SUM] (vacant) | struct voistat, 8 bytes 771| voi[0]voistat[MAX] (vacant) | struct voistat, 8 bytes 772| voi[0]voistat[MIN] | struct voistat, 8 bytes 773|------------------------------------| 774| voi[2]voistat[SUM]voistatdata | struct voistatdata_int32, 4 bytes 775| voi[2]voistat[MAX]voistatdata | struct voistatdata_int32, 4 bytes 776| voi[0]voistat[VOISTATE]voistatdata | struct voistatdata_numeric, 8 bytes 777| voi[0]voistat[MIN]voistatdata | struct voistatdata_int64, 8 bytes 778-------------------------------------- 779 TOTAL 136 bytes 780.Ed 781.Pp 782When rendered to string format using 783.Fn stats_blob_tostr , 784the 785.Dv SB_STRFMT_FREEFORM 786.Fa fmt 787and the 788.Dv SB_TOSTR_OBJDUMP 789flag, the rendered output is: 790.Bd -literal 791struct statsblobv1@0x8016250a0, abi=1, endian=1, maxsz=136, cursz=136, \\ 792 created=6294158585626144, lastrst=6294158585626144, flags=0x0000, \\ 793 stats_off=56, statsdata_off=112, tplhash=2994056564 794 vois[0]: id=0, name="", flags=0x0001, dtype=INT_S64, voistatmaxid=3, \\ 795 stats_off=80 796 vois[0]stat[0]: stype=VOISTATE, flags=0x0000, dtype=VOISTATE, \\ 797 dsz=8, data_off=120 798 voistatdata: prev=0 799 vois[0]stat[1]: stype=-1 800 vois[0]stat[2]: stype=-1 801 vois[0]stat[3]: stype=MIN, flags=0x0000, dtype=INT_S64, \\ 802 dsz=8, data_off=128 803 voistatdata: 9223372036854775807 804 vois[1]: id=-1 805 vois[2]: id=2, name="", flags=0x0000, dtype=INT_U32, voistatmaxid=2, \\ 806 stats_off=56 807 vois[2]stat[0]: stype=-1 808 vois[2]stat[1]: stype=SUM, flags=0x0000, dtype=INT_U32, dsz=4, \\ 809 data_off=112 810 voistatdata: 0 811 vois[2]stat[2]: stype=MAX, flags=0x0000, dtype=INT_U32, dsz=4, \\ 812 data_off=116 813 voistatdata: 0 814.Ed 815.Pp 816Note: The 817.Qq \e 818present in the rendered output above indicates a manual line break inserted to 819keep the man page within 80 columns and is not part of the actual output. 820.Ss Locking 821The 822.Nm 823framework does not provide any concurrency protection at the individual blob 824level, instead requiring that consumers guarantee mutual exclusion when calling 825API functions that reference a non-template blob. 826.Pp 827The list of templates is protected with a 828.Xr rwlock 9 829in-kernel, and 830.Xr pthread 3 831rw lock in user space to support concurrency between template management and 832blob initialization operations. 833.Sh RETURN VALUES 834.Fn stats_tpl_alloc 835returns a runtime-stable template slot ID on success, or a negative errno on 836failure. 837-EINVAL is returned if any problems are detected with the arguments. 838-EEXIST is returned if an existing template is registered with the same name. 839-ENOMEM is returned if a required memory allocation fails. 840.Pp 841.Fn stats_tpl_fetch_allocid 842returns a runtime-stable template slot ID, or negative errno on failure. 843-ESRCH is returned if no registered template matches the specified name and/or 844hash. 845.Pp 846.Fn stats_tpl_fetch 847returns 0 on success, or ENOENT if an invalid 848.Fa tpl_id 849is specified. 850.Pp 851.Fn stats_tpl_id2name 852returns 0 on success, or an errno on failure. 853EOVERFLOW is returned if the length of 854.Fa buf 855specified by 856.Fa len 857is too short to hold the template's name. 858ENOENT is returned if an invalid 859.Fa tpl_id 860is specified. 861.Pp 862.Fn stats_tpl_sample_rollthedice 863returns a valid template slot id selected from 864.Fa rates 865or -1 if a NULL selection was made, that is no stats collection this roll. 866.Pp 867.Fn stats_tpl_add_voistats 868return 0 on success, or an errno on failure. 869EINVAL is returned if any problems are detected with the arguments. 870EFBIG is returned if the resulting blob would have exceeded the maximum size. 871EOPNOTSUPP is returned if an attempt is made to add more VOI stats to a 872previously configured VOI. 873ENOMEM is returned if a required memory allocation fails. 874.Pp 875.Fn stats_voi_update_abs_<dtype> 876and 877.Fn stats_voi_update_rel_<dtype> 878return 0 on success, or EINVAL if any problems are detected with the arguments. 879.Pp 880.Fn stats_blob_init 881returns 0 on success, or an errno on failure. 882EINVAL is returned if any problems are detected with the arguments. 883EOVERFLOW is returned if the template blob's 884.Fa cursz 885is larger than the 886.Fa maxsz 887of the blob being initialized. 888.Pp 889.Fn stats_blob_alloc 890returns a pointer to a newly allocated and initialized blob based on the 891specified template with slot ID 892.Fa tpl_id , 893or NULL if the memory allocation failed. 894.Pp 895.Fn stats_blob_clone 896and 897.Fn stats_blob_snapshot 898return 0 on success, or an errno on failure. 899EINVAL is returned if any problems are detected with the arguments. 900ENOMEM is returned if the SB_CLONE_ALLOCDST flag was specified and the memory 901allocation for 902.Fa dst 903fails. 904EOVERFLOW is returned if the src blob's 905.Fa cursz 906is larger than the 907.Fa maxsz 908of the 909.Fa dst 910blob. 911.Pp 912.Fn stats_blob_visit 913returns 0 on success, or EINVAL if any problems are detected with the arguments. 914.Pp 915.Fn stats_blob_tostr 916and 917.Fn stats_voistatdata_tostr 918return 0 on success, or an errno on failure. 919EINVAL is returned if any problems are detected with the arguments, otherwise 920any error returned by 921.Fn sbuf_error 922for 923.Fa buf 924is returned. 925.Pp 926.Fn stats_voistat_fetch_dptr 927returns 0 on success, or EINVAL if any problems are detected with the arguments. 928.Pp 929.Fn stats_voistat_fetch_<dtype> 930returns 0 on success, or an errno on failure. 931EINVAL is returned if any problems are detected with the arguments. 932EFTYPE is returned if the requested data type does not match the blob's data 933type for the specified 934.Fa voi_id 935and 936.Fa stype . 937.Sh SEE ALSO 938.Xr errno 2 , 939.Xr arb 3 , 940.Xr qmath 3 , 941.Xr tcp 4 , 942.Xr sbuf 9 943.Rs 944.%A "Ted Dunning" 945.%A "Otmar Ertl" 946.%T "Computing Extremely Accurate Quantiles Using t-digests" 947.%U "https://github.com/tdunning/t-digest/raw/master/docs/t-digest-paper/histo.pdf" 948.Re 949.Sh HISTORY 950The 951.Nm 952framework first appeared in 953.Fx 13.0 . 954.Sh AUTHORS 955.An -nosplit 956The 957.Nm 958framework and this manual page were written by 959.An Lawrence Stewart Aq lstewart@FreeBSD.org 960and sponsored by Netflix, Inc. 961.Sh CAVEATS 962Granularity of timing-dependent network statistics, in particular TCP_RTT, 963depends on the 964.Dv HZ 965timer. 966To minimize the measurement error avoid using HZ lower than 1000. 967