1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-05 12:19:48 +03:00
lvm2/libdm/libdm-stats.c

5189 lines
128 KiB
C
Raw Permalink Normal View History

/*
* Copyright (C) 2016 Red Hat, Inc. All rights reserved.
*
* _stats_get_extents_for_file() based in part on filefrag_fiemap() from
* e2fsprogs/misc/filefrag.c. Copyright 2003 by Theodore Ts'o.
*
* This file is part of the device-mapper userspace tools.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libdm/misc/dmlib.h"
#include "libdm/misc/kdev_t.h"
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
#include "math.h" /* log10() */
#include <sys/sysmacros.h>
#include <sys/ioctl.h>
#include <sys/vfs.h> /* fstatfs */
#ifdef __linux__
#include <linux/fs.h> /* FS_IOC_FIEMAP */
#endif
#ifdef HAVE_LINUX_FIEMAP_H
#include <linux/fiemap.h> /* fiemap */
#endif
#ifdef HAVE_LINUX_MAGIC_H
#include <linux/magic.h> /* BTRFS_SUPER_MAGIC */
#endif
#define DM_STATS_REGION_NOT_PRESENT UINT64_MAX
#define DM_STATS_GROUP_NOT_PRESENT DM_STATS_GROUP_NONE
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
#define NSEC_PER_USEC 1000L
#define NSEC_PER_MSEC 1000000L
#define NSEC_PER_SEC 1000000000L
#define PRECISE_ARG "precise_timestamps"
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
#define HISTOGRAM_ARG "histogram:"
#define STATS_ROW_BUF_LEN 4096
#define STATS_MSG_BUF_LEN 1024
#define STATS_FIE_BUF_LEN 2048
#define SECTOR_SHIFT 9L
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
/* Histogram bin */
struct dm_histogram_bin {
uint64_t upper; /* Upper bound on this bin. */
uint64_t count; /* Count value for this bin. */
};
struct dm_histogram {
/* The stats handle this histogram belongs to. */
const struct dm_stats *dms;
/* The region this histogram belongs to. */
const struct dm_stats_region *region;
uint64_t sum; /* Sum of histogram bin counts. */
int nr_bins; /* Number of histogram bins assigned. */
struct dm_histogram_bin bins[];
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
};
/*
* See Documentation/device-mapper/statistics.txt for full descriptions
* of the device-mapper statistics counter fields.
*/
struct dm_stats_counters {
uint64_t reads; /* Num reads completed */
uint64_t reads_merged; /* Num reads merged */
uint64_t read_sectors; /* Num sectors read */
uint64_t read_nsecs; /* Num milliseconds spent reading */
uint64_t writes; /* Num writes completed */
uint64_t writes_merged; /* Num writes merged */
uint64_t write_sectors; /* Num sectors written */
uint64_t write_nsecs; /* Num milliseconds spent writing */
uint64_t io_in_progress; /* Num I/Os currently in progress */
uint64_t io_nsecs; /* Num milliseconds spent doing I/Os */
uint64_t weighted_io_nsecs; /* Weighted num milliseconds doing I/Os */
uint64_t total_read_nsecs; /* Total time spent reading in milliseconds */
uint64_t total_write_nsecs; /* Total time spent writing in milliseconds */
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
struct dm_histogram *histogram; /* Histogram. */
};
struct dm_stats_region {
uint64_t region_id; /* as returned by @stats_list */
uint64_t group_id;
uint64_t start;
uint64_t len;
uint64_t step;
char *program_id;
char *aux_data;
uint64_t timescale; /* precise_timestamps is per-region */
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
struct dm_histogram *bounds; /* histogram configuration */
struct dm_histogram *histogram; /* aggregate cache */
struct dm_stats_counters *counters;
};
struct dm_stats_group {
uint64_t group_id;
const char *alias;
dm_bitset_t regions;
struct dm_histogram *histogram;
};
struct dm_stats {
/* device binding */
int bind_major; /* device major that this dm_stats object is bound to */
int bind_minor; /* device minor that this dm_stats object is bound to */
char *bind_name; /* device-mapper device name */
char *bind_uuid; /* device-mapper UUID */
char *program_id; /* default program_id for this handle */
const char *name; /* cached device_name used for reporting */
struct dm_pool *mem; /* memory pool for region and counter tables */
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
struct dm_pool *hist_mem; /* separate pool for histogram tables */
struct dm_pool *group_mem; /* separate pool for group tables */
uint64_t nr_regions; /* total number of present regions */
uint64_t max_region; /* size of the regions table */
uint64_t interval_ns; /* sampling interval in nanoseconds */
uint64_t timescale; /* default sample value multiplier */
int precise; /* use precise_timestamps when creating regions */
struct dm_stats_region *regions;
struct dm_stats_group *groups;
/* statistics cursor */
uint64_t walk_flags; /* walk control flags */
uint64_t cur_flags;
uint64_t cur_group;
uint64_t cur_region;
uint64_t cur_area;
};
static char *_stats_escape_aux_data(const char *aux_data)
{
size_t aux_data_len = strlen(aux_data);
char *escaped = dm_malloc((3 * aux_data_len + 1) * sizeof(char));
size_t index = 0, i;
if (!escaped) {
log_error("Could not allocate memory for escaped "
"aux_data string.");
return NULL;
}
for (i = 0; i < aux_data_len; i++) {
if (aux_data[i] == ' ') {
escaped[index++] = '\\';
escaped[index++] = ' ';
} else if (aux_data[i] == '\\') {
escaped[index++] = '\\';
escaped[index++] = '\\';
} else if (aux_data[i] == '\t') {
escaped[index++] = '\\';
escaped[index++] = '\t';
} else {
escaped[index++] = aux_data[i];
}
}
escaped[index] = '\0';
return escaped;
}
#define PROC_SELF_COMM "/proc/self/comm"
static char *_program_id_from_proc(void)
{
FILE *comm = NULL;
char buf[STATS_ROW_BUF_LEN];
if (!(comm = fopen(PROC_SELF_COMM, "r")))
return_NULL;
if (!fgets(buf, sizeof(buf), comm)) {
log_error("Could not read from %s", PROC_SELF_COMM);
2015-09-06 01:56:30 +03:00
if (fclose(comm))
stack;
return NULL;
}
if (fclose(comm))
stack;
return dm_strdup(buf);
}
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
static uint64_t _nr_areas(uint64_t len, uint64_t step)
{
/* Default is one area. */
if (!len || !step)
return 1;
/*
* drivers/md/dm-stats.c::message_stats_create()
* A region may be sub-divided into areas with their own counters.
* Any partial area at the end of the region is treated as an
* additional complete area.
*/
return (len + step - 1) / step;
}
static uint64_t _nr_areas_region(struct dm_stats_region *region)
{
return _nr_areas(region->len, region->step);
}
struct dm_stats *dm_stats_create(const char *program_id)
{
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
size_t hist_hint = sizeof(struct dm_histogram_bin);
size_t group_hint = sizeof(struct dm_stats_group);
struct dm_stats *dms = NULL;
if (!(dms = dm_zalloc(sizeof(*dms))))
return_NULL;
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
/* FIXME: better hint. */
if (!(dms->mem = dm_pool_create("stats_pool", 4096))) {
dm_free(dms);
return_NULL;
}
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
if (!(dms->hist_mem = dm_pool_create("histogram_pool", hist_hint)))
goto_bad;
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
if (!(dms->group_mem = dm_pool_create("group_pool", group_hint)))
goto_bad;
if (!program_id || !strlen(program_id))
dms->program_id = _program_id_from_proc();
else
dms->program_id = dm_strdup(program_id);
if (!dms->program_id) {
log_error("Could not allocate memory for program_id");
goto bad;
}
dms->bind_major = -1;
dms->bind_minor = -1;
dms->bind_name = NULL;
dms->bind_uuid = NULL;
dms->name = NULL;
/* by default all regions use msec precision */
dms->timescale = NSEC_PER_MSEC;
dms->precise = 0;
dms->nr_regions = DM_STATS_REGION_NOT_PRESENT;
dms->max_region = DM_STATS_REGION_NOT_PRESENT;
dms->regions = NULL;
/* maintain compatibility with earlier walk version */
dms->walk_flags = dms->cur_flags = DM_STATS_WALK_DEFAULT;
return dms;
2015-09-06 01:56:30 +03:00
bad:
dm_pool_destroy(dms->mem);
if (dms->hist_mem)
dm_pool_destroy(dms->hist_mem);
if (dms->group_mem)
dm_pool_destroy(dms->group_mem);
dm_free(dms);
return NULL;
}
/*
* Test whether the stats region pointed to by region is present.
*/
static int _stats_region_present(const struct dm_stats_region *region)
{
return !(region->region_id == DM_STATS_REGION_NOT_PRESENT);
}
/*
* Test whether the stats group pointed to by group is present.
*/
static int _stats_group_present(const struct dm_stats_group *group)
{
return !(group->group_id == DM_STATS_GROUP_NOT_PRESENT);
}
/*
* Test whether a stats group id is present.
*/
static int _stats_group_id_present(const struct dm_stats *dms, uint64_t id)
{
struct dm_stats_group *group = NULL;
if (id == DM_STATS_GROUP_NOT_PRESENT)
return 0;
if (!dms)
return_0;
if (!dms->regions)
return 0;
if (id > dms->max_region)
return 0;
group = &dms->groups[id];
return _stats_group_present(group);
}
/*
* Test whether the given region_id is a member of any group.
*/
static uint64_t _stats_region_is_grouped(const struct dm_stats* dms,
uint64_t region_id)
{
uint64_t group_id;
if (region_id == DM_STATS_GROUP_NOT_PRESENT)
return 0;
if (!_stats_region_present(&dms->regions[region_id]))
return 0;
group_id = dms->regions[region_id].group_id;
return group_id != DM_STATS_GROUP_NOT_PRESENT;
}
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
static void _stats_histograms_destroy(struct dm_pool *mem,
struct dm_stats_region *region)
{
/* Unpopulated handle. */
if (!region->counters)
return;
/*
2015-09-15 15:17:50 +03:00
* Free everything in the pool back to the first histogram.
*/
if (region->counters[0].histogram)
dm_pool_free(mem, region->counters[0].histogram);
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
}
static void _stats_region_destroy(struct dm_stats_region *region)
{
if (!_stats_region_present(region))
return;
region->start = region->len = region->step = 0;
region->timescale = 0;
/*
* Don't free counters and histogram bounds here: they are
* dropped from the pool along with the corresponding
* regions table.
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
*
* The following objects are all allocated with dm_malloc.
*/
region->counters = NULL;
region->bounds = NULL;
dm_free(region->program_id);
region->program_id = NULL;
dm_free(region->aux_data);
region->aux_data = NULL;
region->region_id = DM_STATS_REGION_NOT_PRESENT;
}
static void _stats_regions_destroy(struct dm_stats *dms)
{
struct dm_pool *mem = dms->mem;
uint64_t i;
if (!dms->regions)
return;
/* walk backwards to obey pool order */
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
for (i = dms->max_region; (i != DM_STATS_REGION_NOT_PRESENT); i--) {
_stats_histograms_destroy(dms->hist_mem, &dms->regions[i]);
_stats_region_destroy(&dms->regions[i]);
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
}
dm_pool_free(mem, dms->regions);
dms->regions = NULL;
}
static void _stats_group_destroy(struct dm_stats_group *group)
{
if (!_stats_group_present(group))
return;
group->histogram = NULL;
if (group->alias) {
dm_free((char *) group->alias);
group->alias = NULL;
}
if (group->regions) {
dm_bitset_destroy(group->regions);
group->regions = NULL;
}
group->group_id = DM_STATS_GROUP_NOT_PRESENT;
}
static void _stats_groups_destroy(struct dm_stats *dms)
{
uint64_t i;
if (!dms->groups)
return;
for (i = dms->max_region; (i != DM_STATS_REGION_NOT_PRESENT); i--)
_stats_group_destroy(&dms->groups[i]);
dm_pool_free(dms->group_mem, dms->groups);
dms->groups = NULL;
}
static int _set_stats_device(struct dm_stats *dms, struct dm_task *dmt)
{
if (dms->bind_name)
return dm_task_set_name(dmt, dms->bind_name);
if (dms->bind_uuid)
return dm_task_set_uuid(dmt, dms->bind_uuid);
if (dms->bind_major > 0)
return dm_task_set_major(dmt, dms->bind_major)
&& dm_task_set_minor(dmt, dms->bind_minor);
return_0;
}
static int _stats_bound(const struct dm_stats *dms)
{
if (dms->bind_major > 0 || dms->bind_name || dms->bind_uuid)
return 1;
/* %p format specifier expects a void pointer. */
log_error("Stats handle at %p is not bound.", (const void *)dms);
return 0;
}
static void _stats_clear_binding(struct dm_stats *dms)
{
if (dms->bind_name)
dm_pool_free(dms->mem, dms->bind_name);
if (dms->bind_uuid)
dm_pool_free(dms->mem, dms->bind_uuid);
dm_free((char *) dms->name);
dms->bind_name = dms->bind_uuid = NULL;
dms->bind_major = dms->bind_minor = -1;
dms->name = NULL;
}
int dm_stats_bind_devno(struct dm_stats *dms, int major, int minor)
{
_stats_clear_binding(dms);
_stats_regions_destroy(dms);
_stats_groups_destroy(dms);
dms->bind_major = major;
dms->bind_minor = minor;
return 1;
}
int dm_stats_bind_name(struct dm_stats *dms, const char *name)
{
_stats_clear_binding(dms);
_stats_regions_destroy(dms);
_stats_groups_destroy(dms);
if (!(dms->bind_name = dm_pool_strdup(dms->mem, name)))
return_0;
return 1;
}
int dm_stats_bind_uuid(struct dm_stats *dms, const char *uuid)
{
_stats_clear_binding(dms);
_stats_regions_destroy(dms);
_stats_groups_destroy(dms);
if (!(dms->bind_uuid = dm_pool_strdup(dms->mem, uuid)))
return_0;
return 1;
}
int dm_stats_bind_from_fd(struct dm_stats *dms, int fd)
{
int major, minor;
struct stat buf;
if (fstat(fd, &buf)) {
log_error("fstat failed for fd %d.", fd);
return 0;
}
major = (int) MAJOR(buf.st_dev);
minor = (int) MINOR(buf.st_dev);
if (!dm_stats_bind_devno(dms, major, minor))
return_0;
return 1;
}
static int _stats_check_precise_timestamps(const struct dm_stats *dms)
{
/* Already checked? */
if (dms && dms->precise)
return 1;
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
return dm_message_supports_precise_timestamps();
}
int dm_stats_driver_supports_precise(void)
{
return _stats_check_precise_timestamps(NULL);
}
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
int dm_stats_driver_supports_histogram(void)
{
return _stats_check_precise_timestamps(NULL);
}
static int _fill_hist_arg(char *hist_arg, size_t hist_len, uint64_t scale,
struct dm_histogram *bounds)
{
int i, l, len = 0, nr_bins;
char *arg = hist_arg;
uint64_t value;
nr_bins = bounds->nr_bins;
for (i = 0; i < nr_bins; i++) {
value = bounds->bins[i].upper / scale;
if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
(i == (nr_bins - 1)) ? "" : ",")) < 0)
return_0;
len += l;
arg += l;
}
return 1;
}
static void *_get_hist_arg(struct dm_histogram *bounds, uint64_t scale,
size_t *len)
{
struct dm_histogram_bin *entry, *bins;
size_t hist_len = 1; /* terminating '\0' */
double value;
entry = bins = bounds->bins;
entry += bounds->nr_bins - 1;
while(entry >= bins) {
value = (double) (entry--)->upper;
/* Use lround to avoid size_t -> double cast warning. */
hist_len += 1 + (size_t) lround(log10(value / scale));
if (entry != bins)
hist_len++; /* ',' */
}
*len = hist_len;
return dm_zalloc(hist_len);
}
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
{
struct dm_histogram_bin *entry, *bins;
size_t hist_len;
char *hist_arg;
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
uint64_t scale;
entry = bins = bounds->bins;
/* Empty histogram is invalid. */
if (!bounds->nr_bins) {
log_error("Cannot format empty histogram description.");
return NULL;
}
/* Validate entries and set *precise if precision < 1ms. */
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
entry += bounds->nr_bins - 1;
while (entry >= bins) {
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
if (entry != bins) {
if (entry->upper < (entry - 1)->upper) {
log_error("Histogram boundaries must be in "
"order of increasing magnitude.");
return 0;
}
}
/*
* Only enable precise_timestamps automatically if any
* value in the histogram bounds uses precision < 1ms.
*/
if (((entry--)->upper % NSEC_PER_MSEC) && !*precise)
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
*precise = 1;
}
scale = (*precise) ? 1 : NSEC_PER_MSEC;
/* Calculate hist_len and allocate a character buffer. */
if (!(hist_arg = _get_hist_arg(bounds, scale, &hist_len))) {
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
log_error("Could not allocate memory for histogram argument.");
return 0;
}
/* Fill hist_arg with boundary strings. */
if (!_fill_hist_arg(hist_arg, hist_len, scale, bounds))
goto_bad;
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
return hist_arg;
2015-09-06 01:56:30 +03:00
bad:
libdm: add latency histogram support Add support for creating, parsing, and reporting dm-stats latency histograms on kernels that support precise_timestamps. Histograms are specified as a series of time values that give the boundaries of the bins into which I/O counts accumulate (with implicit lower and upper bounds on the first and last bins). A new type, struct dm_histogram, is introduced to represent histogram values and bin boundaries. The boundary values may be given as either a string of values (with optional unit suffixes) or as a zero terminated array of uint64_t values expressing boundary times in nanoseconds. A new bounds argument is added to dm_stats_create_region() which accepts a pointer to a struct dm_histogram initialised with bounds values. Histogram data associated with a region is parsed during a call to dm_stats_populate() and used to build a table of histogram values that are pointed to from the containing area's counter set. The histogram for a specified area may then be obtained and interogated for values and properties. This relies on kernel support to provide the boundary values in a @stats_list response: this will be present in 4.3 and 4.2-stable. A check for a minimum driver version of 4.33.0 is implemented to ensure that this is present (4.32.0 has the necessary precise_timestamps and histogram features but is unable to report these via @stats_list). Access methods are provided to retrieve histogram values and bounds as well as simple string representations of the counts and bin boundaries. Methods are also available to return the total count for a histogram and the relative value (as a dm_percent_t) of a specified bin.
2015-08-19 22:39:10 +03:00
log_error("Could not build histogram arguments.");
dm_free(hist_arg);