|  | ============= | 
|  | DM statistics | 
|  | ============= | 
|  |  | 
|  | Device Mapper supports the collection of I/O statistics on user-defined | 
|  | regions of a DM device.	 If no regions are defined no statistics are | 
|  | collected so there isn't any performance impact.  Only bio-based DM | 
|  | devices are currently supported. | 
|  |  | 
|  | Each user-defined region specifies a starting sector, length and step. | 
|  | Individual statistics will be collected for each step-sized area within | 
|  | the range specified. | 
|  |  | 
|  | The I/O statistics counters for each step-sized area of a region are | 
|  | in the same format as `/sys/block/*/stat` or `/proc/diskstats` (see: | 
|  | Documentation/admin-guide/iostats.rst).  But two extra counters (12 and 13) are | 
|  | provided: total time spent reading and writing.  When the histogram | 
|  | argument is used, the 14th parameter is reported that represents the | 
|  | histogram of latencies.  All these counters may be accessed by sending | 
|  | the @stats_print message to the appropriate DM device via dmsetup. | 
|  |  | 
|  | The reported times are in milliseconds and the granularity depends on | 
|  | the kernel ticks.  When the option precise_timestamps is used, the | 
|  | reported times are in nanoseconds. | 
|  |  | 
|  | Each region has a corresponding unique identifier, which we call a | 
|  | region_id, that is assigned when the region is created.	 The region_id | 
|  | must be supplied when querying statistics about the region, deleting the | 
|  | region, etc.  Unique region_ids enable multiple userspace programs to | 
|  | request and process statistics for the same DM device without stepping | 
|  | on each other's data. | 
|  |  | 
|  | The creation of DM statistics will allocate memory via kmalloc or | 
|  | fallback to using vmalloc space.  At most, 1/4 of the overall system | 
|  | memory may be allocated by DM statistics.  The admin can see how much | 
|  | memory is used by reading: | 
|  |  | 
|  | /sys/module/dm_mod/parameters/stats_current_allocated_bytes | 
|  |  | 
|  | Messages | 
|  | ======== | 
|  |  | 
|  | @stats_create <range> <step> [<number_of_optional_arguments> <optional_arguments>...] [<program_id> [<aux_data>]] | 
|  | Create a new region and return the region_id. | 
|  |  | 
|  | <range> | 
|  | "-" | 
|  | whole device | 
|  | "<start_sector>+<length>" | 
|  | a range of <length> 512-byte sectors | 
|  | starting with <start_sector>. | 
|  |  | 
|  | <step> | 
|  | "<area_size>" | 
|  | the range is subdivided into areas each containing | 
|  | <area_size> sectors. | 
|  | "/<number_of_areas>" | 
|  | the range is subdivided into the specified | 
|  | number of areas. | 
|  |  | 
|  | <number_of_optional_arguments> | 
|  | The number of optional arguments | 
|  |  | 
|  | <optional_arguments> | 
|  | The following optional arguments are supported: | 
|  |  | 
|  | precise_timestamps | 
|  | use precise timer with nanosecond resolution | 
|  | instead of the "jiffies" variable.  When this argument is | 
|  | used, the resulting times are in nanoseconds instead of | 
|  | milliseconds.  Precise timestamps are a little bit slower | 
|  | to obtain than jiffies-based timestamps. | 
|  | histogram:n1,n2,n3,n4,... | 
|  | collect histogram of latencies.  The | 
|  | numbers n1, n2, etc are times that represent the boundaries | 
|  | of the histogram.  If precise_timestamps is not used, the | 
|  | times are in milliseconds, otherwise they are in | 
|  | nanoseconds.  For each range, the kernel will report the | 
|  | number of requests that completed within this range. For | 
|  | example, if we use "histogram:10,20,30", the kernel will | 
|  | report four numbers a:b:c:d. a is the number of requests | 
|  | that took 0-10 ms to complete, b is the number of requests | 
|  | that took 10-20 ms to complete, c is the number of requests | 
|  | that took 20-30 ms to complete and d is the number of | 
|  | requests that took more than 30 ms to complete. | 
|  |  | 
|  | <program_id> | 
|  | An optional parameter.  A name that uniquely identifies | 
|  | the userspace owner of the range.  This groups ranges together | 
|  | so that userspace programs can identify the ranges they | 
|  | created and ignore those created by others. | 
|  | The kernel returns this string back in the output of | 
|  | @stats_list message, but it doesn't use it for anything else. | 
|  | If we omit the number of optional arguments, program id must not | 
|  | be a number, otherwise it would be interpreted as the number of | 
|  | optional arguments. | 
|  |  | 
|  | <aux_data> | 
|  | An optional parameter.  A word that provides auxiliary data | 
|  | that is useful to the client program that created the range. | 
|  | The kernel returns this string back in the output of | 
|  | @stats_list message, but it doesn't use this value for anything. | 
|  |  | 
|  | @stats_delete <region_id> | 
|  | Delete the region with the specified id. | 
|  |  | 
|  | <region_id> | 
|  | region_id returned from @stats_create | 
|  |  | 
|  | @stats_clear <region_id> | 
|  | Clear all the counters except the in-flight i/o counters. | 
|  |  | 
|  | <region_id> | 
|  | region_id returned from @stats_create | 
|  |  | 
|  | @stats_list [<program_id>] | 
|  | List all regions registered with @stats_create. | 
|  |  | 
|  | <program_id> | 
|  | An optional parameter. | 
|  | If this parameter is specified, only matching regions | 
|  | are returned. | 
|  | If it is not specified, all regions are returned. | 
|  |  | 
|  | Output format: | 
|  | <region_id>: <start_sector>+<length> <step> <program_id> <aux_data> | 
|  | precise_timestamps histogram:n1,n2,n3,... | 
|  |  | 
|  | The strings "precise_timestamps" and "histogram" are printed only | 
|  | if they were specified when creating the region. | 
|  |  | 
|  | @stats_print <region_id> [<starting_line> <number_of_lines>] | 
|  | Print counters for each step-sized area of a region. | 
|  |  | 
|  | <region_id> | 
|  | region_id returned from @stats_create | 
|  |  | 
|  | <starting_line> | 
|  | The index of the starting line in the output. | 
|  | If omitted, all lines are returned. | 
|  |  | 
|  | <number_of_lines> | 
|  | The number of lines to include in the output. | 
|  | If omitted, all lines are returned. | 
|  |  | 
|  | Output format for each step-sized area of a region: | 
|  |  | 
|  | <start_sector>+<length> | 
|  | counters | 
|  |  | 
|  | The first 11 counters have the same meaning as | 
|  | `/sys/block/*/stat or /proc/diskstats`. | 
|  |  | 
|  | Please refer to Documentation/admin-guide/iostats.rst for details. | 
|  |  | 
|  | 1. the number of reads completed | 
|  | 2. the number of reads merged | 
|  | 3. the number of sectors read | 
|  | 4. the number of milliseconds spent reading | 
|  | 5. the number of writes completed | 
|  | 6. the number of writes merged | 
|  | 7. the number of sectors written | 
|  | 8. the number of milliseconds spent writing | 
|  | 9. the number of I/Os currently in progress | 
|  | 10. the number of milliseconds spent doing I/Os | 
|  | 11. the weighted number of milliseconds spent doing I/Os | 
|  |  | 
|  | Additional counters: | 
|  |  | 
|  | 12. the total time spent reading in milliseconds | 
|  | 13. the total time spent writing in milliseconds | 
|  |  | 
|  | @stats_print_clear <region_id> [<starting_line> <number_of_lines>] | 
|  | Atomically print and then clear all the counters except the | 
|  | in-flight i/o counters.	 Useful when the client consuming the | 
|  | statistics does not want to lose any statistics (those updated | 
|  | between printing and clearing). | 
|  |  | 
|  | <region_id> | 
|  | region_id returned from @stats_create | 
|  |  | 
|  | <starting_line> | 
|  | The index of the starting line in the output. | 
|  | If omitted, all lines are printed and then cleared. | 
|  |  | 
|  | <number_of_lines> | 
|  | The number of lines to process. | 
|  | If omitted, all lines are printed and then cleared. | 
|  |  | 
|  | @stats_set_aux <region_id> <aux_data> | 
|  | Store auxiliary data aux_data for the specified region. | 
|  |  | 
|  | <region_id> | 
|  | region_id returned from @stats_create | 
|  |  | 
|  | <aux_data> | 
|  | The string that identifies data which is useful to the client | 
|  | program that created the range.  The kernel returns this | 
|  | string back in the output of @stats_list message, but it | 
|  | doesn't use this value for anything. | 
|  |  | 
|  | Examples | 
|  | ======== | 
|  |  | 
|  | Subdivide the DM device 'vol' into 100 pieces and start collecting | 
|  | statistics on them:: | 
|  |  | 
|  | dmsetup message vol 0 @stats_create - /100 | 
|  |  | 
|  | Set the auxiliary data string to "foo bar baz" (the escape for each | 
|  | space must also be escaped, otherwise the shell will consume them):: | 
|  |  | 
|  | dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz | 
|  |  | 
|  | List the statistics:: | 
|  |  | 
|  | dmsetup message vol 0 @stats_list | 
|  |  | 
|  | Print the statistics:: | 
|  |  | 
|  | dmsetup message vol 0 @stats_print 0 | 
|  |  | 
|  | Delete the statistics:: | 
|  |  | 
|  | dmsetup message vol 0 @stats_delete 0 |