内核锁压力测试操作¶
CONFIG_LOCK_TORTURE_TEST¶
CONFIG_LOCK_TORTURE_TEST 配置选项提供了一个内核模块,用于对核心内核锁原语运行压力测试。如果需要,可以在要测试的正在运行的内核上事后构建内核模块“locktorture”。这些测试通过 printk() 定期输出状态消息,可以通过 dmesg 查看(也许可以通过 grep 查找“torture”)。加载模块时开始测试,卸载模块时停止测试。该程序基于 RCU 接受压力测试的方式(通过 rcutorture)。
这个压力测试包括创建多个内核线程,它们获取锁并将其保持特定时间,从而模拟不同的临界区行为。可以通过延长该临界区的保持时间和/或创建更多内核线程来模拟对锁的竞争程度。
模块参数¶
该模块具有以下参数
Locktorture 特定参数¶
- nwriters_stress
将对排他锁所有权(写者)进行压力测试的内核线程数。默认值为在线 CPU 数量的两倍。
- nreaders_stress
将对共享锁所有权(读者)进行压力测试的内核线程数。默认值与写者锁的数量相同。如果用户未指定 nwriters_stress,则读者和写者都将是在线 CPU 的数量。
- torture_type
要进行压力测试的锁类型。默认情况下,只对自旋锁进行压力测试。该模块可以对以下锁进行压力测试,其字符串值如下
- “lock_busted”
模拟一个有 bug 的锁实现。
- “spin_lock”
spin_lock()和spin_unlock()对。
- “spin_lock_irq”
spin_lock_irq()和spin_unlock_irq()对。
- “rw_lock”
读/写
lock()和unlock()rwlock 对。
- “rw_lock_irq”
读/写
lock_irq()和unlock_irq()rwlock 对。
- “mutex_lock”
- “rtmutex_lock”
rtmutex_lock()和rtmutex_unlock()对。内核必须配置 CONFIG_RT_MUTEXES=y。
- “rwsem_lock”
读/写
down()和up()信号量对。
压力测试框架(RCU + 锁)¶
- shutdown_secs
在终止测试并关闭系统之前运行测试的秒数。默认值为零,这会禁用测试终止和系统关机。此功能对于自动化测试非常有用。
- onoff_interval
每次尝试执行随机选择的 CPU 热插拔操作之间的秒数。默认为零,这会禁用 CPU 热插拔。在 CONFIG_HOTPLUG_CPU=n 的内核中,无论为 onoff_interval 指定什么值,locktorture 都会默默地拒绝执行任何 CPU 热插拔操作。
- onoff_holdoff
等待开始 CPU 热插拔操作的秒数。这通常仅在 locktorture 被内置到内核中并在引导时自动启动时使用,在这种情况下,它可以避免用上线和下线的 CPU 混淆引导时代码。此参数仅在启用了 CONFIG_HOTPLUG_CPU 时有用。
- stat_interval
与统计相关的
printk()之间的秒数。默认情况下,locktorture 每 60 秒报告一次统计信息。将间隔设置为零会导致-仅-在卸载模块时打印统计信息。- stutter
运行测试的时长,然后暂停相同的时间段。默认为 “stutter=5”,即运行和暂停(大约)五秒钟的间隔。指定 “stutter=0” 会使测试连续运行而不暂停。
- shuffle_interval
保持测试线程绑定到 CPU 的特定子集的秒数,默认为 3 秒。与 test_no_idle_hz 结合使用。
- verbose
通过
printk()启用详细的调试打印。默认启用。这些额外的信息主要与来自主“torture”框架的高级错误和报告有关。
统计数据¶
统计信息以以下格式打印
spin_lock-torture: Writes: Total: 93746064 Max/Min: 0/0 Fail: 0
(A) (B) (C) (D) (E)
(A): Lock type that is being tortured -- torture_type parameter.
(B): Number of writer lock acquisitions. If dealing with a read/write
primitive a second "Reads" statistics line is printed.
(C): Number of times the lock was acquired.
(D): Min and max number of times threads failed to acquire the lock.
(E): true/false values if there were errors acquiring the lock. This should
-only- be positive if there is a bug in the locking primitive's
implementation. Otherwise a lock should never fail (i.e., spin_lock()).
Of course, the same applies for (C), above. A dummy example of this is
the "lock_busted" type.
用法¶
可以使用以下脚本来对锁进行压力测试
#!/bin/sh
modprobe locktorture
sleep 3600
rmmod locktorture
dmesg | grep torture:
可以手动检查输出中的错误标志 “!!!”。当然,人们也可以创建一个更复杂的脚本来自动检查此类错误。“rmmod” 命令会强制通过 printk() 输出 “SUCCESS”(成功)、“FAILURE”(失败)或 “RCU_HOTPLUG” 指示。前两个是不言自明的,而最后一个表明虽然没有锁失败,但检测到了 CPU 热插拔问题。
另请参见:RCU 压力测试操作