感觉之前对于软中断一直有一些误解。
软中断的定义:
软中断是利用硬件中断的概念,用软件方式进行模拟,实现宏观上的异步执行效果。很多情况下,软中断和“信号”类似。同时,软中断又是和硬中断相对应的,“硬中断是外部设备对CPU的中断”,“软中断通常是硬件中断服务程序对内核的中断”
作为系统调用而言,对于i386则是通过软中断int80实现
对于其它的软中断,则是在硬件中断之后触发的软中断。
系统调用在Linux2.6中的实现
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
# define SYSCALL_VECTOR 0x80
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
pushl_cfi %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp) # store the return value
ENTRY(sys_call_table)
.long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
.long sys_exit
.long ptregs_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
.long sys_close
.long sys_waitpid
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
.long ptregs_execve
.long sys_chdir
.long sys_time
.long sys_mknod
.long sys_chmod /* 15 */
.long sys_lchown16
.long sys_ni_syscall /* old break syscall holder */
.long sys_stat
.long sys_lseek
.long sys_getpid /* 20 */
.long sys_mount
.long sys_oldumount
...
对于软中断而言,则稍微复杂些
1.注册软中断当然是通过open_softirq
例子如下:
[cpp]
view plain
copy
软中断TIMER_SOFTIRQ的中断处理函数为:run_timer_softirq
之所以成为softirq,是因为这些中断是由硬件中断来间接触发的,如何间接触发的呢:
硬件中断处理函数-->对软中断的相应位置位-->唤醒ksoftirqd线程-->执行软中断的中断处理函数
2.硬件中断如何通过置位唤醒ksoftirqd线程
timer interrupthandler->
timer_tick->
update_process_times->
run_local_timers->
hrtimer_run_queues()和raise_softirq(TIMER_SOFTIRQ)->
raise_softirq_irqoff->
__raise_softirq_irqoff{ or_softirq_pending(1UL << (nr)); }
即(local_softirq_pending() |= (x))
3.如何执行软中断的action<中断处理函数>
对于TIMER_SOFTIRQ来说,每次system clock产生中断时,即一个tick到来时,在system clock的中断处理函数中会调用run_local_timers来设置TIMER_SOFTIRQ触发条件;也就是当前CPU对应的irq_cpustat_t结构体中的__softirq_pending成员的第TIMER_SOFTIRQ个BIT被置为1。而当这个条件满足时,ksoftirqd线程(入口函数run_ksoftirqd,cpu_callback:kthread_create(run_ksoftirqd,hcpu, "ksoftirqd/%d", hotcpu);)会被唤醒,然后按照下面的流程调用TIMER_SOFTIRQ在数组softirq_vec中注册的action,即run_timer_softirq。
run_ksoftirqd--->do_softirq--->__do_softirq--->softirq_vec[TIMER_SOFTIRQ].action
[cpp]
view plain
copy
From
从上面两种情况的对比可以看出,系统调用的中断由于是软件触发的中断,所以称为软中断,而对于后者的软中断,虽然也是软件触发,但是并不经过中断向量表。