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