요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
============================
Glock internal locking rules
============================
This documents the basic principles of the glock state machine
internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
has two main (internal) locks:
1. A spinlock (gl_lockref.lock) which protects the internal state such
as gl_state, gl_target and the list of holders (gl_holders)
2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
threads from making calls to the DLM, etc. at the same time. If a
thread takes this lock, it must then call run_queue (usually via the
workqueue) when it releases it in order to ensure any pending tasks
are completed.
The gl_holders list contains all the queued lock requests (not
just the holders) associated with the glock. If there are any
held locks, then they will be contiguous entries at the head
of the list. Locks are granted in strictly the order that they
are queued.
There are three lock states that users of the glock layer can request,
namely shared (SH), deferred (DF) and exclusive (EX). Those translate
to the following DLM lock modes:
========== ====== =====================================================
Glock mode DLM lock mode
========== ====== =====================================================
UN IV/NL Unlocked (no DLM lock associated with glock) or NL
SH PR (Protected read)
DF CW (Concurrent write)
EX EX (Exclusive)
========== ====== =====================================================
Thus DF is basically a shared mode which is incompatible with the "normal"
shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
operations. The glocks are basically a lock plus some routines which deal
with cache management. The following rules apply for the cache:
========== ============== ========== ========== ==============
Glock mode Cache Metadata Cache data Dirty Data Dirty Metadata
========== ============== ========== ========== ==============
UN No No No No
DF Yes No No No
SH Yes Yes No No
EX Yes Yes Yes Yes
========== ============== ========== ========== ==============
These rules are implemented using the various glock operations which
are defined for each type of glock. Not all types of glocks use
all the modes. Only inode glocks use the DF mode for example.
Table of glock operations and per type constants:
============== =============================================================
Field Purpose
============== =============================================================
go_sync Called before remote state change (e.g. to sync dirty data)
go_xmote_bh Called after remote state change (e.g. to refill cache)
go_inval Called if remote state change requires invalidating the cache
go_instantiate Called when a glock has been acquired
go_held Called every time a glock holder is acquired
go_dump Called to print content of object for debugfs file, or on
error to dump glock to the log.
go_callback Called if the DLM sends a callback to drop this lock
go_unlocked Called when a glock is unlocked (dlm_unlock())
go_type The type of the glock, ``LM_TYPE_*``
go_flags GLOF_ASPACE is set, if the glock has an address space
associated with it
============== =============================================================
The minimum hold time for each lock is the time after a remote lock
grant for which we ignore remote demote requests. This is in order to
prevent a situation where locks are being bounced around the cluster
from node to node with none of the nodes making any progress. This
tends to show up most with shared mmapped files which are being written
to by multiple nodes. By delaying the demotion in response to a
remote callback, that gives the userspace program time to make
some progress before the pages are unmapped.
Eventually, we hope to make the glock "EX" mode locally shared such that any
local locking will be done with the i_mutex as required rather than via the
glock.
Locking rules for glock operations:
============== ====================== =============================
Operation GLF_LOCK bit lock held gl_lockref.lock spinlock held
============== ====================== =============================
go_sync Yes No
go_xmote_bh Yes No
go_inval Yes No
go_instantiate No No
go_held No No
go_dump Sometimes Yes
go_callback Sometimes (N/A) Yes
go_unlocked Yes No
============== ====================== =============================
.. Note::
Operations must not drop either the bit lock or the spinlock
if its held on entry. go_dump and do_demote_ok must never block.
Note that go_dump will only be called if the glock's state
indicates that it is caching up-to-date data.
Glock locking order within GFS2:
1. i_rwsem (if required)
2. Rename glock (for rename only)
3. Inode glock(s)
(Parents before children, inodes at "same level" with same parent in
lock number order)
4. Rgrp glock(s) (for (de)allocation operations)
5. Transaction glock (via gfs2_trans_begin) for non-read operations
6. i_rw_mutex (if required)
7. Page lock (always last, very important!)
There are two glocks per inode. One deals with access to the inode
itself (locking order as above), and the other, known as the iopen
glock is used in conjunction with the i_nlink field in the inode to
determine the lifetime of the inode in question. Locking of inodes
is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
In general we prefer to lock local locks prior to cluster locks.
Glock Statistics
----------------
The stats are divided into two sets: those relating to the
super block and those relating to an individual glock. The
super block stats are done on a per cpu basis in order to
try and reduce the overhead of gathering them. They are also
further divided by glock type. All timings are in nanoseconds.
In the case of both the super block and glock statistics,
the same information is gathered in each case. The super
block timing statistics are used to provide default values for
the glock timing statistics, so that newly created glocks
should have, as far as possible, a sensible starting point.
The per-glock counters are initialised to zero when the
glock is created. The per-glock statistics are lost when
the glock is ejected from memory.
The statistics are divided into three pairs of mean and
variance, plus two counters. The mean/variance pairs are
smoothed exponential estimates and the algorithm used is
one which will be very familiar to those used to calculation
of round trip times in network code. See "TCP/IP Illustrated,
Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement",
p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards.
Unlike the TCP/IP Illustrated case, the mean and variance are
not scaled, but are in units of integer nanoseconds.
The three pairs of mean/variance measure the following
things:
1. DLM lock time (non-blocking requests)
2. DLM lock time (blocking requests)
3. Inter-request time (again to the DLM)
A non-blocking request is one which will complete right
away, whatever the state of the DLM lock in question. That
currently means any requests when (a) the current state of
the lock is exclusive, i.e. a lock demotion (b) the requested
state is either null or unlocked (again, a demotion) or (c) the
"try lock" flag is set. A blocking request covers all the other
lock requests.
There are two counters. The first is there primarily to show
how many lock requests have been made, and thus how much data
has gone into the mean/variance calculations. The other counter
is counting queuing of holders at the top layer of the glock
code. Hopefully that number will be a lot larger than the number
of dlm lock requests issued.
So why gather these statistics? There are several reasons
we'd like to get a better idea of these timings:
1. To be able to better set the glock "min hold time"
2. To spot performance issues more easily
3. To improve the algorithm for selecting resource groups for
allocation (to base it on lock wait time, rather than blindly
using a "try lock")
Due to the smoothing action of the updates, a step change in
some input quantity being sampled will only fully be taken
into account after 8 samples (or 4 for the variance) and this
needs to be carefully considered when interpreting the
results.
Knowing both the time it takes a lock request to complete and
the average time between lock requests for a glock means we
can compute the total percentage of the time for which the
node is able to use a glock vs. time that the rest of the
cluster has its share. That will be very useful when setting
the lock min hold time.
Great care has been taken to ensure that we
measure exactly the quantities that we want, as accurately
as possible. There are always inaccuracies in any
measuring system, but I hope this is as accurate as we
can reasonably make it.
Per sb stats can be found here::
/sys/kernel/debug/gfs2/<fsname>/sbstats
Per glock stats can be found here::
/sys/kernel/debug/gfs2/<fsname>/glstats
Assuming that debugfs is mounted on /sys/kernel/debug and also
that <fsname> is replaced with the name of the gfs2 filesystem
in question.
The abbreviations used in the output as are follows:
========= ================================================================
srtt Smoothed round trip time for non blocking dlm requests
srttvar Variance estimate for srtt
srttb Smoothed round trip time for (potentially) blocking dlm requests
srttvarb Variance estimate for srttb
sirt Smoothed inter request time (for dlm requests)
sirtvar Variance estimate for sirt
dlm Number of dlm requests made (dcnt in glstats file)
queue Number of glock requests queued (qcnt in glstats file)
========= ================================================================
The sbstats file contains a set of these stats for each glock type (so 8 lines
for each type) and for each cpu (one column per cpu). The glstats file contains
a set of these stats for each glock in a similar format to the glocks file, but
using the format mean/variance for each of the timing stats.
The gfs2_glock_lock_time tracepoint prints out the current values of the stats
for the glock in question, along with some addition information on each dlm
reply that is received:
====== =======================================
status The status of the dlm request
flags The dlm request flags
tdiff The time taken by this specific request
====== =======================================
(remaining fields as per above list)
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Glock 내부 lock, state와 cache 규칙
1-55이 문서는 glock state machine 내부의 기본 원칙을 설명합니다. 각 glock은 `fs/gfs2/incore.h`의 `struct gfs2_glock`이며 두 가지 주요 내부 lock을 가집니다.
첫째 `gl_lockref.lock` spinlock은 `gl_state`, `gl_target`, holder list `gl_holders` 같은 내부 상태를 보호합니다.
둘째 non-blocking bit lock `GLF_LOCK`은 여러 thread가 동시에 DLM 호출 등을 수행하지 못하게 합니다. 이 lock을 획득한 thread는 해제할 때 pending task가 완료되도록 보통 workqueue를 통해 `run_queue`를 호출해야 합니다.
`gl_holders`에는 실제 holder뿐 아니라 glock과 연결된 queue의 모든 lock request가 들어갑니다. held lock이 있다면 list 머리에서 연속한 entry로 배치됩니다. lock은 queue에 들어온 순서를 엄격하게 따라 grant됩니다.
glock layer 사용자가 요청할 수 있는 state는 shared `SH`, deferred `DF`, exclusive `EX` 세 가지이며, unlocked `UN`을 포함해 DLM mode와 대응됩니다.
`DF`는 일반 shared mode `SH`와 호환되지 않는 shared 계열 mode입니다. GFS2에서는 direct I/O operation에만 DF를 사용합니다.
glock은 단순 lock에 cache management routine을 결합한 객체입니다. UN에서는 metadata·data cache와 dirty data·metadata가 모두 허용되지 않습니다. DF는 clean metadata cache만, SH는 clean metadata와 data cache를 허용합니다. EX는 dirty 여부를 포함한 모든 cache를 허용합니다.
각 glock type에 정의된 operation이 이 규칙을 구현합니다. 모든 glock type이 모든 mode를 쓰지는 않으며 예를 들어 DF는 inode glock만 사용합니다.
내부 state와 cluster DLM lock mode의 대응입니다.
mode별 cache·dirty 상태 규칙입니다.
.. SPDX-License-Identifier: GPL-2.0
============================
Glock internal locking rules
============================
This documents the basic principles of the glock state machine
internals. Each glock (struct gfs2_glock in fs/gfs2/incore.h)
has two main (internal) locks:
1. A spinlock (gl_lockref.lock) which protects the internal state such
as gl_state, gl_target and the list of holders (gl_holders)
2. A non-blocking bit lock, GLF_LOCK, which is used to prevent other
threads from making calls to the DLM, etc. at the same time. If a
thread takes this lock, it must then call run_queue (usually via the
workqueue) when it releases it in order to ensure any pending tasks
are completed.
The gl_holders list contains all the queued lock requests (not
just the holders) associated with the glock. If there are any
held locks, then they will be contiguous entries at the head
of the list. Locks are granted in strictly the order that they
are queued.
There are three lock states that users of the glock layer can request,
namely shared (SH), deferred (DF) and exclusive (EX). Those translate
to the following DLM lock modes:
========== ====== =====================================================
Glock mode DLM lock mode
========== ====== =====================================================
UN IV/NL Unlocked (no DLM lock associated with glock) or NL
SH PR (Protected read)
DF CW (Concurrent write)
EX EX (Exclusive)
========== ====== =====================================================
Thus DF is basically a shared mode which is incompatible with the "normal"
shared lock mode, SH. In GFS2 the DF mode is used exclusively for direct I/O
operations. The glocks are basically a lock plus some routines which deal
with cache management. The following rules apply for the cache:
========== ============== ========== ========== ==============
Glock mode Cache Metadata Cache data Dirty Data Dirty Metadata
========== ============== ========== ========== ==============
UN No No No No
DF Yes No No No
SH Yes Yes No No
EX Yes Yes Yes Yes
========== ============== ========== ========== ==============
These rules are implemented using the various glock operations which
are defined for each type of glock. Not all types of glocks use
all the modes. Only inode glocks use the DF mode for example.
Glock operation, hold time과 lock 순서
56-128`go_sync`는 remote state change 전에 dirty data를 sync하는 등의 작업에 호출됩니다. `go_xmote_bh`는 remote state change 뒤 cache를 다시 채우는 등의 작업, `go_inval`은 state change에 cache invalidation이 필요할 때 호출됩니다.
`go_instantiate`는 glock 획득 시, `go_held`는 holder가 획득될 때마다 호출됩니다. `go_dump`는 debugfs file에 object 내용을 출력하거나 error 때 log로 glock을 dump합니다.
`go_callback`은 DLM이 lock을 내리라는 callback을 보낼 때, `go_unlocked`는 `dlm_unlock()`으로 glock이 unlock될 때 호출됩니다. `go_type`은 `LM_TYPE_*` glock type이고 `go_flags`의 `GLOF_ASPACE`는 glock에 address space가 연결됐음을 뜻합니다.
각 lock의 minimum hold time은 remote grant 뒤 remote demote request를 무시하는 기간입니다. lock이 node 사이를 계속 왕복해 어느 node도 진행하지 못하는 상황을 막습니다.
이 문제는 여러 node가 쓰는 shared mmap file에서 주로 나타납니다. remote callback에 따른 demotion을 늦추면 page가 unmap되기 전에 사용자 공간 program이 어느 정도 진행할 시간을 얻습니다.
향후에는 glock `EX` mode를 local에서 shared로 만들어 필요한 local locking은 glock이 아니라 `i_mutex`로 수행하는 것이 목표입니다.
operation별 내부 lock 조건은 엄격합니다. `go_sync`, `go_xmote_bh`, `go_inval`, `go_unlocked`는 `GLF_LOCK`을 보유하고 spinlock은 보유하지 않습니다. `go_instantiate`와 `go_held`는 둘 다 보유하지 않습니다. `go_dump`와 `go_callback`은 spinlock을 보유하며 bit lock은 경우에 따라 보유합니다.
operation은 entry 시 보유한 bit lock이나 spinlock을 놓으면 안 됩니다. `go_dump`와 `do_demote_ok`는 절대 block하면 안 됩니다. `go_dump`는 glock state가 최신 cache data를 보유한다고 나타낼 때만 호출됩니다.
GFS2의 lock 순서는 `i_rwsem`, rename 전용 Rename glock, inode glock, allocation용 rgrp glock, non-read operation의 `gfs2_trans_begin` transaction glock, `i_rw_mutex`, page lock 순입니다. page lock은 반드시 마지막이어야 합니다.
inode glock은 parent를 child보다 먼저 잡고 같은 parent·같은 level inode는 lock number 순서로 잡습니다. inode마다 glock 두 개가 있으며 하나는 inode 자체 접근, 다른 `iopen` glock은 inode `i_nlink`와 함께 inode 수명을 결정합니다.
inode locking은 inode 단위, rgrp locking은 rgrp 단위입니다. 일반 원칙은 cluster lock보다 local lock을 먼저 잡는 것입니다.
entry 시 bit lock과 spinlock 보유 상태입니다.
deadlock 방지를 위해 반드시 지켜야 하는 획득 순서입니다.
Table of glock operations and per type constants:
============== =============================================================
Field Purpose
============== =============================================================
go_sync Called before remote state change (e.g. to sync dirty data)
go_xmote_bh Called after remote state change (e.g. to refill cache)
go_inval Called if remote state change requires invalidating the cache
go_instantiate Called when a glock has been acquired
go_held Called every time a glock holder is acquired
go_dump Called to print content of object for debugfs file, or on
error to dump glock to the log.
go_callback Called if the DLM sends a callback to drop this lock
go_unlocked Called when a glock is unlocked (dlm_unlock())
go_type The type of the glock, ``LM_TYPE_*``
go_flags GLOF_ASPACE is set, if the glock has an address space
associated with it
============== =============================================================
The minimum hold time for each lock is the time after a remote lock
grant for which we ignore remote demote requests. This is in order to
prevent a situation where locks are being bounced around the cluster
from node to node with none of the nodes making any progress. This
tends to show up most with shared mmapped files which are being written
to by multiple nodes. By delaying the demotion in response to a
remote callback, that gives the userspace program time to make
some progress before the pages are unmapped.
Eventually, we hope to make the glock "EX" mode locally shared such that any
local locking will be done with the i_mutex as required rather than via the
glock.
Locking rules for glock operations:
============== ====================== =============================
Operation GLF_LOCK bit lock held gl_lockref.lock spinlock held
============== ====================== =============================
go_sync Yes No
go_xmote_bh Yes No
go_inval Yes No
go_instantiate No No
go_held No No
go_dump Sometimes Yes
go_callback Sometimes (N/A) Yes
go_unlocked Yes No
============== ====================== =============================
.. Note::
Operations must not drop either the bit lock or the spinlock
if its held on entry. go_dump and do_demote_ok must never block.
Note that go_dump will only be called if the glock's state
indicates that it is caching up-to-date data.
Glock locking order within GFS2:
1. i_rwsem (if required)
2. Rename glock (for rename only)
3. Inode glock(s)
(Parents before children, inodes at "same level" with same parent in
lock number order)
4. Rgrp glock(s) (for (de)allocation operations)
5. Transaction glock (via gfs2_trans_begin) for non-read operations
6. i_rw_mutex (if required)
7. Page lock (always last, very important!)
There are two glocks per inode. One deals with access to the inode
itself (locking order as above), and the other, known as the iopen
glock is used in conjunction with the i_nlink field in the inode to
determine the lifetime of the inode in question. Locking of inodes
is on a per-inode basis. Locking of rgrps is on a per rgrp basis.
In general we prefer to lock local locks prior to cluster locks.
Glock timing 통계의 계산과 사용
129-206통계는 superblock 관련 집합과 개별 glock 관련 집합으로 나뉩니다. superblock 통계는 수집 overhead를 줄이기 위해 per-CPU이고 glock type별로도 나뉩니다. 모든 timing 단위는 nanosecond입니다.
두 집합은 같은 정보를 수집합니다. superblock timing은 새 glock이 가능한 한 합리적인 초기값을 갖도록 per-glock timing의 default로 사용됩니다. per-glock counter는 glock 생성 시 0이고 glock이 memory에서 eject되면 통계도 사라집니다.
통계는 mean·variance 세 쌍과 counter 두 개입니다. mean·variance는 network round-trip time 계산에서 익숙한 smoothed exponential estimate를 사용합니다. 참고는 W. Richard Stevens의 TCP/IP Illustrated Volume 1 21.3절과 Volume 2 25.10절입니다.
TCP/IP 예시와 달리 mean과 variance는 scale하지 않고 integer nanosecond 단위 그대로 저장합니다.
세 쌍은 non-blocking DLM lock time, blocking DLM lock time, DLM inter-request time을 측정합니다.
non-blocking request는 현재 DLM lock state와 관계없이 즉시 완료되는 request입니다. 현재 lock이 EX여서 demotion하는 경우, 요청 state가 null 또는 unlocked여서 demotion하는 경우, `try lock` flag가 설정된 경우가 해당합니다. 나머지는 blocking request입니다.
첫 counter는 DLM lock request 수를 세어 mean·variance 계산에 들어간 sample 양을 나타냅니다. 둘째는 glock 상위 계층의 holder queue 횟수입니다. 이상적으로 holder queue 수는 실제 DLM request 수보다 훨씬 커야 local reuse가 잘 된 것입니다.
이 통계를 수집하는 목적은 glock minimum hold time을 더 잘 설정하고, performance issue를 쉽게 찾고, resource group allocation 선택을 단순 try-lock이 아니라 lock wait time에 기반하도록 개선하는 것입니다.
smoothing 때문에 sample quantity가 step change해도 8 sample 뒤에야 mean에 완전히 반영되고 variance는 4 sample이 걸립니다. 결과를 해석할 때 이 지연을 고려해야 합니다.
lock request 완료 시간과 같은 glock의 평균 request 간격을 알면 해당 node가 glock을 사용할 수 있는 시간과 cluster 나머지가 공유하는 시간의 비율을 계산할 수 있습니다. 이는 minimum hold time 설정에 유용합니다.
측정 시스템에는 항상 오차가 있지만 필요한 quantity를 최대한 정확히 측정하도록 세심하게 설계됐습니다.
세 timing 쌍과 두 counter가 의미하는 값입니다.
관측값이 lock bounce 완화에 쓰이는 경로입니다.
Glock Statistics
----------------
The stats are divided into two sets: those relating to the
super block and those relating to an individual glock. The
super block stats are done on a per cpu basis in order to
try and reduce the overhead of gathering them. They are also
further divided by glock type. All timings are in nanoseconds.
In the case of both the super block and glock statistics,
the same information is gathered in each case. The super
block timing statistics are used to provide default values for
the glock timing statistics, so that newly created glocks
should have, as far as possible, a sensible starting point.
The per-glock counters are initialised to zero when the
glock is created. The per-glock statistics are lost when
the glock is ejected from memory.
The statistics are divided into three pairs of mean and
variance, plus two counters. The mean/variance pairs are
smoothed exponential estimates and the algorithm used is
one which will be very familiar to those used to calculation
of round trip times in network code. See "TCP/IP Illustrated,
Volume 1", W. Richard Stevens, sect 21.3, "Round-Trip Time Measurement",
p. 299 and onwards. Also, Volume 2, Sect. 25.10, p. 838 and onwards.
Unlike the TCP/IP Illustrated case, the mean and variance are
not scaled, but are in units of integer nanoseconds.
The three pairs of mean/variance measure the following
things:
1. DLM lock time (non-blocking requests)
2. DLM lock time (blocking requests)
3. Inter-request time (again to the DLM)
A non-blocking request is one which will complete right
away, whatever the state of the DLM lock in question. That
currently means any requests when (a) the current state of
the lock is exclusive, i.e. a lock demotion (b) the requested
state is either null or unlocked (again, a demotion) or (c) the
"try lock" flag is set. A blocking request covers all the other
lock requests.
There are two counters. The first is there primarily to show
how many lock requests have been made, and thus how much data
has gone into the mean/variance calculations. The other counter
is counting queuing of holders at the top layer of the glock
code. Hopefully that number will be a lot larger than the number
of dlm lock requests issued.
So why gather these statistics? There are several reasons
we'd like to get a better idea of these timings:
1. To be able to better set the glock "min hold time"
2. To spot performance issues more easily
3. To improve the algorithm for selecting resource groups for
allocation (to base it on lock wait time, rather than blindly
using a "try lock")
Due to the smoothing action of the updates, a step change in
some input quantity being sampled will only fully be taken
into account after 8 samples (or 4 for the variance) and this
needs to be carefully considered when interpreting the
results.
Knowing both the time it takes a lock request to complete and
the average time between lock requests for a glock means we
can compute the total percentage of the time for which the
node is able to use a glock vs. time that the rest of the
cluster has its share. That will be very useful when setting
the lock min hold time.
Great care has been taken to ensure that we
measure exactly the quantities that we want, as accurately
as possible. There are always inaccuracies in any
measuring system, but I hope this is as accurate as we
can reasonably make it.
Debugfs 통계와 tracepoint 출력
207-249per-superblock 통계는 debugfs가 `/sys/kernel/debug`에 마운트됐다는 전제에서 `/sys/kernel/debug/gfs2/<fsname>/sbstats`에 있습니다.
per-glock 통계는 `/sys/kernel/debug/gfs2/<fsname>/glstats`에 있으며 `<fsname>`은 대상 GFS2 filesystem name으로 바꿉니다.
`srtt`는 non-blocking DLM request의 smoothed round-trip time, `srttvar`는 그 variance estimate입니다. `srttb`와 `srttvarb`는 potentially blocking DLM request에 대응합니다.
`sirt`는 DLM request의 smoothed inter-request time, `sirtvar`는 variance estimate입니다. `dlm`은 실제 DLM request 수로 glstats의 `dcnt`, `queue`는 queued glock request 수로 `qcnt`입니다.
`sbstats`는 각 glock type마다 이 통계 8개를 각 CPU column으로 제공합니다. `glstats`는 glocks file과 비슷한 형식으로 각 glock의 통계를 담고 timing 값은 mean/variance 형식입니다.
`gfs2_glock_lock_time` tracepoint는 DLM reply를 받을 때 해당 glock의 현재 통계와 추가 정보를 출력합니다. `status`는 DLM request status, `flags`는 request flags, `tdiff`는 해당 request가 걸린 시간이며 나머지 field는 앞선 목록과 같습니다.
debugfs와 tracepoint에서 쓰는 이름입니다.
scope별 파일과 출력 형식입니다.
Per sb stats can be found here::
/sys/kernel/debug/gfs2/<fsname>/sbstats
Per glock stats can be found here::
/sys/kernel/debug/gfs2/<fsname>/glstats
Assuming that debugfs is mounted on /sys/kernel/debug and also
that <fsname> is replaced with the name of the gfs2 filesystem
in question.
The abbreviations used in the output as are follows:
========= ================================================================
srtt Smoothed round trip time for non blocking dlm requests
srttvar Variance estimate for srtt
srttb Smoothed round trip time for (potentially) blocking dlm requests
srttvarb Variance estimate for srttb
sirt Smoothed inter request time (for dlm requests)
sirtvar Variance estimate for sirt
dlm Number of dlm requests made (dcnt in glstats file)
queue Number of glock requests queued (qcnt in glstats file)
========= ================================================================
The sbstats file contains a set of these stats for each glock type (so 8 lines
for each type) and for each cpu (one column per cpu). The glstats file contains
a set of these stats for each glock in a similar format to the glocks file, but
using the format mean/variance for each of the timing stats.
The gfs2_glock_lock_time tracepoint prints out the current values of the stats
for the glock in question, along with some addition information on each dlm
reply that is received:
====== =======================================
status The status of the dlm request
flags The dlm request flags
tdiff The time taken by this specific request
====== =======================================
(remaining fields as per above list)
요약·해설
gfs2-glocks.rst:1-249GFS2 glock은 `gl_lockref.lock`으로 내부 state를 보호하고 `GLF_LOCK`으로 DLM 전환을 직렬화합니다. SH·DF·EX state는 cache 가능 범위를 결정하고 type별 `go_*` operation이 sync·invalidate·callback을 수행합니다.
cluster deadlock 방지를 위해 local lock을 cluster lock보다 먼저, page lock을 마지막에 잡습니다. per-CPU superblock 통계와 per-glock 통계는 DLM 지연과 request locality를 smoothing해 minimum hold time과 resource group 선택을 개선합니다.
request queue에서 통계 기반 hold time 조정까지의 흐름입니다.