[Mod] 支持Mutex 死锁测试
This commit is contained in:
@ -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
|
||||||
@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user