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

Linux 6.18.37 · Locking

Lock contention 통계 읽기

CONFIG_LOCK_STAT가 lockdep hook을 이용해 수집하는 wait·hold time, cacheline bounce와 contention call site를 읽는 방법을 설명합니다.

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

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

1. 요약·해설

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

Acquire와 release 사이의 측정 지점

lockstat.rst:5-42
그림 1. lock 함수와 lockstat hook의 측정 구간
__acquirelock__acquiredhold__releaseunlock
lock contention__contendedwait time__acquired

즉시 획득하면 __contended 경로를 거치지 않고 __acquired로 내려갑니다. 경쟁이 있으면 __contended에서 wait timer를 시작하고 __acquired에서 끝냅니다. 이후 __release까지가 hold time이며, acquire와 release hook은 같은 lock class의 통계로 합쳐집니다.

Lockstat는 lock function에 이미 들어 있는 lockdep hook과 class mapping을 재사용합니다. __contended에서 대기 시작을, __acquired에서 대기 종료와 보유 시작을, __release에서 보유 종료를 기록합니다. 수치는 lock instance가 아니라 class별로 모이며 read와 write state가 있으면 분리됩니다.

열 하나하나의 의미

lockstat.rst:43-82
항목해석
contentions즉시 획득하지 못하고 기다린 횟수
waittime min/max/total/avg획득 전 대기 시간 분포
acquisitions전체 획득 횟수
holdtime min/max/total/avg획득 후 release까지 보유 시간
con-bouncescontention이 CPU 간 cache data 이동을 동반한 횟수
acq-bounces획득이 CPU 간 cache data 이동을 동반한 횟수

평균만 보면 드문 긴 stall을 놓칠 수 있습니다. waittime-max가 latency spike와 맞는지, holdtime-max가 긴 critical section인지 owner preemption인지 함께 봐야 합니다. Bounce가 높으면 lock algorithm뿐 아니라 보호 데이터의 cacheline 배치와 CPU affinity도 점검합니다.

수집 활성화와 /proc/lock_stat

lockstat.rst:83-175
# CONFIG_LOCK_STAT=y kernel

echo 1 > /proc/sys/kernel/lock_stat
# workload 실행
less /proc/lock_stat
echo 0 > /proc/sys/kernel/lock_stat
그림 2. /proc/lock_stat에서 class 한 묶음을 읽는 위치
classbouncecontentionswait minwait maxwait totalwait avgacquisitions
mmap_sem-W46840.26939.1016371.53194.902,922,365
mmap_sem-R371001.31299502.6325629.523256.3034,316,685
Contention points__do_page_fault() 96회 · vm_mmap_pgoff() 34회
Contended pointsSyS_mprotect() 60회 · __do_page_fault() 41회

첫 행은 lock class의 집계값이고, read/write lock은 -R과 -W로 나뉩니다. 첫 separator 아래는 획득에 실패해 기다린 call site, 두 번째 separator 아래는 그때 lock을 보유하고 있던 call site입니다. waittime-max만 보고 끝내지 말고 어느 waiter와 owner 조합에서 발생했는지 함께 연결해야 합니다.

그림 3. 같은 class를 중첩 획득한 subclass /1
표시subclass대표 획득 위치의미
&rq->lock0task_rq_lock(), try_to_wake_up(), scheduler_tick()첫 번째 lock
&rq->lock/11double_rq_lock(), schedule(), try_to_wake_up()같은 class의 중첩 lock
공통 class keyC type은 같지만 선언된 nesting level에 따라 통계를 분리한다.

double_rq_lock()은 같은 rq lock class의 두 instance를 정해진 순서로 잡습니다. Lockdep subclass를 지정하면 lockstat도 두 번째 nesting level을 &rq->lock/1로 따로 집계합니다. /1은 다른 C type이라는 뜻이 아니라 같은 class의 중첩 위치가 1이라는 뜻입니다.

그림 4. contention이 큰 lock을 먼저 좁히는 출력
ranklock classcontentionswait totalwait avg
1clockevents_lock2,947,6361,784,540,466605.41
2tick_broadcast_lock346,71739,364,622113.54
3mapping i_mmap_mutex203,89931,767,507,988155,800.21
4rq lock136,909842,1606.15
5zone lru_lock94,934188,2531.98
해석 주의횟수 1위와 누적 대기 또는 평균 지연 1위는 서로 다를 수 있다.

정렬되지 않은 원본에서 head만 보는 것은 출발점일 뿐입니다. 횟수가 많은 lock, 누적 wait가 큰 lock, 한 번의 max wait가 긴 lock은 서로 다를 수 있습니다. 재현 workload를 고정하고 class를 고른 뒤 call-site 묶음으로 내려가야 원인과 개선 지점을 구분할 수 있습니다.

