lockstat.1
最后更新于
最后更新于
LOCKSTAT(1)
LOCKSTAT(1)
FreeBSD General Commands Manual
LOCKSTAT(1)
lockstat
—
报告内核锁和分析统计信息
lockstat
[-ACEHIV
] [-e
event-list] [-i
rate] [-b
| -t
| -h
| -s
depth] [-n
num-records] [-l
lock [,size]] [-d
duration] [-f
function [,size]] [-T
] [-kgwWRpP
] [-D
count] [-o
-filename
] [-x
opt [=val]] command [[args]]
lockstat
实用程序收集并显示内核锁定和分析统计信息。 lockstat
允许您指定要监视的事件(例如,自旋自适应互斥体、由于等待写入者而阻止对 rwlock 的读取访问等)、为每个事件收集多少数据以及如何显示数据。 默认情况下, lockstat
监控所有锁争用事件,收集有关这些事件的频率和时间数据,并按频率降序显示数据,以便最常见的事件首先出现。
lockstat
收集数据,直到指定的命令完成。 例如,要收集固定时间间隔的统计信息,请使用 sleep(1) 作为命令,如下所示:
# lockstat sleep 5
当指定 -I
选项时, lockstat
会建立一个每个处理器的高级周期性中断源来收集分析数据。 中断处理程序只是生成一个 lockstat
事件,其调用者是被中断的 PC(程序计数器)。 分析事件就像任何其他 lockstat
事件一样,因此所有正常的 lockstat
选项都适用。
lockstat
依靠 DTrace 修改正在运行的内核的文本以拦截感兴趣的事件。 这会对所有系统活动造成很小但可衡量的开销,因此默认情况下,对 lockstat
的访问仅限于超级用户。
支持以下选项:
打印用于收集请求数据的 D 程序。
如果未指定事件选择选项,则默认值为 -C
。
观看所有锁定事件。 -A
等价于 -CH
。
观看争用事件。
观察错误事件。
只观看指定的事件。 event-list 是以逗号分隔的事件列表或事件范围,例如 1,4-7,35。 不带参数运行 lockstat
以获得所有事件的简要描述。
观看举行活动。
观察分析中断事件。
启用或修改 dtrace(1) 运行时选项或 D 编译器选项。 布尔选项通过指定它们的名称来启用。 带有值的选项是通过用等号分隔选项名称和值来设置的。
基本统计:锁、调用者、事件数。
直方图:时序加时间分布直方图。
堆栈跟踪:直方图加上堆栈跟踪,直至 depth 帧。
计时:所有事件的基本加计时(默认)。
只观看超过 duration 时间的事件。
仅监听 func 生成的事件,可以指定为符号名或十六进制地址。 size 默认为 ELF 符号大小(如果可用),否则为 1。
只观看 lock ,可以指定为符号名或十六进制地址。 size 默认为 ELF 符号大小,如果符号大小不可用,则默认为 1。
最大数据记录数。
跟踪(而不是样本)事件。 默认情况下这是关闭的。
仅显示每种类型的最高 count 事件。
显示函数生成的总事件。 例如,如果 foo
() 在循环中调用 bar
() ,则 bar
() 完成的工作算作 foo
() 生成的工作(连同 foo
() 本身完成的任何工作)。 -g
选项通过计算每个函数出现的堆栈帧总数来工作。 这意味着两件事:(1) 如果堆栈跟踪不够深, -g
报告的数据可能会产生误导,以及 (2) 递归调用的函数可能显示大于 100% 的活动。 针对问题(1),使用 -g
时默认的数据收集模式是 -s
-50
。
在功能内合并 PC。
直接输出到 filename 。
按(count * time) 产品对数据进行排序。
可解析的输出格式。
显示速率(每秒事件数)而不是计数。
无论哪种方式:仅通过调用者区分事件,而不是通过锁。
Wherever: 仅通过锁来区分事件,而不是调用者。
以下标题出现在不同的数据列中。
Count or ops/s
如果指定了 -R
,则此事件发生的次数或速率(每秒次数)。
indv
此单个事件所代表的所有事件的百分比。
genr
此函数生成的所有事件的百分比。
cuml
累计百分比;个人的总和。
rcnt
平均引用计数。 对于独占锁(互斥锁、自旋锁、作为写入器持有的 rwlock),这将始终为 1,但对于共享锁(作为读取器持有的 rwlock),它可以大于 1。
nsec
事件的平均持续时间(以纳秒为单位),视事件而定。 对于分析事件,持续时间意味着中断延迟。
Lock
锁的地址;如果可能,象征性地显示。
CPU+Pri_Class
CPU 加上被中断线程的优先级。 例如,如果 CPU 4 在运行分时线程时中断,则会报告为 ‘cpu[4]+TShar
’ 。
Caller
来电者的地址;如果可能,象征性地显示。
示例 1 测量内核锁争用
# lockstat sleep 5
Adaptive mutex spin: 41411 events in 5.011 seconds (8263 events/sec) Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------------- 13750 33% 33% 0.00 72 vm_page_queue_free_mtx vm_page_free_toq+0x12e 13648 33% 66% 0.00 66 vm_page_queue_free_mtx vm_page_alloc+0x138 4023 10% 76% 0.00 51 vm_dom+0x80 vm_page_dequeue+0x68 2672 6% 82% 0.00 186 vm_dom+0x80 vm_page_enqueue+0x63 618 1% 84% 0.00 31 0xfffff8000cd83a88 qsyncvp+0x37 506 1% 85% 0.00 164 0xfffff8000cb3f098 vputx+0x5a 477 1% 86% 0.00 69 0xfffff8000c7eb180 uma_dbg_getslab+0x5b 288 1% 87% 0.00 77 0xfffff8000cd8b000 vn_finished_write+0x29 263 1% 88% 0.00 103 0xfffff8000cbad448 vinactive+0xdc 259 1% 88% 0.00 53 0xfffff8000cd8b000 vfs_ref+0x24 237 1% 89% 0.00 20 0xfffff8000cbad448 vfs_hash_get+0xcc 233 1% 89% 0.00 22 0xfffff8000bfd9480 uma_dbg_getslab+0x5b 223 1% 90% 0.00 20 0xfffff8000cb3f098 cache_lookup+0x561 193 0% 90% 0.00 16 0xfffff8000cb40ba8 vref+0x27 175 0% 91% 0.00 34 0xfffff8000cbad448 vputx+0x5a 169 0% 91% 0.00 51 0xfffff8000cd8b000 vfs_unbusy+0x27 164 0% 92% 0.00 31 0xfffff8000cb40ba8 vputx+0x5a [...] Adaptive mutex block: 10 events in 5.011 seconds (2 events/sec) Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------------- 3 30% 30% 0.00 17592 vm_page_queue_free_mtx vm_page_alloc+0x138 2 20% 50% 0.00 20528 vm_dom+0x80 vm_page_enqueue+0x63 2 20% 70% 0.00 55502 0xfffff8000cb40ba8 vputx+0x5a 1 10% 80% 0.00 12007 vm_page_queue_free_mtx vm_page_free_toq+0x12e 1 10% 90% 0.00 9125 0xfffff8000cbad448 vfs_hash_get+0xcc 1 10% 100% 0.00 7864 0xfffff8000cd83a88 qsyncvp+0x37 ------------------------------------------------------------------------------- [...]
示例 2 测量保持时间
# lockstat -H -D 10 sleep 1
Adaptive mutex hold: 109589 events in 1.039 seconds (105526 events/sec) Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------------- 8998 8% 8% 0.00 617 0xfffff8000c7eb180 uma_dbg_getslab+0xd4 5901 5% 14% 0.00 917 vm_page_queue_free_mtx vm_object_terminate+0x16a 5040 5% 18% 0.00 902 vm_dom+0x80 vm_page_free_toq+0x88 4884 4% 23% 0.00 1056 vm_page_queue_free_mtx vm_page_alloc+0x44e 4664 4% 27% 0.00 759 vm_dom+0x80 vm_fault_hold+0x1a13 4011 4% 31% 0.00 888 vm_dom vm_page_advise+0x11b 4010 4% 34% 0.00 957 vm_dom+0x80 _vm_page_deactivate+0x5c 3743 3% 38% 0.00 582 0xfffff8000cf04838 pmap_is_prefaultable+0x158 2254 2% 40% 0.00 952 vm_dom vm_page_free_toq+0x88 1639 1% 41% 0.00 591 0xfffff800d60065b8 trap_pfault+0x1f7 ------------------------------------------------------------------------------- [...] R/W writer hold: 64314 events in 1.039 seconds (61929 events/sec) Count indv cuml rcnt nsec Lock Caller ------------------------------------------------------------------------------- 7421 12% 12% 0.00 2994 pvh_global_lock pmap_page_is_mapped+0xb6 4668 7% 19% 0.00 3313 pvh_global_lock pmap_enter+0x9ae 1639 3% 21% 0.00 733 0xfffff80168d10200 vm_object_deallocate+0x683 1639 3% 24% 0.00 3061 0xfffff80168d10200 unlock_and_deallocate+0x2b 1639 3% 26% 0.00 2966 0xfffff80168d10200 vm_fault_hold+0x16ee 1567 2% 29% 0.00 733 0xfffff80168d10200 vm_fault_hold+0x19bc 821 1% 30% 0.00 786 0xfffff801eb0cc000 vm_object_madvise+0x32d 649 1% 31% 0.00 4918 0xfffff80191105300 vm_fault_hold+0x16ee 648 1% 32% 0.00 8112 0xfffff80191105300 unlock_and_deallocate+0x2b 647 1% 33% 0.00 1261 0xfffff80191105300 vm_object_deallocate+0x683 -------------------------------------------------------------------------------
示例 3 测量包含特定函数的堆栈跟踪的保持时间
# lockstat -H -f tcp_input -s 50 -D 10 sleep 1
Adaptive mutex hold: 68 events in 1.026 seconds (66 events/sec) ------------------------------------------------------------------------------- Count indv cuml rcnt nsec Lock Caller 32 47% 47% 0.00 1631 0xfffff800686f50d8 tcp_do_segment+0x284b nsec ------ Time Distribution ------ count Stack 1024 |@@@@@@@@@@ 11 tcp_input+0xf54 2048 |@@@@@@@@@@@@@ 14 ip_input+0xc8 4096 |@@@@@ 6 swi_net+0x192 8192 | 1 intr_event_execute_handlers+0x93 ithread_loop+0xa6 fork_exit+0x84 0xffffffff808cf9ee ------------------------------------------------------------------------------- Count indv cuml rcnt nsec Lock Caller 29 43% 90% 0.00 4851 0xfffff800686f50d8 sowakeup+0xf8 nsec ------ Time Distribution ------ count Stack 4096 |@@@@@@@@@@@@@@@ 15 tcp_do_segment+0x2423 8192 |@@@@@@@@@@@@ 12 tcp_input+0xf54 16384 |@@ 2 ip_input+0xc8 swi_net+0x192 intr_event_execute_handlers+0x93 ithread_loop+0xa6 fork_exit+0x84 0xffffffff808cf9ee ------------------------------------------------------------------------------- [...]
dtrace(1), ksyms(4), locking(9)
lockstat
实用程序首次出现在 FreeBSD 7.1 。
尾部呼叫消除会影响呼叫站点。 例如,如果 foo
()+0x50 调用 bar
() 并且 bar
() 做的最后一件事是调用 mtx_unlock
(), 编译器可以安排 bar
() 分支到 mtx_unlock
() 返回地址为 foo
()+0x58 。 因此, mtx_unlock
() 中的 bar
() 将看起来好像它发生在 foo
()+0x58 处。
发生中断的堆栈帧中的 PC 可能是伪造的,因为在函数调用之间,编译器可以自由地使用返回地址寄存器进行本地存储。
当同时使用 -I
和 -s
选项时,被中断的 PC 通常不会出现在堆栈中的任何位置,因为中断处理程序是异步进入的,而不是通过来自该 PC 的函数调用。
February 25, 2020
FreeBSD 13.1-RELEASE
event-list
rate
的中断率(每秒)。 默认值为 97 Hz,因此分析不会与时钟中断(以 100 Hz 运行)同步运行。
arg [=val]
depth
duration
func[,size]
lock[,size]
num-records
count
filename