요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
==============
DMA Test Guide
==============
Andy Shevchenko <[email protected]>
This small document introduces how to test DMA drivers using dmatest module.
The dmatest module tests DMA memcpy, memset, XOR and RAID6 P+Q operations using
various lengths and various offsets into the source and destination buffers. It
will initialize both buffers with a repeatable pattern and verify that the DMA
engine copies the requested region and nothing more. It will also verify that
the bytes aren't swapped around, and that the source buffer isn't modified.
The dmatest module can be configured to test a specific channel. It can also
test multiple channels at the same time, and it can start multiple threads
competing for the same channel.
.. note::
The test suite works only on the channels that have at least one
capability of the following: DMA_MEMCPY (memory-to-memory), DMA_MEMSET
(const-to-memory or memory-to-memory, when emulated), DMA_XOR, DMA_PQ.
.. note::
In case of any related questions use the official mailing list
Part 1 - How to build the test module
=====================================
The menuconfig contains an option that could be found by following path:
Device Drivers -> DMA Engine support -> DMA Test client
In the configuration file the option called CONFIG_DMATEST. The dmatest could
be built as module or inside kernel. Let's consider those cases.
Part 2 - When dmatest is built as a module
==========================================
Example of usage::
% modprobe dmatest timeout=2000 iterations=1 channel=dma0chan0 run=1
...or::
% modprobe dmatest
% echo 2000 > /sys/module/dmatest/parameters/timeout
% echo 1 > /sys/module/dmatest/parameters/iterations
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
% echo 1 > /sys/module/dmatest/parameters/run
...or on the kernel command line::
dmatest.timeout=2000 dmatest.iterations=1 dmatest.channel=dma0chan0 dmatest.run=1
Example of multi-channel test usage (new in the 5.0 kernel)::
% modprobe dmatest
% echo 2000 > /sys/module/dmatest/parameters/timeout
% echo 1 > /sys/module/dmatest/parameters/iterations
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
% echo 1 > /sys/module/dmatest/parameters/run
.. note::
For all tests, starting in the 5.0 kernel, either single- or multi-channel,
the channel parameter(s) must be set after all other parameters. It is at
that time that the existing parameter values are acquired for use by the
thread(s). All other parameters are shared. Therefore, if changes are made
to any of the other parameters, and an additional channel specified, the
(shared) parameters used for all threads will use the new values.
After the channels are specified, each thread is set as pending. All threads
begin execution when the run parameter is set to 1.
.. hint::
A list of available channels can be found by running the following command::
% ls -1 /sys/class/dma/
Once started a message like " dmatest: Added 1 threads using dma0chan0" is
emitted. A thread for that specific channel is created and is now pending, the
pending thread is started once run is to 1.
Note that running a new test will not stop any in progress test.
The following command returns the state of the test. ::
% cat /sys/module/dmatest/parameters/run
To wait for test completion userspace can poll 'run' until it is false, or use
the wait parameter. Specifying 'wait=1' when loading the module causes module
initialization to pause until a test run has completed, while reading
/sys/module/dmatest/parameters/wait waits for any running test to complete
before returning. For example, the following scripts wait for 42 tests
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
waiting is disabled.
Example::
% modprobe dmatest run=1 iterations=42 wait=1
% modprobe -r dmatest
...or::
% modprobe dmatest run=1 iterations=42
% cat /sys/module/dmatest/parameters/wait
% modprobe -r dmatest
Part 3 - When built-in in the kernel
====================================
The module parameters that is supplied to the kernel command line will be used
for the first performed test. After user gets a control, the test could be
re-run with the same or different parameters. For the details see the above
section `Part 2 - When dmatest is built as a module`_.
In both cases the module parameters are used as the actual values for the test
case. You always could check them at run-time by running ::
% grep -H . /sys/module/dmatest/parameters/*
Part 4 - Gathering the test results
===================================
Test results are printed to the kernel log buffer with the format::
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
Example of output::
% dmesg | tail -n 1
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
The message format is unified across the different types of errors. A
number in the parentheses represents additional information, e.g. error
code, error counter, or status. A test thread also emits a summary line at
completion listing the number of tests executed, number that failed, and a
result code.
Example::
% dmesg | tail -n 1
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
The details of a data miscompare error are also emitted, but do not follow the
above format.
Part 5 - Handling channel allocation
====================================
Allocating Channels
-------------------
Channels do not need to be configured prior to starting a test run. Attempting
to run the test without configuring the channels will result in testing any
channels that are available.
Example::
% echo 1 > /sys/module/dmatest/parameters/run
dmatest: No channels configured, continue with any
Channels are registered using the "channel" parameter. Channels can be requested by their
name, once requested, the channel is registered and a pending thread is added to the test list.
Example::
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan2
More channels can be added by repeating the example above.
Reading back the channel parameter will return the name of last channel that was added successfully.
Example::
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan1
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan2
% cat /sys/module/dmatest/parameters/channel
dma0chan2
Another method of requesting channels is to request a channel with an empty string, Doing so
will request all channels available to be tested:
Example::
% echo "" > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan0
dmatest: Added 1 threads using dma0chan3
dmatest: Added 1 threads using dma0chan4
dmatest: Added 1 threads using dma0chan5
dmatest: Added 1 threads using dma0chan6
dmatest: Added 1 threads using dma0chan7
dmatest: Added 1 threads using dma0chan8
At any point during the test configuration, reading the "test_list" parameter will
print the list of currently pending tests.
Example::
% cat /sys/module/dmatest/parameters/test_list
dmatest: 1 threads using dma0chan0
dmatest: 1 threads using dma0chan3
dmatest: 1 threads using dma0chan4
dmatest: 1 threads using dma0chan5
dmatest: 1 threads using dma0chan6
dmatest: 1 threads using dma0chan7
dmatest: 1 threads using dma0chan8
Note: Channels will have to be configured for each test run as channel configurations do not
carry across to the next test run.
Releasing Channels
-------------------
Channels can be freed by setting run to 0.
Example::
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan1
% cat /sys/class/dma/dma0chan1/in_use
1
% echo 0 > /sys/module/dmatest/parameters/run
% cat /sys/class/dma/dma0chan1/in_use
0
Channels allocated by previous test runs are automatically freed when a new
channel is requested after completing a successful test run.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
dmatest 개요와 지원 capability
1-27이 DMA Test Guide는 Andy Shevchenko가 작성했으며, `dmatest` module로 DMA driver를 시험하는 방법을 소개합니다.
`dmatest` module은 여러 길이와 source/destination buffer offset을 사용해 DMA `memcpy`, `memset`, XOR, RAID6 P+Q operation을 시험합니다. 두 buffer를 반복 가능한 pattern으로 초기화한 뒤 DMA engine이 요청한 영역만 복사했는지 검증합니다. byte 순서가 바뀌지 않았는지와 source buffer가 수정되지 않았는지도 확인합니다.
특정 channel 하나를 지정할 수 있고, 여러 channel을 동시에 시험하거나 같은 channel을 두고 경쟁하는 여러 thread를 시작할 수도 있습니다.
test suite는 `DMA_MEMCPY`(memory-to-memory), `DMA_MEMSET`(const-to-memory 또는 emulation 시 memory-to-memory), `DMA_XOR`, `DMA_PQ` 가운데 하나 이상의 capability가 있는 channel에서만 동작합니다.
지원 capability와 buffer 검증 목적을 대응시켰습니다.
관련 질문은 공식 mailing list `[email protected]`를 이용합니다.
Part 1. Test module build
28-37`menuconfig`의 다음 경로에서 DMA Test client option을 찾을 수 있습니다.
The menuconfig contains an option that could be found by following path:
Device Drivers -> DMA Engine support -> DMA Test client
configuration file에서 option 이름은 `CONFIG_DMATEST`입니다. `dmatest`는 module로 build하거나 kernel에 built-in할 수 있으며, 다음 절에서 두 경우를 각각 설명합니다.
Part 2. Module로 build한 경우
38-66module parameter는 `modprobe` 명령에 직접 지정하거나 module을 적재한 뒤 `/sys/module/dmatest/parameters/` 아래 sysfs file에 설정할 수 있습니다. kernel command line에서는 `dmatest.` prefix를 사용합니다.
Example of usage::
% modprobe dmatest timeout=2000 iterations=1 channel=dma0chan0 run=1
...or::
% modprobe dmatest
% echo 2000 > /sys/module/dmatest/parameters/timeout
% echo 1 > /sys/module/dmatest/parameters/iterations
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
% echo 1 > /sys/module/dmatest/parameters/run
...or on the kernel command line::
dmatest.timeout=2000 dmatest.iterations=1 dmatest.channel=dma0chan0 dmatest.run=1
Linux 5.0부터는 `channel` parameter에 여러 channel을 차례로 기록해 multi-channel test를 구성할 수 있습니다.
Example of multi-channel test usage (new in the 5.0 kernel)::
% modprobe dmatest
% echo 2000 > /sys/module/dmatest/parameters/timeout
% echo 1 > /sys/module/dmatest/parameters/iterations
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
% echo 1 > /sys/module/dmatest/parameters/run
Parameter 적용, 실행과 완료 대기
67-110Linux 5.0부터 single-channel과 multi-channel test 모두 `channel` parameter를 다른 모든 parameter 뒤에 설정해야 합니다. channel을 지정하는 순간 해당 thread가 사용할 기존 parameter 값을 가져옵니다. 나머지 parameter는 공유되므로 다른 parameter를 바꾼 뒤 channel을 추가하면 모든 thread가 새 공유 값을 사용합니다. channel 지정 뒤 각 thread는 pending 상태가 되고 `run`을 1로 설정할 때 모두 실행을 시작합니다.
공유 parameter 설정부터 pending thread 실행까지의 순서를 고정했습니다.
사용 가능한 channel 목록은 다음 명령으로 확인할 수 있습니다.
.. hint::
A list of available channels can be found by running the following command::
% ls -1 /sys/class/dma/
시작하면 `dmatest: Added 1 threads using dma0chan0` 같은 message가 출력됩니다. 해당 channel용 thread가 생성되어 pending 상태가 되고, `run`이 1이 되면 시작됩니다. 새 test를 실행해도 진행 중인 test는 중지되지 않습니다.
다음 명령은 test 상태를 반환합니다.
The following command returns the state of the test. ::
% cat /sys/module/dmatest/parameters/run
userspace는 완료를 기다리기 위해 `run`이 false가 될 때까지 poll하거나 `wait` parameter를 사용할 수 있습니다. module load 시 `wait=1`을 지정하면 test run 완료까지 module initialization이 멈춥니다. `/sys/module/dmatest/parameters/wait`를 읽으면 실행 중인 test가 끝날 때까지 read가 반환되지 않습니다. 다음 script는 42개 test가 끝난 뒤 종료합니다. `iterations`가 `infinite`이면 waiting은 비활성화됩니다.
Example::
% modprobe dmatest run=1 iterations=42 wait=1
% modprobe -r dmatest
...or::
% modprobe dmatest run=1 iterations=42
% cat /sys/module/dmatest/parameters/wait
% modprobe -r dmatest
run polling과 두 wait 사용법의 blocking 지점을 비교했습니다.
Part 3. Kernel built-in인 경우
111-123kernel command line에 전달한 module parameter는 처음 수행하는 test에 사용됩니다. user가 control을 얻은 뒤에는 같은 parameter 또는 다른 parameter로 test를 다시 실행할 수 있습니다. 자세한 방법은 `Part 2 - When dmatest is built as a module` 절을 참조합니다.
module과 built-in 두 경우 모두 module parameter가 test case의 실제 값입니다. runtime 값은 다음 명령으로 언제든 확인할 수 있습니다.
In both cases the module parameters are used as the actual values for the test
case. You always could check them at run-time by running ::
% grep -H . /sys/module/dmatest/parameters/*
Part 4. Test 결과 수집
124-149test 결과는 다음 형식으로 kernel log buffer에 출력됩니다.
Test results are printed to the kernel log buffer with the format::
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
출력 예시는 다음과 같습니다.
Example of output::
% dmesg | tail -n 1
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
message 형식은 서로 다른 error type에 공통으로 사용됩니다. 괄호 안 숫자는 error code, error counter, status 같은 추가 정보를 뜻합니다. test thread는 완료 시 실행한 test 수, 실패 수, result code를 나열하는 summary line도 출력합니다.
Example::
% dmesg | tail -n 1
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
data miscompare error의 상세 정보도 출력되지만 위 형식을 따르지는 않습니다.
Part 5. Channel 할당
150-175test run을 시작하기 전에 channel을 반드시 구성할 필요는 없습니다. channel을 구성하지 않고 test를 실행하면 사용 가능한 아무 channel이나 시험합니다.
Example::
% echo 1 > /sys/module/dmatest/parameters/run
dmatest: No channels configured, continue with any
channel은 `channel` parameter로 등록합니다. 이름으로 channel을 요청하면 해당 channel이 등록되고 pending thread가 test list에 추가됩니다.
Example::
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan2
같은 방식을 반복해 더 많은 channel을 추가할 수 있습니다. `channel` parameter를 읽으면 마지막으로 성공적으로 추가된 channel 이름을 반환합니다.
여러 channel, 전체 channel과 test_list
176-215여러 channel을 추가한 뒤 마지막 channel 이름을 읽는 예시는 다음과 같습니다.
Example::
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan1
% echo dma0chan2 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan2
% cat /sys/module/dmatest/parameters/channel
dma0chan2
빈 문자열로 channel을 요청하면 시험할 수 있는 모든 channel을 요청합니다.
Example::
% echo "" > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan0
dmatest: Added 1 threads using dma0chan3
dmatest: Added 1 threads using dma0chan4
dmatest: Added 1 threads using dma0chan5
dmatest: Added 1 threads using dma0chan6
dmatest: Added 1 threads using dma0chan7
dmatest: Added 1 threads using dma0chan8
test configuration 중 언제든 `test_list` parameter를 읽으면 현재 pending test 목록을 출력합니다.
Example::
% cat /sys/module/dmatest/parameters/test_list
dmatest: 1 threads using dma0chan0
dmatest: 1 threads using dma0chan3
dmatest: 1 threads using dma0chan4
dmatest: 1 threads using dma0chan5
dmatest: 1 threads using dma0chan6
dmatest: 1 threads using dma0chan7
dmatest: 1 threads using dma0chan8
channel configuration은 다음 test run으로 이어지지 않으므로 매 test run마다 channel을 다시 구성해야 합니다.
Channel 해제
216-232`run`을 0으로 설정하면 channel을 해제할 수 있습니다.
Example::
% echo dma0chan1 > /sys/module/dmatest/parameters/channel
dmatest: Added 1 threads using dma0chan1
% cat /sys/class/dma/dma0chan1/in_use
1
% echo 0 > /sys/module/dmatest/parameters/run
% cat /sys/class/dma/dma0chan1/in_use
0
성공한 test run이 끝난 뒤 새 channel을 요청하면 이전 test run이 할당했던 channel은 자동으로 해제됩니다.
channel 요청, pending 등록, 실행, 재구성과 해제 동작을 정리했습니다.
요약과 해설
dmatest.rst:1-232`dmatest`는 DMA memcpy, memset, XOR, RAID6 P+Q를 다양한 길이와 offset으로 실행해 요청 영역, byte 순서, source integrity를 검증합니다. Linux 5.0 이후에는 공유 parameter를 먼저 설정하고 channel을 마지막에 지정해 thread를 pending으로 만든 뒤 `run=1`로 동시에 시작해야 합니다. `run` polling이나 `wait`로 완료를 기다리고 kernel log의 통합 result/summary 형식을 확인할 수 있습니다. channel은 이름, 빈 문자열을 통한 전체 선택, 또는 미지정 자동 선택으로 할당하며 각 test run마다 다시 구성하고 `run=0`으로 해제합니다.