← Documents Documentation/admin-guide/pstore-blk.rst GitHub 원문 ↗

Linux 6.18.37 · Administration

pstore block oops/panic logger

pstore/blk의 backend 선택, frontend별 chunk 배치, dump filtering과 panic-safe driver I/O 규칙을 설명합니다.

Source pathDocumentation/admin-guide/pstore-blk.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

pstore-blk.rst:1-234

pstore/blk는 crash 직전의 kmsg, pmsg, console, ftrace record를 block 또는 MTD storage의 chunk에 남겨 reboot 뒤 pstore filesystem으로 회수합니다.

Panic path에서는 일반 kernel service를 기대할 수 없으므로 backend driver는 사전 할당, polling, lock-free CPU transfer와 direct register access를 준비해야 합니다.

영역핵심
BackendBlock device 또는 MTD device의 `blkdev`
Oops/panic`kmsg_size`; 여러 chunk를 순환하며 oldest chunk overwrite
Userspace pmsg`pmsg_size`; `/dev/pmsg0`에서 하나의 chunk에 append
Console`console_size`; console log용 단일 chunk
Ftrace`ftrace_size / processors_count`; CPU별 여러 chunk
Reason filter`max_reason`과 `enum kmsg_dump_reason`
Driver 등록`register_pstore_device(struct pstore_device_info)`
Panic I/OAllocation·interrupt·lock·DMA 회피, direct register control

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 pstore block oops/panic logger
4 ==============================
5
6 Introduction
7 ------------
8
9 pstore block (pstore/blk) is an oops/panic logger that writes its logs to a
10 block device and non-block device before the system crashes. You can get
11 these log files by mounting pstore filesystem like::
12
13 mount -t pstore pstore /sys/fs/pstore
14
15
16 pstore block concepts
17 ---------------------
18
19 pstore/blk provides efficient configuration method for pstore/blk, which
20 divides all configurations into two parts, configurations for user and
21 configurations for driver.
22
23 Configurations for user determine how pstore/blk works, such as pmsg_size,
24 kmsg_size and so on. All of them support both Kconfig and module parameters,
25 but module parameters have priority over Kconfig.
26
27 Configurations for driver are all about block device and non-block device,
28 such as total_size of block device and read/write operations.
29
30 Configurations for user
31 -----------------------
32
33 All of these configurations support both Kconfig and module parameters, but
34 module parameters have priority over Kconfig.
35
36 Here is an example for module parameters::
37
38 pstore_blk.blkdev=/dev/mmcblk0p7 pstore_blk.kmsg_size=64 best_effort=y
39
40 The detail of each configurations may be of interest to you.
41
42 blkdev
43 ~~~~~~
44
45 The block device to use. Most of the time, it is a partition of block device.
46 It's required for pstore/blk. It is also used for MTD device.
47
48 When pstore/blk is built as a module, "blkdev" accepts the following variants:
49
50 1. /dev/<disk_name> represents the device number of disk
51 #. /dev/<disk_name><decimal> represents the device number of partition - device
52 number of disk plus the partition number
53 #. /dev/<disk_name>p<decimal> - same as the above; this form is used when disk
54 name of partitioned disk ends with a digit.
55
56 When pstore/blk is built into the kernel, "blkdev" accepts the following variants:
57
58 #. <hex_major><hex_minor> device number in hexadecimal representation,
59 with no leading 0x, for example b302.
60 #. PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF represents the unique id of
61 a partition if the partition table provides it. The UUID may be either an
62 EFI/GPT UUID, or refer to an MSDOS partition using the format SSSSSSSS-PP,
63 where SSSSSSSS is a zero-filled hex representation of the 32-bit
64 "NT disk signature", and PP is a zero-filled hex representation of the
65 1-based partition number.
66 #. PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to a
67 partition with a known unique id.
68 #. <major>:<minor> major and minor number of the device separated by a colon.
69
70 It accepts the following variants for MTD device:
71
72 1. <device name> MTD device name. "pstore" is recommended.
73 #. <device number> MTD device number.
74
75 kmsg_size
76 ~~~~~~~~~
77
78 The chunk size in KB for oops/panic front-end. It **MUST** be a multiple of 4.
79 It's optional if you do not care about the oops/panic log.
80
81 There are multiple chunks for oops/panic front-end depending on the remaining
82 space except other pstore front-ends.
83
84 pstore/blk will log to oops/panic chunks one by one, and always overwrite the
85 oldest chunk if there is no more free chunk.
86
87 pmsg_size
88 ~~~~~~~~~
89
90 The chunk size in KB for pmsg front-end. It **MUST** be a multiple of 4.
91 It's optional if you do not care about the pmsg log.
92
93 Unlike oops/panic front-end, there is only one chunk for pmsg front-end.
94
95 Pmsg is a user space accessible pstore object. Writes to */dev/pmsg0* are
96 appended to the chunk. On reboot the contents are available in
97 */sys/fs/pstore/pmsg-pstore-blk-0*.
98
99 console_size
100 ~~~~~~~~~~~~
101
102 The chunk size in KB for console front-end. It **MUST** be a multiple of 4.
103 It's optional if you do not care about the console log.
104
105 Similar to pmsg front-end, there is only one chunk for console front-end.
106
107 All log of console will be appended to the chunk. On reboot the contents are
108 available in */sys/fs/pstore/console-pstore-blk-0*.
109
110 ftrace_size
111 ~~~~~~~~~~~
112
113 The chunk size in KB for ftrace front-end. It **MUST** be a multiple of 4.
114 It's optional if you do not care about the ftrace log.
115
116 Similar to oops front-end, there are multiple chunks for ftrace front-end
117 depending on the count of cpu processors. Each chunk size is equal to
118 ftrace_size / processors_count.
119
120 All log of ftrace will be appended to the chunk. On reboot the contents are
121 combined and available in */sys/fs/pstore/ftrace-pstore-blk-0*.
122
123 Persistent function tracing might be useful for debugging software or hardware
124 related hangs. Here is an example of usage::
125
126 # mount -t pstore pstore /sys/fs/pstore
127 # mount -t debugfs debugfs /sys/kernel/debug/
128 # echo 1 > /sys/kernel/debug/pstore/record_ftrace
129 # reboot -f
130 [...]
131 # mount -t pstore pstore /sys/fs/pstore
132 # tail /sys/fs/pstore/ftrace-pstore-blk-0
133 CPU:0 ts:5914676 c0063828 c0063b94 call_cpuidle <- cpu_startup_entry+0x1b8/0x1e0
134 CPU:0 ts:5914678 c039ecdc c006385c cpuidle_enter_state <- call_cpuidle+0x44/0x48
135 CPU:0 ts:5914680 c039e9a0 c039ecf0 cpuidle_enter_freeze <- cpuidle_enter_state+0x304/0x314
136 CPU:0 ts:5914681 c0063870 c039ea30 sched_idle_set_state <- cpuidle_enter_state+0x44/0x314
137 CPU:1 ts:5916720 c0160f59 c015ee04 kernfs_unmap_bin_file <- __kernfs_remove+0x140/0x204
138 CPU:1 ts:5916721 c05ca625 c015ee0c __mutex_lock_slowpath <- __kernfs_remove+0x148/0x204
139 CPU:1 ts:5916723 c05c813d c05ca630 yield_to <- __mutex_lock_slowpath+0x314/0x358
140 CPU:1 ts:5916724 c05ca2d1 c05ca638 __ww_mutex_lock <- __mutex_lock_slowpath+0x31c/0x358
141
142 max_reason
143 ~~~~~~~~~~
144
145 Limiting which kinds of kmsg dumps are stored can be controlled via
146 the ``max_reason`` value, as defined in include/linux/kmsg_dump.h's
147 ``enum kmsg_dump_reason``. For example, to store both Oopses and Panics,
148 ``max_reason`` should be set to 2 (KMSG_DUMP_OOPS), to store only Panics
149 ``max_reason`` should be set to 1 (KMSG_DUMP_PANIC). Setting this to 0
150 (KMSG_DUMP_UNDEF), means the reason filtering will be controlled by the
151 ``printk.always_kmsg_dump`` boot param: if unset, it'll be KMSG_DUMP_OOPS,
152 otherwise KMSG_DUMP_MAX.
153
154 Configurations for driver
155 -------------------------
156
157 A device driver uses ``register_pstore_device`` with
158 ``struct pstore_device_info`` to register to pstore/blk.
159
160 .. kernel-doc:: fs/pstore/blk.c
161 :export:
162
163 Compression and header
164 ----------------------
165
166 Block device is large enough for uncompressed oops data. Actually we do not
167 recommend data compression because pstore/blk will insert some information into
168 the first line of oops/panic data. For example::
169
170 Panic: Total 16 times
171
172 It means that it's OOPS|Panic for the 16th time since the first booting.
173 Sometimes the number of occurrences of oops|panic since the first booting is
174 important to judge whether the system is stable.
175
176 The following line is inserted by pstore filesystem. For example::
177
178 Oops#2 Part1
179
180 It means that it's OOPS for the 2nd time on the last boot.
181
182 Reading the data
183 ----------------
184
185 The dump data can be read from the pstore filesystem. The format for these
186 files is ``dmesg-pstore-blk-[N]`` for oops/panic front-end,
187 ``pmsg-pstore-blk-0`` for pmsg front-end and so on. The timestamp of the
188 dump file records the trigger time. To delete a stored record from block
189 device, simply unlink the respective pstore file.
190
191 Attentions in panic read/write APIs
192 -----------------------------------
193
194 If on panic, the kernel is not going to run for much longer, the tasks will not
195 be scheduled and most kernel resources will be out of service. It
196 looks like a single-threaded program running on a single-core computer.
197
198 The following points require special attention for panic read/write APIs:
199
200 1. Can **NOT** allocate any memory.
201 If you need memory, just allocate while the block driver is initializing
202 rather than waiting until the panic.
203 #. Must be polled, **NOT** interrupt driven.
204 No task schedule any more. The block driver should delay to ensure the write
205 succeeds, but NOT sleep.
206 #. Can **NOT** take any lock.
207 There is no other task, nor any shared resource; you are safe to break all
208 locks.
209 #. Just use CPU to transfer.
210 Do not use DMA to transfer unless you are sure that DMA will not keep lock.
211 #. Control registers directly.
212 Please control registers directly rather than use Linux kernel resources.
213 Do I/O map while initializing rather than wait until a panic occurs.
214 #. Reset your block device and controller if necessary.
215 If you are not sure of the state of your block device and controller when
216 a panic occurs, you are safe to stop and reset them.
217
218 pstore/blk supports psblk_blkdev_info(), which is defined in
219 *linux/pstore_blk.h*, to get information of using block device, such as the
220 device number, sector count and start sector of the whole disk.
221
222 pstore block internals
223 ----------------------
224
225 For developer reference, here are all the important structures and APIs:
226
227 .. kernel-doc:: fs/pstore/zone.c
228 :internal:
229
230 .. kernel-doc:: include/linux/pstore_zone.h
231 :internal:
232
233 .. kernel-doc:: include/linux/pstore_blk.h
234 :internal:
235

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

