[Mod] 支持Mutex 死锁测试

This commit is contained in:
gaoyang3513
2024-04-17 15:57:40 +08:00
parent 42f072b126
commit d571378ac7
2 changed files with 61 additions and 1 deletions

View File

@ -800,3 +800,5 @@ CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_LKDTM=y CONFIG_LKDTM=y
CONFIG_TESTING_PSTORE=m CONFIG_TESTING_PSTORE=m
CONFIG_LOCK_STAT=y
CONFIG_PROVE_LOCKING=y

View File

@ -4,6 +4,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
static unsigned int test_type; static unsigned int test_type;
module_param(test_type, uint, 0400); module_param(test_type, uint, 0400);
@ -61,6 +63,56 @@ static void trigger_rcu(void)
call_rcu(&test_rcu_head, bad_rcu_callback); 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) { static int trigger_init(void) {
if (test_type == 0) if (test_type == 0)
trigger_oom(); trigger_oom();
@ -68,12 +120,18 @@ static int trigger_init(void) {
trigger_oops(); trigger_oops();
else if (test_type == 2) else if (test_type == 2)
trigger_rcu(); trigger_rcu();
else if (test_type == 3)
trigger_deadlock();
return 0; // 加载模块不应该有返回值但这里返回0避免编译警告。 return 0; // 加载模块不应该有返回值但这里返回0避免编译警告。
} }
static void __exit trigger_exit(void) { 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); module_init(trigger_init);