각 class 행 뒤에는 획득을 기다린 contention point와 당시 lock holder 측 contended point가 최대 네 곳씩 표시됩니다. symbol과 횟수를 함께 보아 hot call site를 찾습니다. 시간 값의 정수부 단위는 microsecond입니다.

Read/write lock은 -R과 -W 행으로 나뉘며 nested subclass는 class/1처럼 suffix가 붙습니다. double_rq_lock처럼 동일 class를 nested level로 잡는 경로를 별도 통계로 구분할 수 있습니다.

성능 분석 순서

lockstat.rst:176-205
  • 측정 전 echo 0으로 이전 통계를 지운다.
  • 재현 가능한 workload 구간만 echo 1로 수집한다.
  • contentions 수와 waittime-total로 전체 비용이 큰 class를 찾는다.
  • waittime-max와 contention symbol로 tail latency 원인을 찾는다.
  • holdtime과 acquisition 수를 함께 보고 lock 분할, batching, per-CPU화 또는 RCU 전환을 검토한다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ===============
2 Lock Statistics
3 ===============
4
5 What
6 ====
7
8 As the name suggests, it provides statistics on locks.
9
10
11 Why
12 ===
13
14 Because things like lock contention can severely impact performance.
15
16 How
17 ===
18
19 Lockdep already has hooks in the lock functions and maps lock instances to
20 lock classes. We build on that (see Documentation/locking/lockdep-design.rst).
21 The graph below shows the relation between the lock functions and the various
22 hooks therein::
23
24 __acquire
25 |
26 lock _____
27 | \
28 | __contended
29 | |
30 | <wait>
31 | _______/
32 |/
33 |
34 __acquired
35 |
36 .
37 <hold>
38 .
39 |
40 __release
41 |
42 unlock
43
44 lock, unlock - the regular lock functions
45 __* - the hooks
46 <> - states
47
48 With these hooks we provide the following statistics:
49
50 con-bounces
51 - number of lock contention that involved x-cpu data
52 contentions
53 - number of lock acquisitions that had to wait
54 wait time
55 min
56 - shortest (non-0) time we ever had to wait for a lock
57 max
58 - longest time we ever had to wait for a lock
59 total
60 - total time we spend waiting on this lock
61 avg
62 - average time spent waiting on this lock
63 acq-bounces
64 - number of lock acquisitions that involved x-cpu data
65 acquisitions
66 - number of times we took the lock
67 hold time
68 min
69 - shortest (non-0) time we ever held the lock
70 max
71 - longest time we ever held the lock
72 total
73 - total time this lock was held
74 avg
75 - average time this lock was held
76
77 These numbers are gathered per lock class, per read/write state (when
78 applicable).
79
80 It also tracks 4 contention points per class. A contention point is a call site
81 that had to wait on lock acquisition.
82
83 Configuration
84 -------------
85
86 Lock statistics are enabled via CONFIG_LOCK_STAT.
87
88 Usage
89 -----
90
91 Enable collection of statistics::
92
93 # echo 1 >/proc/sys/kernel/lock_stat
94
95 Disable collection of statistics::
96
97 # echo 0 >/proc/sys/kernel/lock_stat
98
99 Look at the current lock statistics::
100
101 ( line numbers not part of actual output, done for clarity in the explanation
102 below )
103
104 # less /proc/lock_stat
105
106 01 lock_stat version 0.4
107 02-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
108 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
109 04-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
110 05
111 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
112 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
113 08 ---------------
114 09 &mm->mmap_sem 1 [<ffffffff811502a7>] khugepaged_scan_mm_slot+0x57/0x280
115 10 &mm->mmap_sem 96 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
116 11 &mm->mmap_sem 34 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
117 12 &mm->mmap_sem 17 [<ffffffff81127e71>] vm_munmap+0x41/0x80
118 13 ---------------
119 14 &mm->mmap_sem 1 [<ffffffff81046fda>] dup_mmap+0x2a/0x3f0
120 15 &mm->mmap_sem 60 [<ffffffff81129e29>] SyS_mprotect+0xe9/0x250
121 16 &mm->mmap_sem 41 [<ffffffff815351c4>] __do_page_fault+0x1d4/0x510
122 17 &mm->mmap_sem 68 [<ffffffff81113d77>] vm_mmap_pgoff+0x87/0xd0
123 18
124 19.............................................................................................................................................................................................................................
125 20
126 21 unix_table_lock: 110 112 0.21 49.24 163.91 1.46 21094 66312 0.12 624.42 31589.81 0.48
127 22 ---------------
128 23 unix_table_lock 45 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
129 24 unix_table_lock 47 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
130 25 unix_table_lock 15 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
131 26 unix_table_lock 5 [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
132 27 ---------------
133 28 unix_table_lock 39 [<ffffffff8150b111>] unix_release_sock+0x31/0x250
134 29 unix_table_lock 49 [<ffffffff8150ad8e>] unix_create1+0x16e/0x1b0
135 30 unix_table_lock 20 [<ffffffff8150ca37>] unix_find_other+0x117/0x230
136 31 unix_table_lock 4 [<ffffffff8150a09f>] unix_autobind+0x11f/0x1b0
137
138
139 This excerpt shows the first two lock class statistics. Line 01 shows the
140 output version - each time the format changes this will be updated. Line 02-04
141 show the header with column descriptions. Lines 05-18 and 20-31 show the actual
142 statistics. These statistics come in two parts; the actual stats separated by a
143 short separator (line 08, 13) from the contention points.
144
145 Lines 09-12 show the first 4 recorded contention points (the code
146 which tries to get the lock) and lines 14-17 show the first 4 recorded
147 contended points (the lock holder). It is possible that the max
148 con-bounces point is missing in the statistics.
149
150 The first lock (05-18) is a read/write lock, and shows two lines above the
151 short separator. The contention points don't match the column descriptors,
152 they have two: contentions and [<IP>] symbol. The second set of contention
153 points are the points we're contending with.
154
155 The integer part of the time values is in us.
156
157 Dealing with nested locks, subclasses may appear::
158
159 32...........................................................................................................................................................................................................................
160 33
161 34 &rq->lock: 13128 13128 0.43 190.53 103881.26 7.91 97454 3453404 0.00 401.11 13224683.11 3.82
162 35 ---------
163 36 &rq->lock 645 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
164 37 &rq->lock 297 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
165 38 &rq->lock 360 [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a
166 39 &rq->lock 428 [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb
167 40 ---------
168 41 &rq->lock 77 [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
169 42 &rq->lock 174 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
170 43 &rq->lock 4715 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
171 44 &rq->lock 893 [<ffffffff81340524>] schedule+0x157/0x7b8
172 45
173 46...........................................................................................................................................................................................................................
174 47
175 48 &rq->lock/1: 1526 11488 0.33 388.73 136294.31 11.86 21461 38404 0.00 37.93 109388.53 2.84
176 49 -----------
177 50 &rq->lock/1 11526 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
178 51 -----------
179 52 &rq->lock/1 5645 [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
180 53 &rq->lock/1 1224 [<ffffffff81340524>] schedule+0x157/0x7b8
181 54 &rq->lock/1 4336 [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
182 55 &rq->lock/1 181 [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
183
184 Line 48 shows statistics for the second subclass (/1) of &rq->lock class
185 (subclass starts from 0), since in this case, as line 50 suggests,
186 double_rq_lock actually acquires a nested lock of two spinlocks.
187
188 View the top contending locks::
189
190 # grep : /proc/lock_stat | head
191 clockevents_lock: 2926159 2947636 0.15 46882.81 1784540466.34 605.41 3381345 3879161 0.00 2260.97 53178395.68 13.71
192 tick_broadcast_lock: 346460 346717 0.18 2257.43 39364622.71 113.54 3642919 4242696 0.00 2263.79 49173646.60 11.59
193 &mapping->i_mmap_mutex: 203896 203899 3.36 645530.05 31767507988.39 155800.21 3361776 8893984 0.17 2254.15 14110121.02 1.59
194 &rq->lock: 135014 136909 0.18 606.09 842160.68 6.15 1540728 10436146 0.00 728.72 17606683.41 1.69
195 &(&zone->lru_lock)->rlock: 93000 94934 0.16 59.18 188253.78 1.98 1199912 3809894 0.15 391.40 3559518.81 0.93
196 tasklist_lock-W: 40667 41130 0.23 1189.42 428980.51 10.43 270278 510106 0.16 653.51 3939674.91 7.72
197 tasklist_lock-R: 21298 21305 0.20 1310.05 215511.12 10.12 186204 241258 0.14 1162.33 1179779.23 4.89
198 rcu_node_1: 47656 49022 0.16 635.41 193616.41 3.95 844888 1865423 0.00 764.26 1656226.96 0.89
199 &(&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
200 rcu_node_0: 29203 30064 0.16 786.55 1555573.00 51.74 88963 244254 0.00 398.87 428872.51 1.76
201
202 Clear the statistics::
203
204 # echo 0 > /proc/lock_stat
205

3. 한국어 전문 번역

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

Lock 통계가 필요한 이유

1-20

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

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

Lock lifecycle과 hook

21-47

원문의 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

48-81
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도 네 개까지 추적한다.

CONFIG_LOCK_STAT과 runtime control

83-99

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

/proc/lock_stat 출력 구조

101-136
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의 실제 통계다.

Acquirer와 holder call site

139-155

각 통계는 짧은 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다.

Nested lock subclass

157-186
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로 구분된다.

상위 contention lock과 통계 초기화

188-204
# 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을 쓰면 누적 통계를 초기화한다.