英语

内核锁压力测试操作

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”

    模拟有缺陷的锁实现。

  • “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”

    mutex_lock()mutex_unlock() 对。

  • “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 压力测试操作