Linux 模拟Soft lockup, Hard lockup 内核崩溃重启

默认环境:

1
2
3
4
[root@localhost ~]# sysctl kernel.softlockup_panic kernel.hardlockup_panic
kernel.softlockup_panic = 0
kernel.hardlockup_panic = 1
[root@localhost ~]#

模拟 单CPU Lockup

Soft Lockup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[root@localhost soft]# cat hog.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");

static int
hog_thread(void *data)
{
DEFINE_SPINLOCK(lock);

printk(KERN_INFO "Soft Lockup Hogging on CPU %d now\n", get_cpu());
spin_lock(&lock);

while (1);

/* unreached */
return 0;
}

static int __init
hog_init(void)
{
kthread_run(hog_thread, NULL, "hog");
return 0;
}

static void __exit
hog_exit(void)
{
printk(KERN_INFO "Hogging exit\n");
return;
}


module_init(hog_init);
module_exit(hog_exit);
[root@localhost soft]#

Hard Lockup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[root@localhost hard]# cat hog.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/spinlock.h>

MODULE_LICENSE("GPL");

static int
hog_thread(void *data)
{
DEFINE_SPINLOCK(lock);

printk(KERN_INFO "Hard lockup Hogging a CPU %d now\n", get_cpu());
spin_lock_irq(&lock);
while (1);

/* unreached */
return 0;
}

static int __init
hog_init(void)
{
kthread_run(hog_thread, NULL, "hog");
return 0;
}

static void __exit
hog_exit(void)
{
printk(KERN_INFO "Hogging exit\n");
return;
}


module_init(hog_init);
module_exit(hog_exit);

模拟 所有CPU Lockup

Soft lockup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[root@localhost soft]# cat hog.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");

static int
hog_thread(void *data)
{
DEFINE_SPINLOCK(lock);

printk(KERN_INFO "Soft Lockup Hogging on CPU %d now\n", get_cpu());
spin_lock(&lock);

while (1);

/* unreached */
return 0;
}

static int __init
hog_init(void)
{
int cpu = 0;
for_each_online_cpu(cpu)
{
struct task_struct *task = kthread_create(hog_thread, NULL, "hog");
kthread_bind(task, cpu);
wake_up_process(task);
}

return 0;
}

static void __exit
hog_exit(void)
{
printk(KERN_INFO "Hogging exit\n");
return;
}


module_init(hog_init);
module_exit(hog_exit);
[root@localhost soft]#

Hard Lockup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[root@localhost hard]# cat hog.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/spinlock.h>

MODULE_LICENSE("GPL");

static int
hog_thread(void *data)
{
DEFINE_SPINLOCK(lock);

printk(KERN_INFO "Hard lockup Hogging a CPU %d now\n", get_cpu());
spin_lock_irq(&lock);
while (1);

/* unreached */
return 0;
}

static int __init
hog_init(void)
{
int cpu = 0;
for_each_online_cpu(cpu)
{
struct task_struct *task = kthread_create(hog_thread, NULL, "hog");
kthread_bind(task, cpu);
wake_up_process(task);
}

return 0;
}

static void __exit
hog_exit(void)
{
printk(KERN_INFO "Hogging exit\n");
return;
}


module_init(hog_init);
module_exit(hog_exit);

Makefile

1
2
3
4
5
6
7
8
[root@localhost hard]# cat Makefile
obj-m += hog.o

all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
[root@localhost hard]#

死锁时 内核崩溃转储

1
2
3
4
5
6
7
8
[root@localhost ~]# vim /etc/sysctl.conf
[root@localhost hard]# sysctl -p
kernel.softlockup_all_cpu_backtrace = 1
kernel.hardlockup_all_cpu_backtrace = 1
kernel.softlockup_panic = 1
kernel.hardlockup_panic = 1
kernel.nmi_watchdog = 1
[root@localhost hard]#