Go to main content

man pages section 9: DDI and DKI Kernel Functions

Exit Print View

Updated: Wednesday, July 27, 2022
 
 

kstat2_create_histogram (9F)

Name

kstat2_create_histogram - create and initialize a new kstat whose data represents a histogram

Synopsis

#include <sys/types.h>
#include <sys/kstat2.h>
kstat2_t *kstat2_create_histogram(const char *ks_pseg[], uint32_t ks_npseg,
    zoneid_t ks_zone, kstat2_nv_hist_type_t type,
    kstat2_nv_metatype_t content_type,
    uint64_t scale, kstat2_nv_metaflag_t md_flags,
    uint64_t *buckets, uint16_t num_buckets,
    uint64_t range_min, uint64_t range_max, uint64_t stepping,
    uint32_t ks_flags, const char *desc, kstat2_metaflag_t ks_mflags);

Interface Level

Solaris DDI specific (Solaris DDI)

Parameters

ks_pseg

The segments used to construct a path which uniquely identifies this kstat. For example, “unix”, “cpu”, “cpu_info”, “1”.

ks_npseg

The number of path segments in the array kstat_pseg.

ks_zone

The ID of the zone in which this kstat will initially be visible. The constant ALL_ZONES is used to make the kstat visible in all zones, and GLOBAL_ZONEID to make it visible only in the global zone. To make the kstat visible in other zones, see kstat2_zone_add(9F) and the description of KSTAT2_FLAG_GZ_VIS later in the man page.

type

Specifies the type of the histogram. The type can be one of the following:

KSTAT2_NVHIST_LINEAR

Linear bucket sizes specified by stepping.

KSTAT2_NVHIST_LOG2

Bucket sizes in increasing powers of 2.

KSTAT2_NVHIST_LOG10

Bucket sizes in increasing powers of 10.

KSTAT2_NVHIST_LOG10_LIN

Bucket ranges in increasing powers of 10 with stepping buckets in each range.

content_type

The type of the values being added to the histogram.

scale

Scaling factor to be applied to the histogram bucket contents. For example, the buckets may contain counts of pages where the content_type indicates bytes, therefore scale would be the page size.

md_flags

Flags which apply to the histogram bucket ranges.

buckets

If not NULL, this array is set as the value of the buckets name-value pair in the kstat's data. This allows to populate a histogram kstat from pre-computed data.

num_buckets

Number of elements in the above array. Must be >0 if buckets is not NULL.

range_min

Upper bound of the first bucket in a linear histogram. All values less than range_min will be in the first bucket.

For log-linear histograms, this specifies the magnitude (power of 10) of the contents of the first bucket.

range_min is ignored for log2 and log10 histograms.

range_max

Lower bound of the last bucket in a linear histogram. All values equal to or greater than range_max up to 2^64-1 will be held in the last bucket of the histogram. If range_max is zero, it is ignored.

For log-linear histograms, this specifies the magnitude of the lower bound of the last bucket, the upper bound being 2^64-1.

range_max is ignored for log2 and log10 histograms.

stepping

Step interval of the buckets in linear histograms.

Number of steps per linear range in log-linear histograms.

stepping is ignored for log2 and log10 histograms.

ks_flags

A bit-field of various flags for this kstat. The only flag which is available for use by kstat providers is:

KSTAT2_FLAG_PERSISTENT

Indicates that this kstat is persistent over time. For persistent kstats, kstat2_delete(9F) simply marks the kstat as dormant; a subsequent kstat2_create() reactivates the kstat. This feature is provided so that statistics are not lost across driver close/open (such as raw disk I/O on a disk with no mounted partitions.) Note that the persistent kstats cannot have their storage managed by the driver since ks_data points to garbage as soon as the driver goes away.

KSTAT2_FLAG_GZ_VIS

Indicates that this kstat is created and made visible in both the global zone and ks_zone, if kz_zone is the ID of a non-global zone.

ks_desc

A brief string describing the purpose of this kstat. This string must be statically allocated as a pointer to it, which is held in the kstat.

ks_mflags

Meta-flags for the kstat as a whole. Either KSTAT2_MF_NONE or one or both of KSTAT2_MF_STABLE and KSTAT2_MF_PRIV.

KSTAT2_MF_NONE

Indicates that this kstat has no meta-flags set.

KSTAT2_MF_STABLE

Indicates that this kstat is considered stable and will not be removed from Oracle Solaris without prior notification.

KSTAT2_MF_PRIV

Indicates that this kstat contains sensitive content which can only be read by users having the appropriate RBAC privilege.

Description

kstat2_create_histogram() function is used in conjunction with kstat2_install(9F) to allocate and initialize a kstat2 structure whose name-value pair data is set up to represent a histogram.

kstat2_create_histogram() function creates a kstat2 structure similar to kstat2_create(9F) function. Once it has created the kstat, it initializes a number of a name-value pair fields (kvals) to support the management of the histogram data. For all histogram types except linear, the array for the "buckets" field is allocated by kstat2_create_histogram() function unless this is supplied as a parameter to the function.

The names of the fields defined in the histogram kstat's data are:

"buckets"   Array containing histogram data
"type"      Histogram type
"range_min" Range of first bucket
"range_max" Range of last bucket
"stepping"  Bucket increment for linear and log-linear histograms

These fields are considered private in the kernel and should not be manipulated directly. A user-space application can access the fields by name through libkstat2(3LIB) function.

Callers can supply a pointer to a driver-managed array of histogram data in buckets. This would typically be used where histogram data is pre-computed by a device and the kstat is used simply to make this visible in structured form to a user-space client.

When kstat2_create_histogram() function returns successfully, kstat2_install(9F) is called to mark the kstat as valid to user-space clients. Unlike other kstats, the ks2_lock field on a histogram kstat must not be set. This field is managed internally by the kstats framework.

