← Documents Documentation/translations/it_IT/locking/lockstat.rst GitHub 원문 ↗

Linux 6.18.37 · Translations

잠금 통계

lockstat의 잠금 생명주기 hook, 경합·획득·대기·보유 지표와 /proc/lock_stat 해석법을 설명합니다.

Source pathDocumentation/translations/it_IT/locking/lockstat.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

lockstat.rst:1-230

lockstat이 잠금 획득·경합·보유 지점을 계측하고 `/proc/lock_stat`에 클래스와 호출 지점별 통계를 표시하는 방식을 다룹니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 .. include:: ../disclaimer-ita.rst
4
5 =======================
6 Statistiche sui blocchi
7 =======================
8
9 Cosa
10 ====
11
12 Come suggerisce il nome, fornisce statistiche sui blocchi.
13
14
15 Perché
16 ======
17
18 Perché, tanto per fare un esempio, le contese sui blocchi possono influenzare
19 significativamente le prestazioni.
20
21 Come
22 ====
23
24 *Lockdep* ha punti di collegamento nelle funzioni di blocco e inoltre
25 mappa le istanze di blocco con le relative classi. Partiamo da questo punto
26 (vedere Documentation/translations/it_IT/locking/lockdep-design.rst).
27 Il grafico sottostante mostra la relazione che intercorre fra le
28 funzioni di blocco e i vari punti di collegamenti che ci sono al loro
29 interno::
30
31 __acquire
32 |
33 lock _____
34 | \
35 | __contended
36 | |
37 | <wait>
38 | _______/
39 |/
40 |
41 __acquired
42 |
43 .
44 <hold>
45 .
46 |
47 __release
48 |
49 unlock
50
51 lock, unlock - le classiche funzioni di blocco
52 __* - i punti di collegamento
53 <> - stati
54
55 Grazie a questi punti di collegamento possiamo fornire le seguenti statistiche:
56
57 con-bounces
58 - numero di contese su un blocco che riguarda dati di un processore
59
60 contentions
61 - numero di acquisizioni di blocchi che hanno dovuto attendere
62
63 wait time
64 min
65 - tempo minimo (diverso da zero) che sia mai stato speso in attesa di
66 un blocco
67
68 max
69 - tempo massimo che sia mai stato speso in attesa di un blocco
70
71 total
72 - tempo totale speso in attesa di un blocco
73
74 avg
75 - tempo medio speso in attesa di un blocco
76
77 acq-bounces
78 - numero di acquisizioni di blocco che riguardavano i dati su un processore
79
80 acquisitions
81 - numero di volte che un blocco è stato ottenuto
82
83 hold time
84 min
85 - tempo minimo (diverso da zero) che sia mai stato speso trattenendo un blocco
86
87 max
88 - tempo massimo che sia mai stato speso trattenendo un blocco
89
90 total
91 - tempo totale di trattenimento di un blocco
92
93 avg
94 - tempo medio di trattenimento di un blocco
95
96 Questi numeri vengono raccolti per classe di blocco, e per ogni stato di
97 lettura/scrittura (quando applicabile).
98
99 Inoltre, questa raccolta di statistiche tiene traccia di 4 punti di contesa
100 per classe di blocco. Un punto di contesa è una chiamata che ha dovuto
101 aspettare l'acquisizione di un blocco.
102
103 Configurazione
104 --------------
105
106 Le statistiche sui blocchi si abilitano usando l'opzione di configurazione
107 CONFIG_LOCK_STAT.
108
109 Uso
110 ---
111
112 Abilitare la raccolta di statistiche::
113
114 # echo 1 >/proc/sys/kernel/lock_stat
115
116 Disabilitare la raccolta di statistiche::
117
118 # echo 0 >/proc/sys/kernel/lock_stat
119
120 Per vedere le statistiche correnti sui blocchi::
121
122 ( i numeri di riga non fanno parte dell'output del comando, ma sono stati
123 aggiunti ai fini di questa spiegazione )
124
125 # less /proc/lock_stat
126
127 01 lock_stat version 0.4
128 02-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
129 03 class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
130 04-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
131 05
132 06 &mm->mmap_sem-W: 46 84 0.26 939.10 16371.53 194.90 47291 2922365 0.16 2220301.69 17464026916.32 5975.99
133 07 &mm->mmap_sem-R: 37 100 1.31 299502.61 325629.52 3256.30 212344 34316685 0.10 7744.91 95016910.20 2.77
134 08 ---------------
135 09 &mm->mmap_sem 1 [<ffffffff811502a7>] khugepaged_scan_mm_slot+0x57/0x280
136 10 &mm->mmap_sem 96 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
137 11 &mm->mmap_sem 34 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
138 12 &mm->mmap_sem 17 [<ffffffff81127e71>] vm_munmap+0x41/0x80
139 13 ---------------
140 14 &mm->mmap_sem 1 [<ffffffff81046fda>] dup_mmap+0x2a/0x3f0
141 15 &mm->mmap_sem 60 [<ffffffff81129e29>] SyS_mprotect+0xe9/0x250
142 16 &mm->mmap_sem 41 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
143 17 &mm->mmap_sem 68 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
144 18
145 19.............................................................................................................................................................................................................................
146 20
147 21 unix_table_lock: 110 112 0.21 49.24 163.91 1.46 21094 66312 0.12 624.42 31589.81 0.48
148 22 ---------------
149 23 unix_table_lock 45 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
150 24 unix_table_lock 47 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
151 25 unix_table_lock 15 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
152 26 unix_table_lock 5 [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
153 27 ---------------
154 28 unix_table_lock 39 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
155 29 unix_table_lock 49 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
156 30 unix_table_lock 20 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
157 31 unix_table_lock 4 [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
158
159 Questo estratto mostra le statistiche delle prime due classi di
160 blocco. La riga 01 mostra la versione dell'output - la versione
161 cambierà ogni volta che cambia il formato. Le righe dalla 02 alla 04
162 rappresentano l'intestazione con la descrizione delle colonne. Le
163 statistiche sono mostrate nelle righe dalla 05 alla 18 e dalla 20
164 alla 31. Queste statistiche sono divise in due parti: le statistiche,
165 seguite dai punti di contesa (righe 08 e 13) separati da un divisore.
166
167 Le righe dalla 09 alla 12 mostrano i primi quattro punti di contesa
168 registrati (il codice che tenta di acquisire un blocco) e le righe
169 dalla 14 alla 17 mostrano i primi quattro punti contesi registrati
170 (ovvero codice che ha acquisito un blocco). È possibile che nelle
171 statistiche manchi il valore *max con-bounces*.
172
173 Il primo blocco (righe dalla 05 alla 18) è di tipo lettura/scrittura e quindi
174 mostra due righe prima del divisore. I punti di contesa non corrispondono alla
175 descrizione delle colonne nell'intestazione; essi hanno due colonne: *punti di
176 contesa* e *[<IP>] simboli*. Il secondo gruppo di punti di contesa sono i punti
177 con cui si contende il blocco.
178
179 La parte interna del tempo è espressa in us (microsecondi).
180
181 Quando si ha a che fare con blocchi annidati si potrebbero vedere le
182 sottoclassi di blocco::
183
184 32...........................................................................................................................................................................................................................
185 33
186 34 &rq->lock: 13128 13128 0.43 190.53 103881.26 7.91 97454 3453404 0.00 401.11 13224683.11 3.82
187 35 ---------
188 36 &rq->lock 645 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
189 37 &rq->lock 297 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
190 38 &rq->lock 360 [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a
191 39 &rq->lock 428 [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb
192 40 ---------
193 41 &rq->lock 77 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
194 42 &rq->lock 174 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
195 43 &rq->lock 4715 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
196 44 &rq->lock 893 [<ffffffff81340524>] schedule+0x157/0x7b8
197 45
198 46...........................................................................................................................................................................................................................
199 47
200 48 &rq->lock/1: 1526 11488 0.33 388.73 136294.31 11.86 21461 38404 0.00 37.93 109388.53 2.84
201 49 -----------
202 50 &rq->lock/1 11526 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
203 51 -----------
204 52 &rq->lock/1 5645 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
205 53 &rq->lock/1 1224 [<ffffffff81340524>] schedule+0x157/0x7b8
206 54 &rq->lock/1 4336 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
207 55 &rq->lock/1 181 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
208
209 La riga 48 mostra le statistiche per la seconda sottoclasse (/1) della
210 classe *&irq->lock* (le sottoclassi partono da 0); in questo caso,
211 come suggerito dalla riga 50, ``double_rq_lock`` tenta di acquisire un blocco
212 annidato di due spinlock.
213
214 Per vedere i blocco più contesi::
215
216 # grep : /proc/lock_stat | head
217 clockevents_lock: 2926159 2947636 0.15 46882.81 1784540466.34 605.41 3381345 3879161 0.00 2260.97 53178395.68 13.71
218 tick_broadcast_lock: 346460 346717 0.18 2257.43 39364622.71 113.54 3642919 4242696 0.00 2263.79 49173646.60 11.59
219 &mapping->i_mmap_mutex: 203896 203899 3.36 645530.05 31767507988.39 155800.21 3361776 8893984 0.17 2254.15 14110121.02 1.59
220 &rq->lock: 135014 136909 0.18 606.09 842160.68 6.15 1540728 10436146 0.00 728.72 17606683.41 1.69
221 &(&zone->lru_lock)->rlock: 93000 94934 0.16 59.18 188253.78 1.98 1199912 3809894 0.15 391.40 3559518.81 0.93
222 tasklist_lock-W: 40667 41130 0.23 1189.42 428980.51 10.43 270278 510106 0.16 653.51 3939674.91 7.72
223 tasklist_lock-R: 21298 21305 0.20 1310.05 215511.12 10.12 186204 241258 0.14 1162.33 1179779.23 4.89
224 rcu_node_1: 47656 49022 0.16 635.41 193616.41 3.95 844888 1865423 0.00 764.26 1656226.96 0.89
225 &(&dentry->d_lockref.lock)->rlock: 39791 40179 0.15 1302.08 88851.96 2.21 2790851 12527025 0.10 1910.75 3379714.27 0.27
226 rcu_node_0: 29203 30064 0.16 786.55 1555573.00 51.74 88963 244254 0.00 398.87 428872.51 1.76
227
228 Per cancellare le statistiche::
229
230 # echo 0 > /proc/lock_stat
231

3. 한국어 전문 번역

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

무엇을 왜 측정하는가

1-20

Lockstat은 lock에 관한 통계를 제공한다. Lock contention은 system 성능을 심각하게 떨어뜨릴 수 있으므로 획득 대기와 보유 시간을 실제 call site별로 관찰할 필요가 있다.

Lockdep은 이미 lock function에 hook을 두고 lock instance를 lock class로 mapping한다. Lockstat은 Documentation/locking/lockdep-design.rst에 설명된 이 기반을 활용한다.

lockstat은 lockdep이 이미 잠금 획득 함수에 연결해 둔 추적 지점을 이용해 잠금 클래스별 경합과 보유 시간을 집계합니다. 새 계측 경로를 따로 삽입하지 않고 lock instance를 lock class에 매핑하는 기존 기반을 재사용합니다.

목표는 어떤 잠금이 자주 기다리게 하는지, 대기가 얼마나 길었는지, 획득 뒤 얼마나 오래 보유됐는지와 그 호출 지점을 함께 보여 주는 것입니다. 평균만이 아니라 최소·최대와 총합을 함께 봐야 드문 긴 지연과 상시 경합을 구분할 수 있습니다.

.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-ita.rst

=======================
Statistiche sui blocchi
=======================

Cosa
====

Come suggerisce il nome, fornisce statistiche sui blocchi.


Perché
======

Perché, tanto per fare un esempio, le contese sui blocchi possono influenzare
significativamente le prestazioni.

잠금 생명주기와 수집 지표

21-102

원문의 ASCII 흐름은 홈페이지에서 구조화 도식으로 다시 그렸다. 일반 lock() 호출은 __acquire hook을 지나고 즉시 획득하지 못하면 __contended에서 wait 상태를 기록한다. 획득 시 __acquired를 거쳐 hold 구간을 측정하며 __release 뒤 unlock()으로 끝난다.

__acquire
    |
  lock ---------
    |           |
    |      __contended
    |           |
    |         <wait>
    |-----------
    |
__acquired
    |
  <hold>
    |
__release
    |
 unlock

그림에서 lock과 unlock은 일반 lock function, __*는 instrumentation hook, angle bracket 표기는 측정하는 상태를 뜻한다.

Metric의미
con-bounces다른 CPU의 data를 건드린 lock contention 횟수
contentions기다려야 했던 lock acquisition 횟수
wait time minlock을 기다린 0이 아닌 가장 짧은 시간
wait time maxlock을 기다린 가장 긴 시간
wait time total이 lock을 기다린 시간의 합
wait time avg이 lock을 기다린 평균 시간
acq-bounces다른 CPU의 data를 건드린 lock acquisition 횟수
acquisitionslock을 획득한 총 횟수
hold time minlock을 보유한 0이 아닌 가장 짧은 시간
hold time maxlock을 보유한 가장 긴 시간
hold time total이 lock을 보유한 시간의 합
hold time avg이 lock을 보유한 평균 시간

통계는 lock class별로, 해당하는 경우 read/write state별로 수집한다. Class마다 acquisition을 기다린 call site인 contention point도 네 개까지 추적한다.

잠금 획득 경로는 `__acquire`에서 시작해 즉시 성공하면 곧바로 `acquired`로 가고, 실패하면 `__contended`와 대기 구간을 거친 뒤 `acquired`에 도달합니다. 해제 시점은 `release`가 기록하여 실제 보유 시간을 계산합니다.

경합 통계는 기다린 횟수와 전체 획득 횟수, 대기 시간의 최소·최대·합계, 보유 시간의 최소·최대·합계를 저장합니다. 읽기/쓰기 잠금은 가능한 경우 read와 write 통계를 분리하여 같은 클래스 안의 사용 양상을 비교합니다.

lockstat 잠금 생명주기
__acquireImmediate success or contention
__contendedWait for owner
acquiredHold critical section
releaseRecord hold time

원문의 세로 ASCII 흐름을 획득·경합·보유 단계로 구조화했습니다.

Come
====

*Lockdep* ha punti di collegamento nelle funzioni di blocco e inoltre
mappa le istanze di blocco con le relative classi. Partiamo da questo punto
(vedere Documentation/translations/it_IT/locking/lockdep-design.rst).
Il grafico sottostante mostra la relazione che intercorre fra le
funzioni di blocco e i vari punti di collegamenti che ci sono al loro
interno::

        __acquire
            |
           lock _____
            |        \
            |    __contended
            |         |
            |       <wait>
            | _______/
            |/
            |
       __acquired
            |
            .
          <hold>
            .
            |
       __release
            |
         unlock

  lock, unlock	- le classiche funzioni di blocco
  __*		- i punti di collegamento
  <> 		- stati

Grazie a questi punti di collegamento possiamo fornire le seguenti statistiche:

con-bounces
  - numero di contese su un blocco che riguarda dati di un processore

contentions
  - numero di acquisizioni di blocchi che hanno dovuto attendere

wait time
  min
    - tempo minimo (diverso da zero) che sia mai stato speso in attesa di
      un blocco

  max
    - tempo massimo che sia mai stato speso in attesa di un blocco

  total
    - tempo totale speso in attesa di un blocco

  avg
	- tempo medio speso in attesa di un blocco

acq-bounces
  - numero di acquisizioni di blocco che riguardavano i dati su un processore

acquisitions
  - numero di volte che un blocco è stato ottenuto

hold time
  min
    - tempo minimo (diverso da zero) che sia mai stato speso trattenendo un blocco

  max
    - tempo massimo che sia mai stato speso trattenendo un blocco

  total
    - tempo totale di trattenimento di un blocco

  avg
    - tempo medio di trattenimento di un blocco

Questi numeri vengono raccolti per classe di blocco, e per ogni stato di
lettura/scrittura (quando applicabile).

Inoltre, questa raccolta di statistiche tiene traccia di 4 punti di contesa
per classe di blocco. Un punto di contesa è una chiamata che ha dovuto
aspettare l'acquisizione di un blocco.

설정과 실행 중 제어

103-108

CONFIG_LOCK_STAT을 enable한 kernel에서 /proc/sys/kernel/lock_stat으로 수집을 제어한다.

# enable collection
echo 1 > /proc/sys/kernel/lock_stat

# disable collection
echo 0 > /proc/sys/kernel/lock_stat

# inspect statistics
less /proc/lock_stat

커널을 `CONFIG_LOCK_STAT`으로 빌드해야 통계 기능을 사용할 수 있습니다. 실행 중에는 `/proc/sys/kernel/lock_stat`에 1을 써서 수집을 켜고 0을 써서 끄므로, 관심 workload 전후의 구간만 측정해 계측 비용과 잡음을 줄일 수 있습니다.

Configurazione
--------------

Le statistiche sui blocchi si abilitano usando l'opzione di configurazione
CONFIG_LOCK_STAT.

/proc/lock_stat 출력

109-172
01 lock_stat version 0.4
02 ------------------------------------------------------------------------
03 class name  con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg
04 ------------------------------------------------------------------------
05
06 &mm->mmap_sem-W: 46 84 0.26 939.10 16371.53 194.90 47291 2922365 0.16 2220301.69 17464026916.32 5975.99
07 &mm->mmap_sem-R: 37 100 1.31 299502.61 325629.52 3256.30 212344 34316685 0.10 7744.91 95016910.20 2.77
08 ---------------
09 &mm->mmap_sem 1  [<ffffffff811502a7>] khugepaged_scan_mm_slot+0x57/0x280
10 &mm->mmap_sem 96 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
11 &mm->mmap_sem 34 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
12 &mm->mmap_sem 17 [<ffffffff81127e71>] vm_munmap+0x41/0x80
13 ---------------
14 &mm->mmap_sem 1  [<ffffffff81046fda>] dup_mmap+0x2a/0x3f0
15 &mm->mmap_sem 60 [<ffffffff81129e29>] SyS_mprotect+0xe9/0x250
16 &mm->mmap_sem 41 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
17 &mm->mmap_sem 68 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
18
19 ........................................................................
20
21 unix_table_lock: 110 112 0.21 49.24 163.91 1.46 21094 66312 0.12 624.42 31589.81 0.48
22 ---------------
23 unix_table_lock 45 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
24 unix_table_lock 47 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
25 unix_table_lock 15 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
26 unix_table_lock 5  [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
27 ---------------
28 unix_table_lock 39 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
29 unix_table_lock 49 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
30 unix_table_lock 20 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
31 unix_table_lock 4  [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0

원문 예시의 line number는 설명을 위해 붙인 것이며 실제 출력에는 없다. 01은 format이 바뀔 때 갱신되는 output version이고 02-04는 column header다. 05-18과 20-31이 두 lock class의 실제 통계다.

`/proc/lock_stat`의 첫 요약 행은 클래스 이름 뒤에 contention 횟수와 획득 횟수, 대기 시간 통계, 보유 시간 통계를 나열합니다. `&mm->mmap_sem-W`와 `-R` 접미사는 같은 읽기/쓰기 잠금의 writer와 reader 측정을 구분합니다.

요약 아래의 `contention points`는 잠금을 얻으려다 기다린 acquirer 호출 지점이고, `contending points` 또는 holder 쪽 목록은 그때 잠금을 보유한 호출 지점입니다. 횟수와 심볼을 함께 보면 병목을 만든 호출자와 실제 차단 원인을 연결할 수 있습니다.

lockstat 핵심 열
의미
contentions잠금을 기다린 횟수
acquisitions잠금 획득 총횟수
wait min/max/total경합 대기 시간 분포
hold min/max/total임계 구역 보유 시간 분포

출력의 주요 수치와 해석을 정리했습니다.

Uso
---

Abilitare la raccolta di statistiche::

	# echo 1 >/proc/sys/kernel/lock_stat

Disabilitare la raccolta di statistiche::

	# echo 0 >/proc/sys/kernel/lock_stat

Per vedere le statistiche correnti sui blocchi::

  ( i numeri di riga non fanno parte dell'output del comando, ma sono stati
  aggiunti ai fini di questa spiegazione )

  # less /proc/lock_stat

  01 lock_stat version 0.4
  02-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  03                              class name    con-bounces    contentions   waittime-min   waittime-max waittime-total   waittime-avg    acq-bounces   acquisitions   holdtime-min   holdtime-max holdtime-total   holdtime-avg
  04-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  05
  06                         &mm->mmap_sem-W:            46             84           0.26         939.10       16371.53         194.90          47291        2922365           0.16     2220301.69 17464026916.32        5975.99
  07                         &mm->mmap_sem-R:            37            100           1.31      299502.61      325629.52        3256.30         212344       34316685           0.10        7744.91    95016910.20           2.77
  08                         ---------------
  09                           &mm->mmap_sem              1          [<ffffffff811502a7>] khugepaged_scan_mm_slot+0x57/0x280
  10                           &mm->mmap_sem             96          [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
  11                           &mm->mmap_sem             34          [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
  12                           &mm->mmap_sem             17          [<ffffffff81127e71>] vm_munmap+0x41/0x80
  13                         ---------------
  14                           &mm->mmap_sem              1          [<ffffffff81046fda>] dup_mmap+0x2a/0x3f0
  15                           &mm->mmap_sem             60          [<ffffffff81129e29>] SyS_mprotect+0xe9/0x250
  16                           &mm->mmap_sem             41          [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
  17                           &mm->mmap_sem             68          [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
  18
  19.............................................................................................................................................................................................................................
  20
  21                         unix_table_lock:           110            112           0.21          49.24         163.91           1.46          21094          66312           0.12         624.42       31589.81           0.48
  22                         ---------------
  23                         unix_table_lock             45          [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
  24                         unix_table_lock             47          [<ffffffff8150b111>] unix_release_sock+0x31/0x250
  25                         unix_table_lock             15          [<ffffffff8150ca37>] unix_find_other+0x117/0x230
  26                         unix_table_lock              5          [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
  27                         ---------------
  28                         unix_table_lock             39          [<ffffffff8150b111>] unix_release_sock+0x31/0x250
  29                         unix_table_lock             49          [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
  30                         unix_table_lock             20          [<ffffffff8150ca37>] unix_find_other+0x117/0x230
  31                         unix_table_lock              4          [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0

Questo estratto mostra le statistiche delle prime due classi di
blocco. La riga 01 mostra la versione dell'output - la versione
cambierà ogni volta che cambia il formato. Le righe dalla 02 alla 04
rappresentano l'intestazione con la descrizione delle colonne. Le
statistiche sono mostrate nelle righe dalla 05 alla 18 e dalla 20
alla 31. Queste statistiche sono divise in due parti: le statistiche,
seguite dai punti di contesa (righe 08 e 13) separati da un divisore.

Le righe dalla 09 alla 12 mostrano i primi quattro punti di contesa
registrati (il codice che tenta di acquisire un blocco) e le righe
dalla 14 alla 17 mostrano i primi quattro punti contesi registrati
(ovvero codice che ha acquisito un blocco). È possibile che nelle
statistiche manchi il valore *max con-bounces*.

경합 지점과 중첩 subclass

173-215

각 통계는 짧은 separator를 기준으로 main stats와 contention point 두 부분으로 나뉜다. Line 09-12는 lock을 얻으려 한 첫 네 contention point이고 line 14-17은 그 요청이 경쟁한 현재 lock holder 쪽 call site 네 개다. Max con-bounces 지점이 통계에서 빠질 수 있다.

첫 lock인 &mm->mmap_sem은 read/write lock이므로 separator 위에 -W와 -R 두 줄이 있다. Contention point 줄은 main column과 형식이 다르고 count와 [<IP>] symbol 두 값을 가진다. 두 번째 point 묶음은 acquisition이 경쟁한 holder 지점을 나타낸다.

Time value의 정수 부분 단위는 microsecond다.

34 &rq->lock: 13128 13128 0.43 190.53 103881.26 7.91 97454 3453404 0.00 401.11 13224683.11 3.82
35 ---------
36 &rq->lock 645  [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
37 &rq->lock 297  [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
38 &rq->lock 360  [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a
39 &rq->lock 428  [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb
40 ---------
41 &rq->lock 77   [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
42 &rq->lock 174  [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
43 &rq->lock 4715 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
44 &rq->lock 893  [<ffffffff81340524>] schedule+0x157/0x7b8

48 &rq->lock/1: 1526 11488 0.33 388.73 136294.31 11.86 21461 38404 0.00 37.93 109388.53 2.84
49 -----------
50 &rq->lock/1 11526 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
51 -----------
52 &rq->lock/1 5645 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
53 &rq->lock/1 1224 [<ffffffff81340524>] schedule+0x157/0x7b8
54 &rq->lock/1 4336 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
55 &rq->lock/1 181  [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a

Line 48의 &rq->lock/1은 &rq->lock class의 두 번째 subclass다. Subclass index는 0부터 시작한다. Line 50의 double_rq_lock은 두 spinlock 중 nested lock을 실제로 획득하므로 /1로 구분된다.

동일한 잠금 클래스라도 `_nested()` API의 subclass가 다르면 `/0`, `/1`처럼 별도 행으로 출력됩니다. 예제의 `&rq->lock/1`은 두 번째 subclass를 뜻하며 subclass 번호는 0부터 시작합니다.

class 요약과 호출 지점 목록을 함께 읽어야 합니다. 클래스 전체 경합이 높아도 특정 acquirer 한 곳에 집중될 수 있고, 반대로 여러 작은 호출 지점이 합쳐져 병목이 될 수도 있으므로 횟수·시간·심볼을 교차 확인합니다.

호출 지점 역할
역할해석
Acquirer잠금을 얻으려다 대기한 호출 지점
Holder경합 순간 잠금을 보유한 호출 지점
Subclass같은 클래스의 계층적 획득 문맥

잠금 경합을 일으킨 두 쪽을 분리해 읽습니다.

Il primo blocco (righe dalla 05 alla 18) è di tipo lettura/scrittura e quindi
mostra due righe prima del divisore. I punti di contesa non corrispondono alla
descrizione delle colonne nell'intestazione; essi hanno due colonne: *punti di
contesa* e *[<IP>] simboli*. Il secondo gruppo di punti di contesa sono i punti
con cui si contende il blocco.

La parte interna del tempo è espressa in us (microsecondi).

Quando si ha a che fare con blocchi annidati si potrebbero vedere le
sottoclassi di blocco::

  32...........................................................................................................................................................................................................................
  33
  34                               &rq->lock:       13128          13128           0.43         190.53      103881.26           7.91          97454        3453404           0.00         401.11    13224683.11           3.82
  35                               ---------
  36                               &rq->lock          645          [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
  37                               &rq->lock          297          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
  38                               &rq->lock          360          [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a
  39                               &rq->lock          428          [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb
  40                               ---------
  41                               &rq->lock           77          [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
  42                               &rq->lock          174          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
  43                               &rq->lock         4715          [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
  44                               &rq->lock          893          [<ffffffff81340524>] schedule+0x157/0x7b8
  45
  46...........................................................................................................................................................................................................................
  47
  48                             &rq->lock/1:        1526          11488           0.33         388.73      136294.31          11.86          21461          38404           0.00          37.93      109388.53           2.84
  49                             -----------
  50                             &rq->lock/1        11526          [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
  51                             -----------
  52                             &rq->lock/1         5645          [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
  53                             &rq->lock/1         1224          [<ffffffff81340524>] schedule+0x157/0x7b8
  54                             &rq->lock/1         4336          [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
  55                             &rq->lock/1          181          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a

La riga 48 mostra le statistiche per la seconda sottoclasse (/1) della
classe *&irq->lock* (le sottoclassi partono da 0); in questo caso,
come suggerito dalla riga 50, ``double_rq_lock`` tenta di acquisire un blocco
annidato di due spinlock.

Per vedere i blocco più contesi::

상위 경합 잠금과 초기화

216-230
# show top contending locks
grep : /proc/lock_stat | head

clockevents_lock: ...
tick_broadcast_lock: ...
&mapping->i_mmap_mutex: ...
&rq->lock: ...
&(&zone->lru_lock)->rlock: ...
tasklist_lock-W: ...
tasklist_lock-R: ...
rcu_node_1: ...
&(&dentry->d_lockref.lock)->rlock: ...
rcu_node_0: ...

# clear statistics
echo 0 > /proc/lock_stat

grep으로 class summary 줄만 뽑고 head를 적용하면 출력 정렬 상태에서 상위 contention lock을 빠르게 볼 수 있다. /proc/lock_stat에 0을 쓰면 누적 통계를 초기화한다.

콜론이 들어간 클래스 요약 행을 추려 상위 항목만 보면 가장 큰 경합 후보를 빠르게 찾을 수 있습니다. 다만 횟수가 높은 잠금과 총 대기 시간이 큰 잠금은 다를 수 있으므로 한 열만으로 결론 내리지 않습니다.

`echo 0 > /proc/lock_stat`은 수집을 비활성화하는 동시에 현재 통계를 지워 다음 측정을 깨끗하게 시작하게 합니다. workload별 비교에서는 같은 활성화·실행·덤프·초기화 순서를 반복해야 수치가 섞이지 않습니다.

상위 경합 잠금 판독
관찰 항목판단 기준
클래스 요약 행contentions와 acquisitions뿐 아니라 waittime 및 holdtime의 합계·최대값을 함께 비교
상위 호출 지점반복 횟수와 symbol을 함께 확인해 획득자·경합자의 실제 경로 식별
측정 초기화`echo 0 > /proc/lock_stat`으로 기존 값을 지운 뒤 같은 workload 순서로 재측정

요약 출력과 호출 지점 출력에서 함께 확인할 항목을 정리했습니다.

  # grep : /proc/lock_stat | head
			clockevents_lock:       2926159        2947636           0.15       46882.81  1784540466.34         605.41        3381345        3879161           0.00        2260.97    53178395.68          13.71
		     tick_broadcast_lock:        346460         346717           0.18        2257.43    39364622.71         113.54        3642919        4242696           0.00        2263.79    49173646.60          11.59
		  &mapping->i_mmap_mutex:        203896         203899           3.36      645530.05 31767507988.39      155800.21        3361776        8893984           0.17        2254.15    14110121.02           1.59
			       &rq->lock:        135014         136909           0.18         606.09      842160.68           6.15        1540728       10436146           0.00         728.72    17606683.41           1.69
	       &(&zone->lru_lock)->rlock:         93000          94934           0.16          59.18      188253.78           1.98        1199912        3809894           0.15         391.40     3559518.81           0.93
			 tasklist_lock-W:         40667          41130           0.23        1189.42      428980.51          10.43         270278         510106           0.16         653.51     3939674.91           7.72
			 tasklist_lock-R:         21298          21305           0.20        1310.05      215511.12          10.12         186204         241258           0.14        1162.33     1179779.23           4.89
			      rcu_node_1:         47656          49022           0.16         635.41      193616.41           3.95         844888        1865423           0.00         764.26     1656226.96           0.89
       &(&dentry->d_lockref.lock)->rlock:         39791          40179           0.15        1302.08       88851.96           2.21        2790851       12527025           0.10        1910.75     3379714.27           0.27
			      rcu_node_0:         29203          30064           0.16         786.55     1555573.00          51.74          88963         244254           0.00         398.87      428872.51           1.76

Per cancellare le statistiche::

  # echo 0 > /proc/lock_stat