[Mod] 支持Mutex 死锁测试
This commit is contained in:
@ -800,3 +800,5 @@ CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_LKDTM=y
|
||||
|
||||
CONFIG_TESTING_PSTORE=m
|
||||
CONFIG_LOCK_STAT=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
@ -4,6 +4,8 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
static unsigned int test_type;
|
||||
module_param(test_type, uint, 0400);
|
||||
@ -61,6 +63,56 @@ static void trigger_rcu(void)
|
||||
call_rcu(&test_rcu_head, bad_rcu_callback);
|
||||
}
|
||||
|
||||
static int is_ready_thread1, is_ready_thread2;
|
||||
static struct task_struct *thread1;
|
||||
static struct task_struct *thread2;
|
||||
|
||||
static DEFINE_MUTEX(mutex_a);
|
||||
static DEFINE_MUTEX(mutex_b);
|
||||
|
||||
static int thread_func(void *data)
|
||||
{
|
||||
char *name = (char *) data;
|
||||
|
||||
if (!strcmp(name, "Thread1")) {
|
||||
printk(KERN_INFO "%s: Acquiring mutex A...\n", name);
|
||||
mutex_lock(&mutex_a);
|
||||
is_ready_thread1 = 1;
|
||||
while (!is_ready_thread2);
|
||||
printk(KERN_INFO "%s: Got mutex A. Now trying to acquire mutex B...\n", name);
|
||||
mutex_lock(&mutex_b); // This will block, causing deadlock
|
||||
printk(KERN_INFO "%s: Got mutex B.\n", name);
|
||||
} else {
|
||||
printk(KERN_INFO "%s: Acquiring mutex B...\n", name);
|
||||
mutex_lock(&mutex_b);
|
||||
is_ready_thread2 = 1;
|
||||
while (!is_ready_thread1);
|
||||
printk(KERN_INFO "%s: Got mutex B. Now trying to acquire mutex A...\n", name);
|
||||
mutex_lock(&mutex_a); // This will block, causing deadlock
|
||||
printk(KERN_INFO "%s: Got mutex A.\n", name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trigger_deadlock(void)
|
||||
{
|
||||
thread1 = kthread_run(thread_func, (void *) "Thread1", "thread1");
|
||||
if (IS_ERR(thread1)) {
|
||||
printk(KERN_ERR "Failed to create thread1\n");
|
||||
return PTR_ERR(thread1);
|
||||
}
|
||||
|
||||
thread2 = kthread_run(thread_func, (void *) "Thread2", "thread2");
|
||||
if (IS_ERR(thread2)) {
|
||||
printk(KERN_ERR "Failed to create thread2\n");
|
||||
kthread_stop(thread1);
|
||||
return PTR_ERR(thread2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trigger_init(void) {
|
||||
if (test_type == 0)
|
||||
trigger_oom();
|
||||
@ -68,12 +120,18 @@ static int trigger_init(void) {
|
||||
trigger_oops();
|
||||
else if (test_type == 2)
|
||||
trigger_rcu();
|
||||
else if (test_type == 3)
|
||||
trigger_deadlock();
|
||||
|
||||
return 0; // 加载模块不应该有返回值,但这里返回0避免编译警告。
|
||||
}
|
||||
|
||||
static void __exit trigger_exit(void) {
|
||||
printk(KERN_INFO "oom_trigger: Exiting the oom_trigger LKM\n");
|
||||
if (test_type == 3) {
|
||||
kthread_stop(thread1);
|
||||
kthread_stop(thread2);
|
||||
printk(KERN_INFO "Deadlock trigger exit.\n");
|
||||
}
|
||||
}
|
||||
|
||||
module_init(trigger_init);
|
||||
|
||||
Reference in New Issue
Block a user