소개와 configuration 개념

1-29

이 문서는 `SPDX-License-Identifier: GPL-2.0`을 따릅니다. `pstore block`, 즉 `pstore/blk`는 system crash 전에 block device 또는 non-block device에 log를 쓰는 oops/panic logger입니다.

다음처럼 pstore filesystem을 mount하면 log file을 읽을 수 있습니다.

mount -t pstore pstore /sys/fs/pstore

`pstore/blk`는 configuration을 user용과 driver용 두 부분으로 나누는 효율적인 설정 방식을 제공합니다.

User configuration은 `pmsg_size`, `kmsg_size` 등 pstore/blk의 동작 방식을 결정합니다. 모두 Kconfig와 module parameter를 지원하며 module parameter가 Kconfig보다 우선합니다.

Driver configuration은 block device 또는 non-block device의 `total_size`, read/write operation처럼 storage device 자체에 관한 항목입니다.

User configuration과 `blkdev`

30-74

모든 user configuration은 Kconfig와 module parameter를 모두 지원하고 module parameter가 Kconfig보다 우선합니다. 다음은 module parameter 예제입니다.

pstore_blk.blkdev=/dev/mmcblk0p7 pstore_blk.kmsg_size=64 best_effort=y

`blkdev`는 사용할 block device를 지정하며 대부분 block device의 partition입니다. pstore/blk에 필수이고 MTD device에도 사용합니다.

