本文章添加自己定义一个额外的软中断
首先添加软中断种类:MY_SOFTIRQ
enum
{
HI_SOFTIRQ=0,
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ,
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
MY_SOFTIRQ,
NR_SOFTIRQS
};
然后编写测试驱动程序:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/stat.h>
#include <linux/interrupt.h>
#include <linux/bottom_half.h>
#include <linux/delay.h>
static void test_action(struct softirq_action *action)
{
int i;
printk("hello\n");
}
static int softirq_init_test(void)
{
int i;
printk("init\n");
open_softirq(MY_SOFTIRQ, test_action);
raise_softirq(MY_SOFTIRQ);
return 0;
}
static void softirq_exit_test(void)
{
printk("exit\n");
}
module_init(softirq_init_test);
module_exit(softirq_exit_test);
MODULE_AUTHOR("David Xie");
MODULE_LICENSE("Dual BSD/GPL");
编译发现报错,信息为open_softirq和raise_softirq这两个函数没有定义,通过查看源代码可知,这两个函数没有导出符号表,因此在内核代码里面加上两句代码:
EXPORT_SYMBOL(open_softirq);
EXPORT_SYMBOL(raise_softirq);
重新编译内核就行了.
另外了解到,softirq的中断函数是在中断上下文的情况下执行的,因此不能发生调度,那么如果我们主动调度会怎么样,来测试一下,在test_action这个函数中加上msleep函数,然后插入这个驱动,结果会打印一大串的信息,意思基本就是在院子上下文中发生了调度,截取一段如下:
BUG: scheduling while atomic: insmod/733/0x00000100
Modules linked in: softirq_test(+)
Pid: 733, comm: insmod
CPU: 0 Not tainted (2.6.32.2-FriendlyARM #4)
PC is at raise_softirq+0x5c/0x64
LR is at check_preempt_wakeup+0x8c/0x128
pc : [<c004dbc4>] lr : [<c00453dc>] psr: a0000013
sp : c3a6bf08 ip : c3a6be88 fp : c3a6bf1c
r10: 00000000 r9 : c3a6a000 r8 : c0030088
r7 : bf00001c r6 : 00000000 r5 : c3a6a000 r4 : 60000013
r3 : 00000000 r2 : db1d654a r1 : c3820630 r0 : 00000001
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: c000717f Table: 33a08000 DAC: 00000015
[<c0031534>] (show_regs+0x0/0x50) from [<c0044b68>] (__schedule_bug+0x4c/0x60)
r5:c3a6a000 r4:c3a6bec0
[<c0044b1c>] (__schedule_bug+0x0/0x60) from [<c0368864>] (schedule+0x380/0x3c8)
r5:c3a6a000 r4:c04950d8
[<c03684e4>] (schedule+0x0/0x3c8) from [<c0368b30>] (schedule_timeout+0x104/0x19c)
[<c0368a2c>] (schedule_timeout+0x0/0x19c) from [<c0368bf0>] (schedule_timeout_uninterruptible+0x28/0x2c)
r7:c3a6a000 r6:c04eda00 r5:00000001 r4:00000001
[<c0368bc8>] (schedule_timeout_uninterruptible+0x0/0x2c) from [<c00530fc>] (msleep+0x1c/0x28)
[<c00530e0>] (msleep+0x0/0x28) from [<bf000078>] (test_action+0x24/0x40 [softirq_test])
[<bf000054>] (test_action+0x0/0x40 [softirq_test]) from [<c004df00>] (__do_softirq+0x9c/0x130)
r5:00000001 r4:00000028
[<c004de64>] (__do_softirq+0x0/0x130) from [<c004dfdc>] (irq_exit+0x48/0x50)
[<c004df94>] (irq_exit+0x0/0x50) from [<c002f048>] (asm_do_IRQ+0x48/0x8c)
[<c002f000>] (asm_do_IRQ+0x0/0x8c) from [<c002fac4>] (__irq_svc+0x24/0xa0)
Exception stack(0xc3a6bec0 to 0xc3a6bf08)
bec0: 00000001 c3820630 db1d654a 00000000 60000013 c3a6a000 00000000 bf00001c
bee0: c0030088 c3a6a000 00000000 c3a6bf1c c3a6be88 c3a6bf08 c00453dc c004dbc4
bf00: a0000013 ffffffff
r7:bf00001c r6:00002000 r5:f4000000 r4:ffffffff
[<c004db68>] (raise_softirq+0x0/0x64) from [<bf000044>] (softirq_init_test+0x28/0x38 [softirq_test])
r5:c3a6a000 r4:c04cc860
[<bf00001c>] (softirq_init_test+0x0/0x38 [softirq_test]) from [<c002f32c>] (do_one_initcall+0x3c/0x1dc)
[<c002f2f0>] (do_one_initcall+0x0/0x1dc) from [<c006e398>] (sys_init_module+0xcc/0x1fc)
[<c006e2cc>] (sys_init_module+0x0/0x1fc) from [<c002fee0>] (ret_fast_syscall+0x0/0x28)
r7:00000080 r6:be90de54 r5:00000069 r4:00000005
BUG: scheduling while atomic: insmod/733/0x00000100
Modules linked in: softirq_test(+)
Pid: 733, comm: insmod
CPU: 0 Not tainted (2.6.32.2-FriendlyARM #4)
PC is at raise_softirq+0x5c/0x64
LR is at check_preempt_wakeup+0x8c/0x128
pc : [<c004dbc4>] lr : [<c00453dc>] psr: a0000013
sp : c3a6bf08 ip : c3a6be88 fp : c3a6bf1c
r10: 00000000 r9 : c3a6a000 r8 : c0030088
r7 : bf00001c r6 : 00000000 r5 : c3a6a000 r4 : 60000013
r3 : 00000000 r2 : db1d654a r1 : c3820630 r0 : 00000001
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: c000717f Table: 33a08000 DAC: 00000015
[<c0031534>] (show_regs+0x0/0x50) from [<c0044b68>] (__schedule_bug+0x4c/0x60)
r5:c3a6a000 r4:c3a6bec0
[<c0044b1c>] (__schedule_bug+0x0/0x60) from [<c0368864>] (schedule+0x380/0x3c8)
r5:c3a6a000 r4:c04950d8