요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===================================================
Using Coresight for Kernel panic and Watchdog reset
===================================================
Introduction
------------
This documentation is about using Linux coresight trace support to
debug kernel panic and watchdog reset scenarios.
Coresight trace during Kernel panic
-----------------------------------
From the coresight driver point of view, addressing the kernel panic
situation has four main requirements.
a. Support for allocation of trace buffer pages from reserved memory area.
Platform can advertise this using a new device tree property added to
relevant coresight nodes.
b. Support for stopping coresight blocks at the time of panic
c. Saving required metadata in the specified format
d. Support for reading trace data captured at the time of panic
Allocation of trace buffer pages from reserved RAM
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A new optional device tree property "memory-region" is added to the
Coresight TMC device nodes, that would give the base address and size of trace
buffer.
Static allocation of trace buffers would ensure that both IOMMU enabled
and disabled cases are handled. Also, platforms that support persistent
RAM will allow users to read trace data in the subsequent boot without
booting the crashdump kernel.
Note:
For ETR sink devices, this reserved region will be used for both trace
capture and trace data retrieval.
For ETF sink devices, internal SRAM would be used for trace capture,
and they would be synced to reserved region for retrieval.
Disabling coresight blocks at the time of panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to avoid the situation of losing relevant trace data after a
kernel panic, it would be desirable to stop the coresight blocks at the
time of panic.
This can be achieved by configuring the comparator, CTI and sink
devices as below::
Trigger on panic
Comparator --->External out --->CTI -->External In---->ETR/ETF stop
Saving metadata at the time of kernel panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Coresight metadata involves all additional data that are required for a
successful trace decode in addition to the trace data. This involves
ETR/ETF/ETB register snapshot etc.
A new optional device property "memory-region" is added to
the ETR/ETF/ETB device nodes for this.
Reading trace data captured at the time of panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Trace data captured at the time of panic, can be read from rebooted kernel
or from crashdump kernel using a special device file /dev/crash_tmc_xxx.
This device file is created only when there is a valid crashdata available.
General flow of trace capture and decode in case of kernel panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Enable source and sink on all the cores using the sysfs interface.
ETR sinks should have trace buffers allocated from reserved memory,
by selecting "resrv" buffer mode from sysfs.
2. Run relevant tests.
3. On a kernel panic, all coresight blocks are disabled, necessary
metadata is synced by kernel panic handler.
System would eventually reboot or boot a crashdump kernel.
4. For platforms that supports crashdump kernel, raw trace data can be
dumped using the coresight sysfs interface from the crashdump kernel
itself. Persistent RAM is not a requirement in this case.
5. For platforms that supports persistent RAM, trace data can be dumped
using the coresight sysfs interface in the subsequent Linux boot.
Crashdump kernel is not a requirement in this case. Persistent RAM
ensures that trace data is intact across reboot.
Coresight trace during Watchdog reset
-------------------------------------
The main difference between addressing the watchdog reset and kernel panic
case are below,
a. Saving coresight metadata need to be taken care by the
SCP(system control processor) firmware in the specified format,
instead of kernel.
b. Reserved memory region given by firmware for trace buffer and metadata
has to be in persistent RAM.
Note: This is a requirement for watchdog reset case but optional
in kernel panic case.
Watchdog reset can be supported only on platforms that meet the above
two requirements.
Sample commands for testing a Kernel panic case with ETR sink
-------------------------------------------------------------
1. Boot Linux kernel with "crash_kexec_post_notifiers" added to the kernel
bootargs. This is mandatory if the user would like to read the tracedata
from the crashdump kernel.
2. Enable the preloaded ETM configuration::
#echo 1 > /sys/kernel/config/cs-syscfg/configurations/panicstop/enable
3. Configure CTI using sysfs interface::
#./cti_setup.sh
#cat cti_setup.sh
cd /sys/bus/coresight/devices/
ap_cti_config () {
#ETM trig out[0] trigger to Channel 0
echo 0 4 > channels/trigin_attach
}
etf_cti_config () {
#ETF Flush in trigger from Channel 0
echo 0 1 > channels/trigout_attach
echo 1 > channels/trig_filter_enable
}
etr_cti_config () {
#ETR Flush in from Channel 0
echo 0 1 > channels/trigout_attach
echo 1 > channels/trig_filter_enable
}
ctidevs=`find . -name "cti*"`
for i in $ctidevs
do
cd $i
connection=`find . -name "ete*"`
if [ ! -z "$connection" ]
then
echo "AP CTI config for $i"
ap_cti_config
fi
connection=`find . -name "tmc_etf*"`
if [ ! -z "$connection" ]
then
echo "ETF CTI config for $i"
etf_cti_config
fi
connection=`find . -name "tmc_etr*"`
if [ ! -z "$connection" ]
then
echo "ETR CTI config for $i"
etr_cti_config
fi
cd ..
done
Note: CTI connections are SOC specific and hence the above script is
added just for reference.
4. Choose reserved buffer mode for ETR buffer::
#echo "resrv" > /sys/bus/coresight/devices/tmc_etr0/buf_mode_preferred
5. Enable stop on flush trigger configuration::
#echo 1 > /sys/bus/coresight/devices/tmc_etr0/stop_on_flush
6. Start Coresight tracing on cores 1 and 2 using sysfs interface
7. Run some application on core 1::
#taskset -c 1 dd if=/dev/urandom of=/dev/null &
8. Invoke kernel panic on core 2::
#echo 1 > /proc/sys/kernel/panic
#taskset -c 2 echo c > /proc/sysrq-trigger
9. From rebooted kernel or crashdump kernel, read crashdata::
#dd if=/dev/crash_tmc_etr0 of=/trace/cstrace.bin
10. Run opencsd decoder tools/scripts to generate the instruction trace.
Sample instruction trace dump
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Core1 dump::
A etm4_enable_hw: ffff800008ae1dd4
CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
I etm4_enable_hw: ffff800008ae1dd4:
d503201f nop
I etm4_enable_hw: ffff800008ae1dd8:
d503201f nop
I etm4_enable_hw: ffff800008ae1ddc:
d503201f nop
I etm4_enable_hw: ffff800008ae1de0:
d503201f nop
I etm4_enable_hw: ffff800008ae1de4:
d503201f nop
I etm4_enable_hw: ffff800008ae1de8:
d503233f paciasp
I etm4_enable_hw: ffff800008ae1dec:
a9be7bfd stp x29, x30, [sp, #-32]!
I etm4_enable_hw: ffff800008ae1df0:
910003fd mov x29, sp
I etm4_enable_hw: ffff800008ae1df4:
a90153f3 stp x19, x20, [sp, #16]
I etm4_enable_hw: ffff800008ae1df8:
2a0003f4 mov w20, w0
I etm4_enable_hw: ffff800008ae1dfc:
900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
I etm4_enable_hw: ffff800008ae1e00:
910f4273 add x19, x19, #0x3d0
I etm4_enable_hw: ffff800008ae1e04:
f8747a60 ldr x0, [x19, x20, lsl #3]
E etm4_enable_hw: ffff800008ae1e08:
b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
I 149.039572921 etm4_enable_hw: ffff800008ae1e30:
a94153f3 ldp x19, x20, [sp, #16]
I 149.039572921 etm4_enable_hw: ffff800008ae1e34:
52800000 mov w0, #0x0 // #0
I 149.039572921 etm4_enable_hw: ffff800008ae1e38:
a8c27bfd ldp x29, x30, [sp], #32
..snip
149.052324811 chacha_block_generic: ffff800008642d80:
9100a3e0 add x0,
I 149.052324811 chacha_block_generic: ffff800008642d84:
b86178a2 ldr w2, [x5, x1, lsl #2]
I 149.052324811 chacha_block_generic: ffff800008642d88:
8b010803 add x3, x0, x1, lsl #2
I 149.052324811 chacha_block_generic: ffff800008642d8c:
b85fc063 ldur w3, [x3, #-4]
I 149.052324811 chacha_block_generic: ffff800008642d90:
0b030042 add w2, w2, w3
I 149.052324811 chacha_block_generic: ffff800008642d94:
b8217882 str w2, [x4, x1, lsl #2]
I 149.052324811 chacha_block_generic: ffff800008642d98:
91000421 add x1, x1, #0x1
I 149.052324811 chacha_block_generic: ffff800008642d9c:
f100443f cmp x1, #0x11
Core 2 dump::
A etm4_enable_hw: ffff800008ae1dd4
CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
I etm4_enable_hw: ffff800008ae1dd4:
d503201f nop
I etm4_enable_hw: ffff800008ae1dd8:
d503201f nop
I etm4_enable_hw: ffff800008ae1ddc:
d503201f nop
I etm4_enable_hw: ffff800008ae1de0:
d503201f nop
I etm4_enable_hw: ffff800008ae1de4:
d503201f nop
I etm4_enable_hw: ffff800008ae1de8:
d503233f paciasp
I etm4_enable_hw: ffff800008ae1dec:
a9be7bfd stp x29, x30, [sp, #-32]!
I etm4_enable_hw: ffff800008ae1df0:
910003fd mov x29, sp
I etm4_enable_hw: ffff800008ae1df4:
a90153f3 stp x19, x20, [sp, #16]
I etm4_enable_hw: ffff800008ae1df8:
2a0003f4 mov w20, w0
I etm4_enable_hw: ffff800008ae1dfc:
900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
I etm4_enable_hw: ffff800008ae1e00:
910f4273 add x19, x19, #0x3d0
I etm4_enable_hw: ffff800008ae1e04:
f8747a60 ldr x0, [x19, x20, lsl #3]
E etm4_enable_hw: ffff800008ae1e08:
b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
I 149.046243445 etm4_enable_hw: ffff800008ae1e30:
a94153f3 ldp x19, x20, [sp, #16]
I 149.046243445 etm4_enable_hw: ffff800008ae1e34:
52800000 mov w0, #0x0 // #0
I 149.046243445 etm4_enable_hw: ffff800008ae1e38:
a8c27bfd ldp x29, x30, [sp], #32
I 149.046243445 etm4_enable_hw: ffff800008ae1e3c:
d50323bf autiasp
E 149.046243445 etm4_enable_hw: ffff800008ae1e40:
d65f03c0 ret
A ete_sysreg_write: ffff800008adfa18
..snip
I 149.05422547 panic: ffff800008096300:
a90363f7 stp x23, x24, [sp, #48]
I 149.05422547 panic: ffff800008096304:
6b00003f cmp w1, w0
I 149.05422547 panic: ffff800008096308:
3a411804 ccmn w0, #0x1, #0x4, ne // ne = any
N 149.05422547 panic: ffff80000809630c:
540001e0 b.eq ffff800008096348 <panic+0xe0> // b.none
I 149.05422547 panic: ffff800008096310:
f90023f9 str x25, [sp, #64]
E 149.05422547 panic: ffff800008096314:
97fe44ef bl ffff8000080276d0 <panic_smp_self_stop>
A panic: ffff80000809634c
I 149.05422547 panic: ffff80000809634c:
910102d5 add x21, x22, #0x40
I 149.05422547 panic: ffff800008096350:
52800020 mov w0, #0x1 // #1
E 149.05422547 panic: ffff800008096354:
94166b8b bl ffff800008631180 <bust_spinlocks>
N 149.054225518 bust_spinlocks: ffff800008631180:
340000c0 cbz w0, ffff800008631198 <bust_spinlocks+0x18>
I 149.054225518 bust_spinlocks: ffff800008631184:
f000a321 adrp x1, ffff800009a98000 <pbufs.0+0xbb8>
I 149.054225518 bust_spinlocks: ffff800008631188:
b9405c20 ldr w0, [x1, #92]
I 149.054225518 bust_spinlocks: ffff80000863118c:
11000400 add w0, w0, #0x1
I 149.054225518 bust_spinlocks: ffff800008631190:
b9005c20 str w0, [x1, #92]
E 149.054225518 bust_spinlocks: ffff800008631194:
d65f03c0 ret
A panic: ffff800008096358
Perf based testing
------------------
Starting perf session
~~~~~~~~~~~~~~~~~~~~~
ETF::
perf record -e cs_etm/panicstop,@tmc_etf1/ -C 1
perf record -e cs_etm/panicstop,@tmc_etf2/ -C 2
ETR::
perf record -e cs_etm/panicstop,@tmc_etr0/ -C 1,2
Reading trace data after panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Same sysfs based method explained above can be used to retrieve and
decode the trace data after the reboot on kernel panic.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
목적과 네 가지 요구 사항
1-23이 문서는 Linux CoreSight trace 지원을 이용해 kernel panic과 watchdog reset 상황을 디버깅하는 방법을 설명한다.
CoreSight driver 관점에서 kernel panic을 다루려면 네 가지가 필요하다. 예약 메모리에서 trace buffer page를 할당해야 하며, platform은 관련 CoreSight node에 추가된 새 Device Tree property로 이를 알릴 수 있어야 한다.
panic이 발생하는 시점에 CoreSight block을 정지할 수 있어야 하고, 필요한 metadata를 지정 형식으로 저장해야 하며, panic 시점에 캡처한 trace data를 다시 읽을 수 있어야 한다.
드라이버가 panic 이후에도 해독 가능한 추적을 남기기 위한 네 가지 조건이다.
===================================================
Using Coresight for Kernel panic and Watchdog reset
===================================================
Introduction
------------
This documentation is about using Linux coresight trace support to
debug kernel panic and watchdog reset scenarios.
Coresight trace during Kernel panic
-----------------------------------
From the coresight driver point of view, addressing the kernel panic
situation has four main requirements.
a. Support for allocation of trace buffer pages from reserved memory area.
Platform can advertise this using a new device tree property added to
relevant coresight nodes.
b. Support for stopping coresight blocks at the time of panic
c. Saving required metadata in the specified format
d. Support for reading trace data captured at the time of panic
예약 버퍼, 정지, metadata와 crash device
24-68CoreSight TMC Device Tree node에는 선택적 `memory-region` property가 추가된다. 이 property가 trace buffer의 base address와 size를 제공한다.
trace buffer를 정적으로 할당하면 IOMMU가 활성화된 경우와 비활성화된 경우를 모두 처리할 수 있다. persistent RAM을 지원하는 platform에서는 crashdump kernel을 부팅하지 않아도 다음 부팅에서 trace data를 읽을 수 있다.
ETR sink는 예약 영역을 trace 캡처와 trace data 회수에 모두 사용한다. ETF sink는 내부 SRAM에 trace를 캡처한 뒤 회수를 위해 예약 영역으로 동기화한다.
kernel panic 뒤에도 관련 trace data를 잃지 않으려면 panic 시점에 CoreSight block을 정지하는 편이 바람직하다. comparator, CTI, sink를 연결해 panic trigger가 comparator의 external output과 CTI external input을 지나 ETR 또는 ETF의 stop 동작으로 전달되게 구성한다.
CoreSight metadata는 trace data 외에 성공적인 trace decode에 필요한 모든 추가 데이터다. 여기에는 ETR, ETF, ETB register snapshot 등이 포함된다. 이를 위해 ETR, ETF, ETB device node에도 선택적 `memory-region` property를 둔다.
panic 시점에 캡처한 trace data는 재부팅한 kernel이나 crashdump kernel에서 특수 device file `/dev/crash_tmc_xxx`를 통해 읽는다. 이 파일은 유효한 crashdata가 있을 때만 생성된다.
ETR과 ETF는 캡처 위치가 다르지만 회수 가능한 데이터를 예약 영역에 남긴다.
원문의 ASCII 경로를 같은 의미의 구조화 흐름으로 다시 그렸다.
trace 해독에 필요한 데이터와 노출 조건을 구분한다.
Allocation of trace buffer pages from reserved RAM
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A new optional device tree property "memory-region" is added to the
Coresight TMC device nodes, that would give the base address and size of trace
buffer.
Static allocation of trace buffers would ensure that both IOMMU enabled
and disabled cases are handled. Also, platforms that support persistent
RAM will allow users to read trace data in the subsequent boot without
booting the crashdump kernel.
Note:
For ETR sink devices, this reserved region will be used for both trace
capture and trace data retrieval.
For ETF sink devices, internal SRAM would be used for trace capture,
and they would be synced to reserved region for retrieval.
Disabling coresight blocks at the time of panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to avoid the situation of losing relevant trace data after a
kernel panic, it would be desirable to stop the coresight blocks at the
time of panic.
This can be achieved by configuring the comparator, CTI and sink
devices as below::
Trigger on panic
Comparator --->External out --->CTI -->External In---->ETR/ETF stop
Saving metadata at the time of kernel panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Coresight metadata involves all additional data that are required for a
successful trace decode in addition to the trace data. This involves
ETR/ETF/ETB register snapshot etc.
A new optional device property "memory-region" is added to
the ETR/ETF/ETB device nodes for this.
Reading trace data captured at the time of panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Trace data captured at the time of panic, can be read from rebooted kernel
or from crashdump kernel using a special device file /dev/crash_tmc_xxx.
This device file is created only when there is a valid crashdata available.
Panic 캡처 흐름과 watchdog 차이
69-108kernel panic의 일반적인 캡처 및 해독 흐름은 다음과 같다. 먼저 sysfs interface로 모든 core의 source와 sink를 활성화한다. ETR sink는 sysfs에서 `resrv` buffer mode를 선택해 예약 메모리에서 trace buffer를 할당받아야 한다.
관련 test를 실행한다. kernel panic이 발생하면 모든 CoreSight block을 비활성화하고 panic handler가 필요한 metadata를 동기화한다. 그 뒤 system은 재부팅하거나 crashdump kernel을 부팅한다.
crashdump kernel을 지원하는 platform은 그 kernel 자체에서 CoreSight sysfs interface로 raw trace data를 dump할 수 있으므로 persistent RAM이 필수는 아니다.
persistent RAM을 지원하는 platform은 다음 Linux 부팅에서 CoreSight sysfs interface로 trace data를 dump할 수 있다. 이 경우 crashdump kernel이 필요 없고, persistent RAM이 재부팅을 거쳐서도 trace data를 온전히 보존한다.
watchdog reset은 kernel panic과 두 가지가 다르다. CoreSight metadata 저장은 kernel 대신 SCP(System Control Processor) firmware가 지정 형식에 맞춰 수행해야 한다.
firmware가 trace buffer와 metadata용으로 제공하는 예약 메모리 영역은 persistent RAM이어야 한다. 이는 watchdog reset에서는 필수지만 kernel panic에서는 선택 사항이다. 따라서 이 두 조건을 모두 충족하는 platform에서만 watchdog reset 추적을 지원할 수 있다.
source 활성화부터 재부팅 이후 해독까지의 순서다.
platform 기능에 따라 crashdump kernel 또는 persistent RAM 경로를 택한다.
metadata 주체와 메모리 지속성 요구가 다르다.
General flow of trace capture and decode in case of kernel panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Enable source and sink on all the cores using the sysfs interface.
ETR sinks should have trace buffers allocated from reserved memory,
by selecting "resrv" buffer mode from sysfs.
2. Run relevant tests.
3. On a kernel panic, all coresight blocks are disabled, necessary
metadata is synced by kernel panic handler.
System would eventually reboot or boot a crashdump kernel.
4. For platforms that supports crashdump kernel, raw trace data can be
dumped using the coresight sysfs interface from the crashdump kernel
itself. Persistent RAM is not a requirement in this case.
5. For platforms that supports persistent RAM, trace data can be dumped
using the coresight sysfs interface in the subsequent Linux boot.
Crashdump kernel is not a requirement in this case. Persistent RAM
ensures that trace data is intact across reboot.
Coresight trace during Watchdog reset
-------------------------------------
The main difference between addressing the watchdog reset and kernel panic
case are below,
a. Saving coresight metadata need to be taken care by the
SCP(system control processor) firmware in the specified format,
instead of kernel.
b. Reserved memory region given by firmware for trace buffer and metadata
has to be in persistent RAM.
Note: This is a requirement for watchdog reset case but optional
in kernel panic case.
Watchdog reset can be supported only on platforms that meet the above
two requirements.
ETR sink로 kernel panic 시험하기
109-202ETR sink를 사용하는 시험은 다음 순서로 진행한다. crashdump kernel에서 trace data를 읽으려면 kernel bootargs에 `crash_kexec_post_notifiers`를 추가해 Linux를 부팅해야 한다.
configfs의 `panicstop` configuration을 활성화해 미리 적재된 ETM 설정을 켠다. 이어서 sysfs interface를 사용하는 `cti_setup.sh`로 CTI를 구성한다.
참고 script에서 `ap_cti_config`는 ETM trigger output 0을 channel 0에 붙이고, `etf_cti_config`와 `etr_cti_config`는 channel 0의 flush input을 각 sink에 붙인 뒤 trigger filter를 활성화한다.
script는 모든 `cti*` device를 순회한다. 연결 대상이 `ete*`이면 AP CTI 설정을, `tmc_etf*`이면 ETF 설정을, `tmc_etr*`이면 ETR 설정을 적용한다. CTI 연결은 SoC마다 다르므로 이 script는 참고용이다.
ETR buffer에는 `resrv` preferred buffer mode를 선택하고 `stop_on_flush`를 활성화한다. 그런 다음 sysfs로 core 1과 core 2에서 CoreSight tracing을 시작한다.
core 1에서 `taskset`으로 `/dev/urandom`을 읽어 `/dev/null`에 쓰는 workload를 실행한다. core 2에서는 panic timeout을 설정하고 SysRq trigger에 `c`를 써 kernel panic을 일으킨다.
재부팅한 kernel 또는 crashdump kernel에서 `/dev/crash_tmc_etr0`를 `dd`로 읽어 `/trace/cstrace.bin`에 저장한다. 마지막으로 OpenCSD decoder tool 또는 script로 instruction trace를 생성한다.
원문의 열 단계를 명령과 목적 중심으로 정리한다.
발견한 연결 device 종류에 따라 적용할 함수를 선택한다.
Sample commands for testing a Kernel panic case with ETR sink
-------------------------------------------------------------
1. Boot Linux kernel with "crash_kexec_post_notifiers" added to the kernel
bootargs. This is mandatory if the user would like to read the tracedata
from the crashdump kernel.
2. Enable the preloaded ETM configuration::
#echo 1 > /sys/kernel/config/cs-syscfg/configurations/panicstop/enable
3. Configure CTI using sysfs interface::
#./cti_setup.sh
#cat cti_setup.sh
cd /sys/bus/coresight/devices/
ap_cti_config () {
#ETM trig out[0] trigger to Channel 0
echo 0 4 > channels/trigin_attach
}
etf_cti_config () {
#ETF Flush in trigger from Channel 0
echo 0 1 > channels/trigout_attach
echo 1 > channels/trig_filter_enable
}
etr_cti_config () {
#ETR Flush in from Channel 0
echo 0 1 > channels/trigout_attach
echo 1 > channels/trig_filter_enable
}
ctidevs=`find . -name "cti*"`
for i in $ctidevs
do
cd $i
connection=`find . -name "ete*"`
if [ ! -z "$connection" ]
then
echo "AP CTI config for $i"
ap_cti_config
fi
connection=`find . -name "tmc_etf*"`
if [ ! -z "$connection" ]
then
echo "ETF CTI config for $i"
etf_cti_config
fi
connection=`find . -name "tmc_etr*"`
if [ ! -z "$connection" ]
then
echo "ETR CTI config for $i"
etr_cti_config
fi
cd ..
done
Note: CTI connections are SOC specific and hence the above script is
added just for reference.
4. Choose reserved buffer mode for ETR buffer::
#echo "resrv" > /sys/bus/coresight/devices/tmc_etr0/buf_mode_preferred
5. Enable stop on flush trigger configuration::
#echo 1 > /sys/bus/coresight/devices/tmc_etr0/stop_on_flush
6. Start Coresight tracing on cores 1 and 2 using sysfs interface
7. Run some application on core 1::
#taskset -c 1 dd if=/dev/urandom of=/dev/null &
8. Invoke kernel panic on core 2::
#echo 1 > /proc/sys/kernel/panic
#taskset -c 2 echo c > /proc/sysrq-trigger
9. From rebooted kernel or crashdump kernel, read crashdata::
#dd if=/dev/crash_tmc_etr0 of=/trace/cstrace.bin
10. Run opencsd decoder tools/scripts to generate the instruction trace.
Core 1과 Core 2 instruction trace 예시
203-344Core 1 dump는 `etm4_enable_hw`의 EL2 context에서 시작한다. `nop`, `paciasp`, register 저장, stack frame 설정, `reserved_mem` 주소 계산, 조건 분기와 복귀 준비가 address와 opcode 그대로 나열된다.
중간 생략 뒤에는 `chacha_block_generic`에서 load, address 계산, add, store, index 증가, compare가 같은 timestamp를 따라 기록된다. 이 부분은 core 1에서 실행한 `/dev/urandom` workload의 실행 흐름을 보여 준다.
Core 2 dump도 `etm4_enable_hw`에서 시작해 `ete_sysreg_write`까지 이어진다. 중간 생략 뒤에는 `panic`, `panic_smp_self_stop`, `bust_spinlocks` 함수의 instruction과 branch가 timestamp와 함께 기록되어 panic을 유발한 core의 흐름을 확인할 수 있다.
덤프의 address, opcode, instruction mnemonic, function symbol, timestamp는 분석 입력이므로 번역하지 않고 원문 그대로 보존한다.
두 core에서 포착한 대표 실행 구간을 구분한다.
샘플의 각 줄은 실행 위치와 기계어 정보를 결합한다.
Sample instruction trace dump
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Core1 dump::
A etm4_enable_hw: ffff800008ae1dd4
CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
I etm4_enable_hw: ffff800008ae1dd4:
d503201f nop
I etm4_enable_hw: ffff800008ae1dd8:
d503201f nop
I etm4_enable_hw: ffff800008ae1ddc:
d503201f nop
I etm4_enable_hw: ffff800008ae1de0:
d503201f nop
I etm4_enable_hw: ffff800008ae1de4:
d503201f nop
I etm4_enable_hw: ffff800008ae1de8:
d503233f paciasp
I etm4_enable_hw: ffff800008ae1dec:
a9be7bfd stp x29, x30, [sp, #-32]!
I etm4_enable_hw: ffff800008ae1df0:
910003fd mov x29, sp
I etm4_enable_hw: ffff800008ae1df4:
a90153f3 stp x19, x20, [sp, #16]
I etm4_enable_hw: ffff800008ae1df8:
2a0003f4 mov w20, w0
I etm4_enable_hw: ffff800008ae1dfc:
900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
I etm4_enable_hw: ffff800008ae1e00:
910f4273 add x19, x19, #0x3d0
I etm4_enable_hw: ffff800008ae1e04:
f8747a60 ldr x0, [x19, x20, lsl #3]
E etm4_enable_hw: ffff800008ae1e08:
b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
I 149.039572921 etm4_enable_hw: ffff800008ae1e30:
a94153f3 ldp x19, x20, [sp, #16]
I 149.039572921 etm4_enable_hw: ffff800008ae1e34:
52800000 mov w0, #0x0 // #0
I 149.039572921 etm4_enable_hw: ffff800008ae1e38:
a8c27bfd ldp x29, x30, [sp], #32
..snip
149.052324811 chacha_block_generic: ffff800008642d80:
9100a3e0 add x0,
I 149.052324811 chacha_block_generic: ffff800008642d84:
b86178a2 ldr w2, [x5, x1, lsl #2]
I 149.052324811 chacha_block_generic: ffff800008642d88:
8b010803 add x3, x0, x1, lsl #2
I 149.052324811 chacha_block_generic: ffff800008642d8c:
b85fc063 ldur w3, [x3, #-4]
I 149.052324811 chacha_block_generic: ffff800008642d90:
0b030042 add w2, w2, w3
I 149.052324811 chacha_block_generic: ffff800008642d94:
b8217882 str w2, [x4, x1, lsl #2]
I 149.052324811 chacha_block_generic: ffff800008642d98:
91000421 add x1, x1, #0x1
I 149.052324811 chacha_block_generic: ffff800008642d9c:
f100443f cmp x1, #0x11
Core 2 dump::
A etm4_enable_hw: ffff800008ae1dd4
CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
I etm4_enable_hw: ffff800008ae1dd4:
d503201f nop
I etm4_enable_hw: ffff800008ae1dd8:
d503201f nop
I etm4_enable_hw: ffff800008ae1ddc:
d503201f nop
I etm4_enable_hw: ffff800008ae1de0:
d503201f nop
I etm4_enable_hw: ffff800008ae1de4:
d503201f nop
I etm4_enable_hw: ffff800008ae1de8:
d503233f paciasp
I etm4_enable_hw: ffff800008ae1dec:
a9be7bfd stp x29, x30, [sp, #-32]!
I etm4_enable_hw: ffff800008ae1df0:
910003fd mov x29, sp
I etm4_enable_hw: ffff800008ae1df4:
a90153f3 stp x19, x20, [sp, #16]
I etm4_enable_hw: ffff800008ae1df8:
2a0003f4 mov w20, w0
I etm4_enable_hw: ffff800008ae1dfc:
900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
I etm4_enable_hw: ffff800008ae1e00:
910f4273 add x19, x19, #0x3d0
I etm4_enable_hw: ffff800008ae1e04:
f8747a60 ldr x0, [x19, x20, lsl #3]
E etm4_enable_hw: ffff800008ae1e08:
b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
I 149.046243445 etm4_enable_hw: ffff800008ae1e30:
a94153f3 ldp x19, x20, [sp, #16]
I 149.046243445 etm4_enable_hw: ffff800008ae1e34:
52800000 mov w0, #0x0 // #0
I 149.046243445 etm4_enable_hw: ffff800008ae1e38:
a8c27bfd ldp x29, x30, [sp], #32
I 149.046243445 etm4_enable_hw: ffff800008ae1e3c:
d50323bf autiasp
E 149.046243445 etm4_enable_hw: ffff800008ae1e40:
d65f03c0 ret
A ete_sysreg_write: ffff800008adfa18
..snip
I 149.05422547 panic: ffff800008096300:
a90363f7 stp x23, x24, [sp, #48]
I 149.05422547 panic: ffff800008096304:
6b00003f cmp w1, w0
I 149.05422547 panic: ffff800008096308:
3a411804 ccmn w0, #0x1, #0x4, ne // ne = any
N 149.05422547 panic: ffff80000809630c:
540001e0 b.eq ffff800008096348 <panic+0xe0> // b.none
I 149.05422547 panic: ffff800008096310:
f90023f9 str x25, [sp, #64]
E 149.05422547 panic: ffff800008096314:
97fe44ef bl ffff8000080276d0 <panic_smp_self_stop>
A panic: ffff80000809634c
I 149.05422547 panic: ffff80000809634c:
910102d5 add x21, x22, #0x40
I 149.05422547 panic: ffff800008096350:
52800020 mov w0, #0x1 // #1
E 149.05422547 panic: ffff800008096354:
94166b8b bl ffff800008631180 <bust_spinlocks>
N 149.054225518 bust_spinlocks: ffff800008631180:
340000c0 cbz w0, ffff800008631198 <bust_spinlocks+0x18>
I 149.054225518 bust_spinlocks: ffff800008631184:
f000a321 adrp x1, ffff800009a98000 <pbufs.0+0xbb8>
I 149.054225518 bust_spinlocks: ffff800008631188:
b9405c20 ldr w0, [x1, #92]
I 149.054225518 bust_spinlocks: ffff80000863118c:
11000400 add w0, w0, #0x1
I 149.054225518 bust_spinlocks: ffff800008631190:
b9005c20 str w0, [x1, #92]
E 149.054225518 bust_spinlocks: ffff800008631194:
d65f03c0 ret
A panic: ffff800008096358
Perf 기반 시험과 재부팅 후 회수
345-362Perf 기반 시험에서는 `cs_etm` event에 `panicstop` configuration과 sink 이름을 지정한다. ETF를 사용할 때는 CPU 1에 `tmc_etf1`, CPU 2에 `tmc_etf2`를 각각 선택한다.
ETR을 사용할 때는 `tmc_etr0` 하나를 선택하고 CPU 1과 2를 함께 기록한다. kernel panic 뒤 재부팅하면 앞에서 설명한 것과 같은 sysfs 방식으로 trace data를 회수하고 해독할 수 있다.
sink 종류에 따른 command 구성을 보존한다.
Perf based testing
------------------
Starting perf session
~~~~~~~~~~~~~~~~~~~~~
ETF::
perf record -e cs_etm/panicstop,@tmc_etf1/ -C 1
perf record -e cs_etm/panicstop,@tmc_etf2/ -C 2
ETR::
perf record -e cs_etm/panicstop,@tmc_etr0/ -C 1,2
Reading trace data after panic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Same sysfs based method explained above can be used to retrieve and
decode the trace data after the reboot on kernel panic.
요약·해설
panic.rst:1-362예약 메모리와 CTI panic trigger를 사용해 kernel panic 또는 watchdog reset 직전의 CoreSight trace를 보존하고 회수하는 절차입니다.