pstore/blk를 module로 build한 경우 `blkdev`는 세 형식을 받습니다. `/dev/<disk_name>`은 disk의 device number를 나타냅니다. `/dev/<disk_name><decimal>`은 disk device number에 partition number를 더한 partition device number를 나타냅니다. `/dev/<disk_name>p<decimal>`도 같은 뜻이며 partition된 disk 이름이 숫자로 끝날 때 사용합니다.

pstore/blk를 kernel에 built-in한 경우 `blkdev`는 네 형식을 받습니다. `<hex_major><hex_minor>`는 선행 `0x` 없는 hexadecimal device number이며 예는 `b302`입니다.

`PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF`는 partition table이 제공하는 unique partition ID를 나타냅니다. UUID는 EFI/GPT UUID일 수 있고, MSDOS partition이라면 `SSSSSSSS-PP` 형식을 사용합니다. `SSSSSSSS`는 32-bit `NT disk signature`의 zero-filled hexadecimal 표현이고 `PP`는 1부터 시작하는 partition number의 zero-filled hexadecimal 표현입니다.

`PARTUUID=<UUID>/PARTNROFF=<int>`는 알려진 unique ID를 가진 partition을 기준으로 상대적인 partition을 선택합니다. `<major>:<minor>`는 colon으로 구분한 device major/minor number입니다.

