요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
생성과 userspace metadata
statistics.rst:40-103Range·step, precise timestamp, histogram, program_id와 aux_data 문법을 설명합니다.
관리·출력·예제
statistics.rst:104-225Region 삭제·clear·list·print·print_clear·set_aux와 13개 counter 및 dmsetup 사용법을 정리합니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=============
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
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
사용자 정의 region별 I/O 통계
1-39Device Mapper는 DM device에서 사용자가 정의한 region별 I/O statistics 수집을 지원합니다. Region을 정의하지 않으면 통계를 수집하지 않으므로 성능 영향도 없습니다. 현재는 bio-based DM device만 지원합니다.
각 region은 시작 sector, 길이와 step을 지정합니다. 지정 범위 안을 step 크기 area로 나누고 각 area마다 독립적인 statistics를 수집합니다.
하나의 DM device 범위를 region과 step-sized area로 나눠 각 area의 counter를 독립적으로 유지합니다.
각 area의 I/O counter 형식은 `/sys/block/*/stat` 또는 `/proc/diskstats`와 같습니다. 자세한 내용은 `Documentation/admin-guide/iostats.rst`를 참고합니다. 여기에 read와 write에 소비한 total time인 counter 12와 13을 추가합니다. Histogram argument를 사용하면 latency histogram을 나타내는 14번째 parameter도 보고합니다. 이 counter들은 `dmsetup`을 통해 적절한 DM device에 `@stats_print` message를 보내 읽습니다.
기본 보고 시간 단위는 millisecond이며 granularity는 kernel tick에 좌우됩니다. `precise_timestamps` option을 사용하면 nanosecond 단위로 보고합니다.
Region을 만들 때 고유한 `region_id`를 할당합니다. 통계 query, region 삭제 등의 작업에는 이 id를 지정해야 합니다. 고유 id 덕분에 여러 userspace program이 서로의 data를 침범하지 않고 같은 DM device의 통계를 요청·처리할 수 있습니다.
DM statistics 생성은 `kmalloc`으로 memory를 할당하고 필요하면 `vmalloc` 공간으로 fallback합니다. 전체 system memory의 최대 1/4까지 DM statistics가 할당할 수 있습니다. 현재 사용량은 다음 parameter에서 확인합니다.
/sys/module/dm_mod/parameters/stats_current_allocated_bytes
지원 대상, 시간 단위와 memory 제한을 요약합니다.
@stats_create 범위와 step
40-60`@stats_create`는 새 region을 만들고 그 `region_id`를 반환합니다.
@stats_create <range> <step> [<number_of_optional_arguments> <optional_arguments>...] [<program_id> [<aux_data>]]
`<range>`에 `-`를 쓰면 device 전체를 뜻합니다. `<start_sector>+<length>` 형식은 `<start_sector>`에서 시작하는 `<length>`개의 512-byte sector 범위를 뜻합니다.
`<step>`에 `<area_size>`를 쓰면 range를 각각 `<area_size>` sector인 area로 나눕니다. `/<number_of_areas>`를 쓰면 지정한 개수의 area로 range를 나눕니다.
Range 선택과 area 분할 방식을 독립적으로 지정합니다.
Range와 step을 해석해 area counter 집합을 만들고 고유 id를 반환합니다.
정밀 timestamp와 latency histogram
61-86`<number_of_optional_arguments>`는 뒤따르는 optional argument 수입니다. 지원 option은 `precise_timestamps`와 `histogram:n1,n2,n3,n4,...`입니다.
`precise_timestamps`는 `jiffies` 대신 nanosecond resolution의 precise timer를 사용합니다. 결과 시간도 millisecond 대신 nanosecond가 됩니다. 정밀 timestamp는 jiffies 기반 timestamp보다 얻는 비용이 조금 더 큽니다.
`histogram:n1,n2,n3,n4,...`는 latency histogram을 수집합니다. `n1`, `n2` 등의 숫자가 bucket boundary입니다. `precise_timestamps`를 쓰지 않으면 millisecond, 쓰면 nanosecond 단위입니다. Kernel은 각 범위 안에서 완료된 request 수를 보고합니다.
시간 측정 방식과 latency 분포 수집을 선택합니다.
예를 들어 `histogram:10,20,30`은 네 숫자 `a:b:c:d`를 보고합니다. `a`는 0~10 ms, `b`는 10~20 ms, `c`는 20~30 ms에 완료된 request 수이며 `d`는 30 ms보다 오래 걸린 request 수입니다. `precise_timestamps`를 함께 쓰면 같은 boundary 숫자의 단위는 ns입니다.
세 boundary는 네 latency 구간을 만듭니다.
program_id와 aux_data
87-103`<program_id>`는 region의 userspace owner를 고유하게 식별하는 선택적 이름입니다. Region을 group으로 묶어 userspace program이 자신이 만든 range를 식별하고 다른 program의 range를 무시할 수 있게 합니다.
Kernel은 이 문자열을 `@stats_list` 출력에 돌려주지만 다른 용도로 사용하지 않습니다. Optional argument 개수를 생략한 경우 program id는 숫자일 수 없습니다. 숫자라면 optional argument 개수로 해석되기 때문입니다.
`<aux_data>`는 region을 만든 client program에 유용한 보조 data를 담는 선택적 한 단어입니다. Kernel은 이 값도 `@stats_list` 출력에 돌려줄 뿐 다른 용도로 사용하지 않습니다.
Kernel이 보존·반환하지만 의미를 해석하지 않는 두 문자열입니다.
Region 삭제·clear·list
104-131`@stats_delete`는 `@stats_create`가 반환한 id의 region을 삭제합니다.
@stats_delete <region_id>
`@stats_clear`는 in-flight I/O counter를 제외한 모든 counter를 지웁니다.
@stats_clear <region_id>
`@stats_list`는 `@stats_create`로 등록한 모든 region을 나열합니다. 선택적 `<program_id>`를 지정하면 일치하는 region만 반환하고, 생략하면 모두 반환합니다.
@stats_list [<program_id>]
List 출력은 region id, range, step, program id, aux data와 생성 시 선택한 timestamp·histogram option을 포함합니다.
Output format:
<region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
precise_timestamps histogram:n1,n2,n3,...
`precise_timestamps`와 `histogram` 문자열은 region을 만들 때 실제로 지정한 경우에만 출력됩니다.
고유 region id를 중심으로 수명주기와 counter 상태를 제어합니다.
Area counter 출력과 번호별 의미
132-172`@stats_print`는 region의 각 step-sized area counter를 출력합니다. 선택적인 `<starting_line>`은 출력 시작 line index이며, `<number_of_lines>`는 포함할 line 수입니다. 둘을 생략하면 모든 line을 반환합니다.
@stats_print <region_id> [<starting_line> <number_of_lines>]
각 area 출력은 `<start_sector>+<length>` 뒤에 counter가 이어지는 형식입니다. 처음 11개 counter는 `/sys/block/*/stat` 또는 `/proc/diskstats`와 같은 의미이며 `Documentation/admin-guide/iostats.rst`에 자세히 설명되어 있습니다.
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.
기본 11개 block I/O counter에 누적 read·write total time 두 개를 추가합니다.
손실 없는 원자적 print와 clear
173-189`@stats_print_clear`는 counter를 원자적으로 출력한 뒤 in-flight I/O counter를 제외한 나머지를 지웁니다. Print와 clear 사이에 갱신되는 statistics를 잃고 싶지 않은 client에 유용합니다.
@stats_print_clear <region_id> [<starting_line> <number_of_lines>]
`<starting_line>`은 출력 시작 index이고, `<number_of_lines>`는 처리할 line 수입니다. 생략하면 모든 line을 출력한 다음 clear합니다.
하나의 operation으로 snapshot과 reset을 묶어 print와 clear 사이의 update 손실을 막습니다.
Region의 auxiliary data 변경
190-200`@stats_set_aux <region_id> <aux_data>`는 지정한 region에 auxiliary data를 저장합니다.
@stats_set_aux <region_id> <aux_data>
`<region_id>`는 `@stats_create`가 반환한 id입니다. `<aux_data>`는 range를 만든 client program에 유용한 data를 식별하는 문자열입니다. Kernel은 이 문자열을 `@stats_list` 출력에 돌려주지만 값 자체를 해석하거나 다른 용도로 사용하지 않습니다.
Userspace가 정한 문자열을 kernel이 region metadata로 보존해 list 결과에 다시 제공합니다.
100개 area 생성부터 삭제까지
201-225DM device `vol` 전체를 100개 area로 나누고 통계 수집을 시작합니다.
dmsetup message vol 0 @stats_create - /100
Auxiliary data를 `foo bar baz`로 설정합니다. 각 space의 escape 자체도 escape해야 하며, 그렇지 않으면 shell이 이를 소비합니다.
dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz
등록 region을 나열하고 region 0의 statistics를 출력한 뒤 삭제합니다.
dmsetup message vol 0 @stats_list
dmsetup message vol 0 @stats_print 0
dmsetup message vol 0 @stats_delete 0
전체 device를 100개 area로 만들고 metadata 설정, 조회, 출력, 삭제 순으로 진행합니다.
각 dmsetup message가 statistics region에 수행하는 작업입니다.
Region과 counter 모델
statistics.rst:1-39시작 sector, 길이와 step으로 area를 나누고 region_id별 block I/O 통계를 수집합니다.