1、softirq number
和IRQ number一样,对于软中断,linux kernel也是用一个softirq number唯一标识一个softirq,具体定义如下
HI_SOFTIRQ用于高优先级的tasklet,TASKLET_SOFTIRQ用于普通的tasklet。TIMER_SOFTIRQ是for software timer的(所谓software timer就是说该timer是基于系统tick的)。NET_TX_SOFTIRQ和NET_RX_SOFTIRQ是用于网卡数据收发的。BLOCK_SOFTIRQ和BLOCK_IOPOLL_SOFTIRQ是用于block device的。SCHED_SOFTIRQ用于多CPU之间的负载均衡的。HRTIMER_SOFTIRQ用于高精度timer的。RCU_SOFTIRQ是处理RCU的。
2、softirq描述符
softirq是静态定义的,也就是说系统中有一个定义softirq描述符的数组,而softirq number就是这个数组的index。
1、注册softirq
通过调用open_softirq接口函数可以注册softirq的action callback函数
2、触发softirq
软中断的触发时机
1)、irq_exit:在硬中断退出时,会检查local_softirq_pending和preemt_count,如果都符合条件,则执行软中断。
if (!in_interrupt() &&local_softirq_pending())
invoke_softirq()
2)、local_bh_enable:使用此函数开启软中断时,会检查local_softirq_pending,如果都符合条件,则执行软中断。调用链为local_bh_enable()->__local_bh_enable()->do_softirq()。
3)、raise_softirq:主动唤起一个软中断,会首先设置__softirq_pending对应的软中断位为挂起,然后检查in_interrupt,如果不在中断中,则唤起ksoftirq线程执行软中断(ksoftirq是softirq的一种执行机制,在软中的运行流程中会提到)。
3、执行softirq
在中断处理程序中触发软中断是最常见的形式,一个硬件中断处理完成之后。下面的函数在处理完硬件中断之后退出中断处理函数,在irq_exit中会触发软件中断的处理,最后会调用__do_softirq执行软中断。
1、注册
2、唤醒
timer interrupt handler->
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))}
3、执行
对于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
参考:
http://www.wowotech.net/irq_subsystem/soft-irq.html
https://blog.csdn.net/yhb1047818384/article/details/63687126
https://www.cnblogs.com/lidabo/p/5312856.html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)