MTD device에서는 `<device name>` 또는 `<device number>`를 받습니다. MTD device name으로는 `pstore`를 권장합니다.

Frontend별 chunk 크기와 persistent ftrace

75-141

`kmsg_size`는 oops/panic frontend의 KB 단위 chunk size이며 반드시 4의 배수여야 합니다. Oops/panic log가 필요 없으면 optional입니다.

다른 pstore frontend가 차지한 공간을 제외한 remaining space에 따라 oops/panic frontend에는 여러 chunk가 있습니다. pstore/blk는 oops/panic chunk에 하나씩 순서대로 기록하고 free chunk가 없으면 항상 가장 오래된 chunk를 overwrite합니다.

`pmsg_size`는 pmsg frontend의 KB 단위 chunk size이며 반드시 4의 배수여야 합니다. Pmsg log가 필요 없으면 optional입니다. Oops/panic과 달리 pmsg frontend에는 chunk가 하나뿐입니다.

Pmsg는 user space에서 접근 가능한 pstore object입니다. `/dev/pmsg0`에 쓴 내용은 chunk에 append되고 reboot 뒤 `/sys/fs/pstore/pmsg-pstore-blk-0`에서 읽을 수 있습니다.

`console_size`는 console frontend의 KB 단위 chunk size이며 반드시 4의 배수여야 합니다. Console log가 필요 없으면 optional입니다. Pmsg처럼 console frontend에는 chunk가 하나뿐이며 모든 console log를 append합니다. Reboot 뒤 `/sys/fs/pstore/console-pstore-blk-0`에서 읽을 수 있습니다.

`ftrace_size`는 ftrace frontend의 KB 단위 chunk size이며 반드시 4의 배수여야 합니다. Ftrace log가 필요 없으면 optional입니다.

Oops frontend와 비슷하게 ftrace frontend에는 CPU processor 수에 따른 여러 chunk가 있습니다. 각 chunk size는 `ftrace_size / processors_count`입니다. 모든 ftrace log를 chunk에 append하며 reboot 뒤 결합된 내용을 `/sys/fs/pstore/ftrace-pstore-blk-0`에서 읽을 수 있습니다.

Persistent function tracing은 software 또는 hardware 관련 hang을 debug하는 데 유용할 수 있습니다. 다음 예제는 pstore와 debugfs를 mount하고 `record_ftrace`를 켠 뒤 강제 reboot하여 저장된 trace를 읽습니다.

# mount -t pstore pstore /sys/fs/pstore
# mount -t debugfs debugfs /sys/kernel/debug/
# echo 1 > /sys/kernel/debug/pstore/record_ftrace
# reboot -f
[...]
# mount -t pstore pstore /sys/fs/pstore
# tail /sys/fs/pstore/ftrace-pstore-blk-0
CPU:0 ts:5914676 c0063828  c0063b94  call_cpuidle <- cpu_startup_entry+0x1b8/0x1e0
CPU:0 ts:5914678 c039ecdc  c006385c  cpuidle_enter_state <- call_cpuidle+0x44/0x48
CPU:0 ts:5914680 c039e9a0  c039ecf0  cpuidle_enter_freeze <- cpuidle_enter_state+0x304/0x314
CPU:0 ts:5914681 c0063870  c039ea30  sched_idle_set_state <- cpuidle_enter_state+0x44/0x314
CPU:1 ts:5916720 c0160f59  c015ee04  kernfs_unmap_bin_file <- __kernfs_remove+0x140/0x204
CPU:1 ts:5916721 c05ca625  c015ee0c  __mutex_lock_slowpath <- __kernfs_remove+0x148/0x204
CPU:1 ts:5916723 c05c813d  c05ca630  yield_to <- __mutex_lock_slowpath+0x314/0x358
CPU:1 ts:5916724 c05ca2d1  c05ca638  __ww_mutex_lock <- __mutex_lock_slowpath+0x31c/0x358
Persistent ftrace 기록과 회수
Mount pstore and debugfsEnable /sys/kernel/debug/pstore/record_ftraceCPU별 ftrace chunk에 function transition appendForced reboot; pstore/blk preserves chunksCombine and read /sys/fs/pstore/ftrace-pstore-blk-0

