← Documents Documentation/trace/coresight/panic.rst GitHub 원문 ↗

Linux 6.18.37 · Tracing

커널 panic과 Watchdog reset에 CoreSight 사용하기

예약 메모리와 CTI panic trigger를 사용해 kernel panic 또는 watchdog reset 직전의 CoreSight trace를 보존하고 회수하는 절차입니다.

Source pathDocumentation/trace/coresight/panic.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

panic.rst:1-362

예약 메모리와 CTI panic trigger를 사용해 kernel panic 또는 watchdog reset 직전의 CoreSight trace를 보존하고 회수하는 절차입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ===================================================
2 Using Coresight for Kernel panic and Watchdog reset
3 ===================================================
4
5 Introduction
6 ------------
7 This documentation is about using Linux coresight trace support to
8 debug kernel panic and watchdog reset scenarios.
9
10 Coresight trace during Kernel panic
11 -----------------------------------
12 From the coresight driver point of view, addressing the kernel panic
13 situation has four main requirements.
14
15 a. Support for allocation of trace buffer pages from reserved memory area.
16 Platform can advertise this using a new device tree property added to
17 relevant coresight nodes.
18
19 b. Support for stopping coresight blocks at the time of panic
20
21 c. Saving required metadata in the specified format
22
23 d. Support for reading trace data captured at the time of panic
24
25 Allocation of trace buffer pages from reserved RAM
26 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 A new optional device tree property "memory-region" is added to the
28 Coresight TMC device nodes, that would give the base address and size of trace
29 buffer.
30
31 Static allocation of trace buffers would ensure that both IOMMU enabled
32 and disabled cases are handled. Also, platforms that support persistent
33 RAM will allow users to read trace data in the subsequent boot without
34 booting the crashdump kernel.
35
36 Note:
37 For ETR sink devices, this reserved region will be used for both trace
38 capture and trace data retrieval.
39 For ETF sink devices, internal SRAM would be used for trace capture,
40 and they would be synced to reserved region for retrieval.
41
42
43 Disabling coresight blocks at the time of panic
44 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 In order to avoid the situation of losing relevant trace data after a
46 kernel panic, it would be desirable to stop the coresight blocks at the
47 time of panic.
48
49 This can be achieved by configuring the comparator, CTI and sink
50 devices as below::
51
52 Trigger on panic
53 Comparator --->External out --->CTI -->External In---->ETR/ETF stop
54
55 Saving metadata at the time of kernel panic
56 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57 Coresight metadata involves all additional data that are required for a
58 successful trace decode in addition to the trace data. This involves
59 ETR/ETF/ETB register snapshot etc.
60
61 A new optional device property "memory-region" is added to
62 the ETR/ETF/ETB device nodes for this.
63
64 Reading trace data captured at the time of panic
65 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66 Trace data captured at the time of panic, can be read from rebooted kernel
67 or from crashdump kernel using a special device file /dev/crash_tmc_xxx.
68 This device file is created only when there is a valid crashdata available.
69
70 General flow of trace capture and decode in case of kernel panic
71 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72 1. Enable source and sink on all the cores using the sysfs interface.
73 ETR sinks should have trace buffers allocated from reserved memory,
74 by selecting "resrv" buffer mode from sysfs.
75
76 2. Run relevant tests.
77
78 3. On a kernel panic, all coresight blocks are disabled, necessary
79 metadata is synced by kernel panic handler.
80
81 System would eventually reboot or boot a crashdump kernel.
82
83 4. For platforms that supports crashdump kernel, raw trace data can be
84 dumped using the coresight sysfs interface from the crashdump kernel
85 itself. Persistent RAM is not a requirement in this case.
86
87 5. For platforms that supports persistent RAM, trace data can be dumped
88 using the coresight sysfs interface in the subsequent Linux boot.
89 Crashdump kernel is not a requirement in this case. Persistent RAM
90 ensures that trace data is intact across reboot.
91
92 Coresight trace during Watchdog reset
93 -------------------------------------
94 The main difference between addressing the watchdog reset and kernel panic
95 case are below,
96
97 a. Saving coresight metadata need to be taken care by the
98 SCP(system control processor) firmware in the specified format,
99 instead of kernel.
100
101 b. Reserved memory region given by firmware for trace buffer and metadata
102 has to be in persistent RAM.
103 Note: This is a requirement for watchdog reset case but optional
104 in kernel panic case.
105
106 Watchdog reset can be supported only on platforms that meet the above
107 two requirements.
108
109 Sample commands for testing a Kernel panic case with ETR sink
110 -------------------------------------------------------------
111
112 1. Boot Linux kernel with "crash_kexec_post_notifiers" added to the kernel
113 bootargs. This is mandatory if the user would like to read the tracedata
114 from the crashdump kernel.
115
116 2. Enable the preloaded ETM configuration::
117
118 #echo 1 > /sys/kernel/config/cs-syscfg/configurations/panicstop/enable
119
120 3. Configure CTI using sysfs interface::
121
122 #./cti_setup.sh
123
124 #cat cti_setup.sh
125
126
127 cd /sys/bus/coresight/devices/
128
129 ap_cti_config () {
130 #ETM trig out[0] trigger to Channel 0
131 echo 0 4 > channels/trigin_attach
132 }
133
134 etf_cti_config () {
135 #ETF Flush in trigger from Channel 0
136 echo 0 1 > channels/trigout_attach
137 echo 1 > channels/trig_filter_enable
138 }
139
140 etr_cti_config () {
141 #ETR Flush in from Channel 0
142 echo 0 1 > channels/trigout_attach
143 echo 1 > channels/trig_filter_enable
144 }
145
146 ctidevs=`find . -name "cti*"`
147
148 for i in $ctidevs
149 do
150 cd $i
151
152 connection=`find . -name "ete*"`
153 if [ ! -z "$connection" ]
154 then
155 echo "AP CTI config for $i"
156 ap_cti_config
157 fi
158
159 connection=`find . -name "tmc_etf*"`
160 if [ ! -z "$connection" ]
161 then
162 echo "ETF CTI config for $i"
163 etf_cti_config
164 fi
165
166 connection=`find . -name "tmc_etr*"`
167 if [ ! -z "$connection" ]
168 then
169 echo "ETR CTI config for $i"
170 etr_cti_config
171 fi
172
173 cd ..
174 done
175
176 Note: CTI connections are SOC specific and hence the above script is
177 added just for reference.
178
179 4. Choose reserved buffer mode for ETR buffer::
180
181 #echo "resrv" > /sys/bus/coresight/devices/tmc_etr0/buf_mode_preferred
182
183 5. Enable stop on flush trigger configuration::
184
185 #echo 1 > /sys/bus/coresight/devices/tmc_etr0/stop_on_flush
186
187 6. Start Coresight tracing on cores 1 and 2 using sysfs interface
188
189 7. Run some application on core 1::
190
191 #taskset -c 1 dd if=/dev/urandom of=/dev/null &
192
193 8. Invoke kernel panic on core 2::
194
195 #echo 1 > /proc/sys/kernel/panic
196 #taskset -c 2 echo c > /proc/sysrq-trigger
197
198 9. From rebooted kernel or crashdump kernel, read crashdata::
199
200 #dd if=/dev/crash_tmc_etr0 of=/trace/cstrace.bin
201
202 10. Run opencsd decoder tools/scripts to generate the instruction trace.
203
204 Sample instruction trace dump
205 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
206
207 Core1 dump::
208
209 A etm4_enable_hw: ffff800008ae1dd4
210 CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
211 I etm4_enable_hw: ffff800008ae1dd4:
212 d503201f nop
213 I etm4_enable_hw: ffff800008ae1dd8:
214 d503201f nop
215 I etm4_enable_hw: ffff800008ae1ddc:
216 d503201f nop
217 I etm4_enable_hw: ffff800008ae1de0:
218 d503201f nop
219 I etm4_enable_hw: ffff800008ae1de4:
220 d503201f nop
221 I etm4_enable_hw: ffff800008ae1de8:
222 d503233f paciasp
223 I etm4_enable_hw: ffff800008ae1dec:
224 a9be7bfd stp x29, x30, [sp, #-32]!
225 I etm4_enable_hw: ffff800008ae1df0:
226 910003fd mov x29, sp
227 I etm4_enable_hw: ffff800008ae1df4:
228 a90153f3 stp x19, x20, [sp, #16]
229 I etm4_enable_hw: ffff800008ae1df8:
230 2a0003f4 mov w20, w0
231 I etm4_enable_hw: ffff800008ae1dfc:
232 900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
233 I etm4_enable_hw: ffff800008ae1e00:
234 910f4273 add x19, x19, #0x3d0
235 I etm4_enable_hw: ffff800008ae1e04:
236 f8747a60 ldr x0, [x19, x20, lsl #3]
237 E etm4_enable_hw: ffff800008ae1e08:
238 b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
239 I 149.039572921 etm4_enable_hw: ffff800008ae1e30:
240 a94153f3 ldp x19, x20, [sp, #16]
241 I 149.039572921 etm4_enable_hw: ffff800008ae1e34:
242 52800000 mov w0, #0x0 // #0
243 I 149.039572921 etm4_enable_hw: ffff800008ae1e38:
244 a8c27bfd ldp x29, x30, [sp], #32
245
246 ..snip
247
248 149.052324811 chacha_block_generic: ffff800008642d80:
249 9100a3e0 add x0,
250 I 149.052324811 chacha_block_generic: ffff800008642d84:
251 b86178a2 ldr w2, [x5, x1, lsl #2]
252 I 149.052324811 chacha_block_generic: ffff800008642d88:
253 8b010803 add x3, x0, x1, lsl #2
254 I 149.052324811 chacha_block_generic: ffff800008642d8c:
255 b85fc063 ldur w3, [x3, #-4]
256 I 149.052324811 chacha_block_generic: ffff800008642d90:
257 0b030042 add w2, w2, w3
258 I 149.052324811 chacha_block_generic: ffff800008642d94:
259 b8217882 str w2, [x4, x1, lsl #2]
260 I 149.052324811 chacha_block_generic: ffff800008642d98:
261 91000421 add x1, x1, #0x1
262 I 149.052324811 chacha_block_generic: ffff800008642d9c:
263 f100443f cmp x1, #0x11
264
265
266 Core 2 dump::
267
268 A etm4_enable_hw: ffff800008ae1dd4
269 CONTEXT EL2 etm4_enable_hw: ffff800008ae1dd4
270 I etm4_enable_hw: ffff800008ae1dd4:
271 d503201f nop
272 I etm4_enable_hw: ffff800008ae1dd8:
273 d503201f nop
274 I etm4_enable_hw: ffff800008ae1ddc:
275 d503201f nop
276 I etm4_enable_hw: ffff800008ae1de0:
277 d503201f nop
278 I etm4_enable_hw: ffff800008ae1de4:
279 d503201f nop
280 I etm4_enable_hw: ffff800008ae1de8:
281 d503233f paciasp
282 I etm4_enable_hw: ffff800008ae1dec:
283 a9be7bfd stp x29, x30, [sp, #-32]!
284 I etm4_enable_hw: ffff800008ae1df0:
285 910003fd mov x29, sp
286 I etm4_enable_hw: ffff800008ae1df4:
287 a90153f3 stp x19, x20, [sp, #16]
288 I etm4_enable_hw: ffff800008ae1df8:
289 2a0003f4 mov w20, w0
290 I etm4_enable_hw: ffff800008ae1dfc:
291 900085b3 adrp x19, ffff800009b95000 <reserved_mem+0xc48>
292 I etm4_enable_hw: ffff800008ae1e00:
293 910f4273 add x19, x19, #0x3d0
294 I etm4_enable_hw: ffff800008ae1e04:
295 f8747a60 ldr x0, [x19, x20, lsl #3]
296 E etm4_enable_hw: ffff800008ae1e08:
297 b4000140 cbz x0, ffff800008ae1e30 <etm4_starting_cpu+0x50>
298 I 149.046243445 etm4_enable_hw: ffff800008ae1e30:
299 a94153f3 ldp x19, x20, [sp, #16]
300 I 149.046243445 etm4_enable_hw: ffff800008ae1e34:
301 52800000 mov w0, #0x0 // #0
302 I 149.046243445 etm4_enable_hw: ffff800008ae1e38:
303 a8c27bfd ldp x29, x30, [sp], #32
304 I 149.046243445 etm4_enable_hw: ffff800008ae1e3c:
305 d50323bf autiasp
306 E 149.046243445 etm4_enable_hw: ffff800008ae1e40:
307 d65f03c0 ret
308 A ete_sysreg_write: ffff800008adfa18
309
310 ..snip
311
312 I 149.05422547 panic: ffff800008096300:
313 a90363f7 stp x23, x24, [sp, #48]
314 I 149.05422547 panic: ffff800008096304:
315 6b00003f cmp w1, w0
316 I 149.05422547 panic: ffff800008096308:
317 3a411804 ccmn w0, #0x1, #0x4, ne // ne = any
318 N 149.05422547 panic: ffff80000809630c:
319 540001e0 b.eq ffff800008096348 <panic+0xe0> // b.none
320 I 149.05422547 panic: ffff800008096310:
321 f90023f9 str x25, [sp, #64]
322 E 149.05422547 panic: ffff800008096314:
323 97fe44ef bl ffff8000080276d0 <panic_smp_self_stop>
324 A panic: ffff80000809634c
325 I 149.05422547 panic: ffff80000809634c:
326 910102d5 add x21, x22, #0x40
327 I 149.05422547 panic: ffff800008096350:
328 52800020 mov w0, #0x1 // #1
329 E 149.05422547 panic: ffff800008096354:
330 94166b8b bl ffff800008631180 <bust_spinlocks>
331 N 149.054225518 bust_spinlocks: ffff800008631180:
332 340000c0 cbz w0, ffff800008631198 <bust_spinlocks+0x18>
333 I 149.054225518 bust_spinlocks: ffff800008631184:
334 f000a321 adrp x1, ffff800009a98000 <pbufs.0+0xbb8>
335 I 149.054225518 bust_spinlocks: ffff800008631188:
336 b9405c20 ldr w0, [x1, #92]
337 I 149.054225518 bust_spinlocks: ffff80000863118c:
338 11000400 add w0, w0, #0x1
339 I 149.054225518 bust_spinlocks: ffff800008631190:
340 b9005c20 str w0, [x1, #92]
341 E 149.054225518 bust_spinlocks: ffff800008631194:
342 d65f03c0 ret
343 A panic: ffff800008096358
344
345 Perf based testing
346 ------------------
347
348 Starting perf session
349 ~~~~~~~~~~~~~~~~~~~~~
350 ETF::
351
352 perf record -e cs_etm/panicstop,@tmc_etf1/ -C 1
353 perf record -e cs_etm/panicstop,@tmc_etf2/ -C 2
354
355 ETR::
356
357 perf record -e cs_etm/panicstop,@tmc_etr0/ -C 1,2
358
359 Reading trace data after panic
360 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
361 Same sysfs based method explained above can be used to retrieve and
362 decode the trace data after the reboot on kernel panic.
363

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를 다시 읽을 수 있어야 한다.

Kernel panic 추적 요구 사항
구분요구 사항
a예약 메모리에서 trace buffer page 할당
bpanic 시점에 CoreSight block 정지
c필수 metadata를 지정 형식으로 저장
dpanic 시점의 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-68

CoreSight 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가 있을 때만 생성된다.

Sink별 예약 메모리 사용
Sink캡처회수
ETR예약 메모리같은 예약 메모리
ETF내부 SRAM예약 메모리로 동기화

ETR과 ETF는 캡처 위치가 다르지만 회수 가능한 데이터를 예약 영역에 남긴다.

Panic stop trigger
Trigger on panicComparator
Comparator external outCTI external in
CTIETR / ETF stop

원문의 ASCII 경로를 같은 의미의 구조화 흐름으로 다시 그렸다.

Crash trace 구성 요소
항목내용
Trace datapanic 직전까지 캡처한 실행 흐름
MetadataETR/ETF/ETB register snapshot 등
Device file/dev/crash_tmc_xxx
생성 조건유효한 crashdata 존재

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-108

kernel 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 추적을 지원할 수 있다.

Kernel panic 캡처와 회수
Enable source and sinkRun tests
Kernel panicStop CoreSight blocks
Panic handlerSync metadata
Crashdump kernelDump raw trace
Persistent RAM and rebootDump raw trace
Raw traceDecode

source 활성화부터 재부팅 이후 해독까지의 순서다.

회수 경로 비교
경로Persistent RAMCrashdump kernel
Crashdump 부팅 후 회수필수 아님필수
다음 일반 부팅에서 회수필수필수 아님

platform 기능에 따라 crashdump kernel 또는 persistent RAM 경로를 택한다.

Watchdog reset과 kernel panic
항목Kernel panicWatchdog reset
Metadata 저장 주체kernel panic handlerSCP firmware
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-202

ETR 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를 생성한다.

ETR panic 시험 순서
단계작업
1crash_kexec_post_notifiers bootarg로 부팅
2panicstop ETM configuration 활성화
3SoC에 맞게 CTI 연결 구성
4tmc_etr0의 buffer mode를 resrv로 선택
5stop_on_flush 활성화
6core 1과 2의 tracing 시작
7core 1에서 workload 실행
8core 2에서 kernel panic 유발
9crash_tmc_etr0에서 crashdata 회수
10OpenCSD로 instruction trace 생성

원문의 열 단계를 명령과 목적 중심으로 정리한다.

CTI 설정 script의 분기
Find cti*Inspect connection
ete*ap_cti_config
tmc_etf*etf_cti_config
tmc_etr*etr_cti_config
Channel 0 triggerFlush and stop path

발견한 연결 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-344

Core 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는 분석 입력이므로 번역하지 않고 원문 그대로 보존한다.

샘플 dump 비교
Core대표 symbol의미
Core 1etm4_enable_hw, chacha_block_generic일반 workload와 추적 활성화 경로
Core 2etm4_enable_hw, panic, bust_spinlockspanic을 유발한 core의 정지 경로

두 core에서 포착한 대표 실행 구간을 구분한다.

Instruction trace 해석 단위
Timestamp and trace markerFunction symbol and address
Function symbol and addressOpcode
OpcodeInstruction mnemonic and operands

샘플의 각 줄은 실행 위치와 기계어 정보를 결합한다.


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-362

Perf 기반 시험에서는 `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를 회수하고 해독할 수 있다.

Perf panic session
SinkCPU 선택Event
ETF-C 1cs_etm/panicstop,@tmc_etf1/
ETF-C 2cs_etm/panicstop,@tmc_etf2/
ETR-C 1,2cs_etm/panicstop,@tmc_etr0/

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.