kstat2_create_histogram - create and initialize a new kstat whose data represents a histogram
#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);
Solaris DDI specific (Solaris DDI)
The segments used to construct a path which uniquely identifies this kstat. For example, “unix”, “cpu”, “cpu_info”, “1”.
The number of path segments in the array kstat_pseg.
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.
Specifies the type of the histogram. The type can be one of the following:
Linear bucket sizes specified by stepping.
Bucket sizes in increasing powers of 2.
Bucket sizes in increasing powers of 10.
Bucket ranges in increasing powers of 10 with stepping buckets in each range.
The type of the values being added to the histogram.
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.
Flags which apply to the histogram bucket ranges.
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.
Number of elements in the above array. Must be >0 if buckets is not NULL.
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.
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.
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.
A bit-field of various flags for this kstat. The only flag which is available for use by kstat providers is:
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.
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.
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.
Meta-flags for the kstat as a whole. Either KSTAT2_MF_NONE or one or both of KSTAT2_MF_STABLE and KSTAT2_MF_PRIV.
Indicates that this kstat has no meta-flags set.
Indicates that this kstat is considered stable and will not be removed from Oracle Solaris without prior notification.
Indicates that this kstat contains sensitive content which can only be read by users having the appropriate RBAC privilege.
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.
If successful, the kstat2_create_histogram() function returns a pointer to the allocated kstat. NULL is returned upon failure.
kstat2_create_histogram() function can be called from user or kernel context.
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.
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)
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.