원문의 command와 CPU별 trace 출력을 저장 시점부터 reboot 후 결합 file까지의 흐름으로 구성했습니다.

`max_reason` dump filtering

142-153

저장할 kmsg dump 종류는 `include/linux/kmsg_dump.h`의 `enum kmsg_dump_reason`에 정의된 `max_reason` 값으로 제한합니다.

Oops와 Panic을 모두 저장하려면 `max_reason=2`, 즉 `KMSG_DUMP_OOPS`로 설정합니다. Panic만 저장하려면 `max_reason=1`, 즉 `KMSG_DUMP_PANIC`으로 설정합니다.

`max_reason=0`, 즉 `KMSG_DUMP_UNDEF`로 설정하면 `printk.always_kmsg_dump` boot parameter가 reason filtering을 제어합니다. Parameter가 설정되지 않으면 `KMSG_DUMP_OOPS`, 설정되면 `KMSG_DUMP_MAX`가 됩니다.

Driver 등록, compression과 header

154-181

Device driver는 `struct pstore_device_info`와 함께 `register_pstore_device`를 사용해 pstore/blk에 등록합니다. Export된 kernel-doc은 `fs/pstore/blk.c`에 있습니다.

Block device는 uncompressed oops data를 담기에 충분히 큽니다. pstore/blk가 oops/panic data의 첫 줄에 정보를 삽입하므로 data compression은 권장하지 않습니다. 예를 들어 다음 header가 들어갑니다.

Panic: Total 16 times

이는 첫 boot 이후 16번째 OOPS 또는 Panic임을 뜻합니다. 첫 boot 이후 oops/panic 발생 횟수는 system 안정성을 판단하는 데 중요할 수 있습니다.

다음 줄은 pstore filesystem이 삽입합니다.

Oops#2 Part1

이는 마지막 boot에서 두 번째로 발생한 OOPS의 첫 번째 part라는 뜻입니다.

저장 data 읽기와 삭제

182-190

Dump data는 pstore filesystem에서 읽습니다. Oops/panic frontend file 형식은 `dmesg-pstore-blk-[N]`, pmsg frontend는 `pmsg-pstore-blk-0`이며 다른 frontend도 같은 방식입니다.

Dump file timestamp는 trigger time을 기록합니다. Block device에서 저장 record를 삭제하려면 해당 pstore file을 unlink하면 됩니다.

Panic read/write API 주의사항

191-221

Panic이 발생하면 kernel은 오래 실행되지 않고 task가 schedule되지 않으며 대부분의 kernel resource가 동작하지 않습니다. Single-core computer에서 single-threaded program 하나가 실행되는 것과 비슷합니다.

첫째, memory를 할당할 수 없습니다. Memory가 필요하면 panic까지 기다리지 말고 block driver initialization 중에 미리 할당해야 합니다.

둘째, interrupt-driven 방식이 아니라 polling 방식이어야 합니다. 더 이상 task scheduling이 없으므로 block driver는 write 성공을 보장하도록 delay해야 하지만 sleep해서는 안 됩니다.

셋째, 어떤 lock도 잡을 수 없습니다. 다른 task나 shared resource가 없으므로 모든 lock을 깨도 안전합니다.

넷째, CPU만 사용해 transfer합니다. DMA가 lock을 유지하지 않는다고 확신하지 못하면 DMA transfer를 사용하지 마십시오.

다섯째, Linux kernel resource 대신 control register를 직접 제어합니다. I/O map도 panic 발생 시점까지 기다리지 말고 initialization 중에 수행해야 합니다.

여섯째, 필요하면 block device와 controller를 reset합니다. Panic 시점의 상태를 확신할 수 없다면 중지하고 reset해도 안전합니다.

pstore/blk는 `linux/pstore_blk.h`에 정의된 `psblk_blkdev_info()`를 지원합니다. 이를 사용해 block device의 device number, sector count, 전체 disk의 start sector 같은 정보를 얻습니다.

pstore block 내부 API

222-234

Developer reference용 주요 structure와 internal API는 `fs/pstore/zone.c`, `include/linux/pstore_zone.h`, `include/linux/pstore_blk.h`의 kernel-doc에 있습니다.