Once the kstat is completely initialized, kstat2_install(9F) is used to make the kstat accessible to the outside world.

The content_type argument specifies the type of the values added to the buckets. For more information on the value types, see kstat2_md(9S).

Histogram kstats containing data which might be regarded as sensitive should have the KSTAT_MF_PRIV flag set in metadata. Kstats with this flag set are only visible to and readable by users having the RBAC privilege: kstat_rd_sensitive.

Return Values

If successful, the kstat2_create_histogram() function returns a pointer to the allocated kstat. NULL is returned upon failure.

Context

kstat2_create_histogram() function can be called from user or kernel context.

Examples

Example 1 Creating a kstat for a linear histogram

This example creates a kstat containing at most 10 buckets, in 128- byte increments. The buckets will contain values as follows:

bucket      value-range
-------------------------
0               0
1               1 - 127
2             128 - 255
3             256 - 383
4             384 - 511
5             512 - 639
6             640 - 767
7             768 - 895
8             896 - 1023
9           > 1024
kstat2_t *ksp;
const char *pseg[4] = {"misc", "my_drv", "1", "data_in"};
uint32_t npseg = sizeof (pseg) / sizeof (char *);

ksp = kstat2_create_histogram(pseg, npseg
       ALL_ZONES, KSTAT2_NVHIST_LINEAR,
       KSTAT_NVMT_BYTES, 1, KSTAT2_NVMF_NONE,
       NULL, 0,
       0, 1024, 128,
       "data read by my_drv", KSTAT2_MF_NONE);

if (ksp != NULL) {
       kstat2_install(ksp);
}
Example 2 Creating a kstat for a log2 histogram

This example creates a kstat containing exactly 65 buckets in increments of powers of 2. The buckets will contain values as follows:

bucket      value-range
-------------------------
0              0
1              1
2              2 - 3
3              4 - 7
4              8 - 15
...
63          2^62 - 2^63-1
64          2^63 - 2^64-1

Note that any supplied values for range_min, range_max, and stepping are ignored for this type of histogram.

kstat2_t *ksp;
        const char *pseg[4] = {"misc", "my_drv", "data_in", "2"};
        uint32_t npseg = sizeof (pseg) / sizeof (char *);

ksp = kstat2_create_histogram(pseg, npseg
       ALL_ZONES, KSTAT2_NVHIST_LOG2,
       KSTAT_NVMT_BYTES, 1, KSTAT2_NVMF_NONE,
       NULL, 0,
       0, 0, 0,
       "data read by my_drv", KSTAT2_MF_NONE);

if (ksp != NULL) {
       kstat2_install(ksp);
}
Example 3 Creating a kstat for a log10 histogram

This example creates a kstat containing exactly 21 buckets in increments of powers of 10 representing time values recorded in microseconds. The buckets will contain values as follows:

bucket      value-range
---------------------------
0               0
1               1 - 9
2              10 - 99
3             100 - 999
...
19          10^18 - 10^19-1
20          10^19 - 2^64-1

Note that any supplied values for range_min, range_max, and stepping are ignored for this type of histogram.

kstat2_t *ksp;
const char *pseg[4] = {"misc", "my_drv", "data_in", "3"};
uint32_t npseg = sizeof (pseg) / sizeof (char *);

ksp = kstat2_create_histogram(pseg, npseg
       ALL_ZONES, KSTAT2_NVHIST_LOG10,
       KSTAT_NVMT_T_REL, 1000000, KSTAT2_NVMF_FRACT,
       NULL, 0,
       0, 0, 0,
       "data read by my_drv", KSTAT2_MF_NONE);

if (ksp != NULL) {
       kstat2_install(ksp);
}
Example 4 Creating a kstat for a log10-linear histogram

This type of histogram replicates the behaviour of the DTrace llquantize() function. In this example there are 5 linear steps between each log10 level. The buckets will contain values as follows:

bucket      value-range
---------------------------
0              <100
1               100 - 199
2               200 - 399
3               400 - 599
4               600 - 799
5               800 - 999
6              1000 - 1999
7              2000 - 3999
8              4000 - 5999
9              6000 - 7999
10             8000 - 9999
19            10000 - 19999
20            20000 - 39999
21            40000 - 59999
22            60000 - 79999
23            80000 - 99999
23          >100000
kstat2_t *ksp;
const char *pseg[4] = {"misc", "my_drv", "data_in", "4"};
uint32_t npseg = sizeof (pseg) / sizeof (char *);

ksp = kstat2_create_histogram(pseg, npseg
       ALL_ZONES, KSTAT2_NVHIST_LOG10_LIN,
       KSTAT_NVMT_COUNT, 1, KSTAT2_NVMF_NONE,
       NULL, 0,
       2, 4, 5,
       "data read by my_drv", KSTAT2_MF_NONE);

if (ksp != NULL) {
       kstat2_install(ksp);
}

range_min and range_max are powers of 10 and stepping sets the number of linear steps between each power of 10. The value of stepping must result in steps which are integer values. For example a stepping of 3 will not be valid because no power of 10 divides exactly by 3. A value of 25 is valid because it divides exactly into 100/1000/etc.

See Also

libkstat2(3LIB), user_attr(5), privileges(7), kstat2_create(9F), kstat2_hist_add_value(9F), kstat2_install(9F), kstat2(9S), kstat2_md(9S), dtrace(8)

Notes

If an array of buckets are supplied by the driver in the call to kstat2_create_histogram() function, it is expected that the bucket array will be large enough to accommodate any value later added to the histogram according to the supplied values for range_min, range_max, and stepping.

Changing the values of any of the histogram kstat's data fields after kstat creation is not supported, and will result in undefined behaviour which can cause a system panic.