Docs/zh_CN: Translate gfs2-glocks.rst to Simplified Chinese

translate the "gfs2-glocks.rst" into Simplified Chinese.

Update to commit 713f8834389f("gfs2: Get rid of emote_ok
checks")

Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Signed-off-by: yang tao <yang.tao172@zte.com.cn>
Signed-off-by: Alex Shi <alexs@kernel.org>
This commit is contained in:
Shao Mingyin
2025-08-26 19:07:19 +08:00
committed by Alex Shi
parent a1cce3f467
commit 1c8e194113
2 changed files with 200 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
.. SPDX-License-Identifier: GPL-2.0
==================
Glock 内部加锁规则
==================
本文档阐述 glock 状态机内部运作的基本原理。每个 glock
fs/gfs2/incore.h 中的 struct gfs2_glock包含两把主要的内部锁
1. 自旋锁gl_lockref.lock用于保护内部状态
gl_state、gl_target和持有者列表gl_holders
2. 非阻塞的位锁GLF_LOCK用于防止其他线程同时调用
DLM 等操作。若某线程获取此锁,则在释放时必须调用
run_queue通常通过工作队列以确保所有待处理任务
得以完成。
gl_holders 列表包含与该 glock 关联的所有排队锁请求(不
仅是持有者)。若存在已持有的锁,它们将位于列表开头的连
续条目中。锁的授予严格遵循排队顺序。
glock 层用户可请求三种锁状态共享SH、延迟DF
排他EX。它们对应以下 DLM 锁模式:
========== ====== =====================================================
Glock 模式 DLM 锁模式
========== ====== =====================================================
UN IV/NL 未加锁(无关联的 DLM 锁)或 NL
SH PR 受保护读Protected read
DF CW 并发写Concurrent write
EX EX 排他Exclusive
========== ====== =====================================================
因此DF 本质上是一种与“常规”共享锁模式SH互斥的共
享模式。在 GFS2 中DF 模式专用于直接 I/O 操作。Glock
本质上是锁加缓存管理例程的组合,其缓存规则如下:
========== ============== ========== ========== ==============
Glock 模式 缓存元数据 缓存数据 脏数据 脏元数据
========== ============== ========== ========== ==============
UN 否 否 否 否
DF 是 否 否 否
SH 是 是 否 否
EX 是 是 是 是
========== ============== ========== ========== ==============
这些规则通过为每种 glock 定义的操作函数实现。并非所有
glock 类型都使用全部的模式,例如仅 inode glock 使用 DF 模
式。
glock 操作函数及类型常量说明表:
============== ========================================================
字段 用途
============== ========================================================
go_sync 远程状态变更前调用(如同步脏数据)
go_xmote_bh 远程状态变更后调用(如刷新缓存)
go_inval 远程状态变更需使缓存失效时调用
go_instantiate 获取 glock 时调用
go_held 每次获取 glock 持有者时调用
go_dump 为 debugfs 文件打印对象内容,或出错时将 glock 转储至日志
go_callback 若 DLM 发送回调以释放此锁时调用
go_unlocked 当 glock 解锁时调用dlm_unlock()
go_type glock 类型,``LM_TYPE_*``
go_flags 若 glock 关联地址空间则设置GLOF_ASPACE 标志
============== ========================================================
每种锁的最短持有时间是指在远程锁授予后忽略远程降级请求
的时间段。此举旨在防止锁在集群节点间持续弹跳而无实质进
展的情况,此现象常见于多节点写入的共享内存映射文件。通
过延迟响应远程回调的降级操作,为用户空间程序争取页面取
消映射前的处理时间。
未来计划将 glock 的 "EX" 模式设为本地共享,使本地锁通
过 i_mutex 实现而非 glock。
glock 操作函数的加锁规则:
============== ====================== =============================
操作 GLF_LOCK 位锁持有 gl_lockref.lock 自旋锁持有
============== ====================== =============================
go_sync 是 否
go_xmote_bh 是 否
go_inval 是 否
go_instantiate 否 否
go_held 否 否
go_dump 有时 是
go_callback 有时N/A
go_unlocked 是 否
============== ====================== =============================
.. Note::
若入口处持有锁则操作期间不得释放位锁或自旋锁。
go_dump 和 do_demote_ok 严禁阻塞。
仅当 glock 状态指示其缓存最新数据时才会调用 go_dump。
GFS2 内部的 glock 加锁顺序:
1. i_rwsem如需要
2. 重命名 glock仅用于重命名
3. Inode glock
(父级优先于子级,同级 inode 按锁编号排序)
4. Rgrp glock用于分配操作
5. 事务 glock通过 gfs2_trans_begin非读操作
6. i_rw_mutex如需要
7. 页锁(始终最后,至关重要!)
每个 inode 对应两把 glock一把管理 inode 本身(加锁顺
序如上),另一把(称为 iopen glock结合 inode 的
i_nlink 字段决定 inode 生命周期。inode 加锁基于单个
inodergrp 加锁基于单个 rgrp。通常优先获取本地锁再获
取集群锁。
Glock 统计
----------
统计分为两类:超级块相关统计和单个 glock 相关统计。超级
块统计按每 CPU 执行以减少收集开销,并进一步按 glock 类
型细分。所有时间单位为纳秒。
超级块和 glock 统计收集相同信息。超级块时序统计为 glock
时序统计提供默认值,使新建 glock 具有合理的初始值。每个
glock 的计数器在创建时初始化为零,当 glock 从内存移除时
统计丢失。
统计包含三组均值/方差对及两个计数器。均值/方差对为平滑
指数估计,算法与网络代码中的往返时间计算类似(参见《
TCP/IP详解 卷1》第21.3节及《卷2》第25.10节)。与 TCP/IP
案例不同,此处均值/方差未缩放且单位为整数纳秒。
三组均值/方差对测量以下内容:
1. DLM 锁时间(非阻塞请求)
2. DLM 锁时间(阻塞请求)
3. 请求间隔时间(指向 DLM
非阻塞请求指无论目标 DLM 锁处于何种状态均能立即完成的请求。
当前满足条件的请求包括:(a)锁当前状态为互斥(如锁降级)、
(b)请求状态为空置或解锁(同样如锁降级)、或(c)设置"try lock"
标志的请求。其余锁请求均属阻塞请求。
两个计数器分别统计:
1. 锁请求总数(决定均值/方差计算的数据量)
2. glock 代码顶层的持有者排队数(通常远大于 DLM 锁请求数)
为什么收集这些统计数据?我们需深入分析时序参数的动因如下:
1. 更精准设置 glock "最短持有时间"
2. 快速识别性能问题
3. 改进资源组分配算法(基于锁等待时间而非盲目 "try lock"
因平滑更新的特性,采样量的阶跃变化需经 8 次采样(方差需
4 次)才能完全体现,解析结果时需审慎考虑。
通过锁请求完成时间和 glock 平均锁请求间隔时间,可计算节
点使用 glock 时长与集群共享时长的占比,对设置锁最短持有
时间至关重要。
我们已采取严谨措施,力求精准测量目标量值。任何测量系统均
存在误差,但我期望当前方案已达到合理精度极限。
超级块状态统计路径::
/sys/kernel/debug/gfs2/<fsname>/sbstats
Glock 状态统计路径::
/sys/kernel/debug/gfs2/<fsname>/glstats
(假设 debugfs 挂载于 /sys/kernel/debug且 <fsname> 替
换为对应 GFS2 文件系统名)
输出缩写说明:
========= ============================================
srtt 非阻塞 DLM 请求的平滑往返时间
srttvar srtt 的方差估计
srttb (潜在)阻塞 DLM 请求的平滑往返时间
srttvarb srttb 的方差估计
sirt DLM 请求的平滑请求间隔时间
sirtvar sirt 的方差估计
dlm DLM 请求数glstats 文件中的 dcnt
queue 排队的 glock 请求数glstats 文件中的 qcnt
========= ============================================
sbstats文件按glock类型每种类型8行和CPU核心每CPU一列
记录统计数据集。glstats文件则为每个glock提供统计集其格式
与glocks文件类似但所有时序统计量均采用均值/方差格式存储。
gfs2_glock_lock_time 跟踪点实时输出目标 glock 的当前统计
并附带每次接收到的dlm响应附加信息
====== ============
status DLM 请求状态
flags DLM 请求标志
tdiff 该请求的耗时
====== ============
(其余字段同上表)

View File

@@ -30,3 +30,4 @@ Linux Kernel中的文件系统
ubifs-authentication
gfs2
gfs2-uevents
gfs2-glocks