下面关于linux内核软中断,Linux内核软中断线程对于通用内核线程的启示

Linux 2.6.11版本的内核软中断线程ksoftirqd代码如下,下面框架可以看出对于,吞吐量与处理延迟两者之间的权衡。

软中断线程处理概括:

1、如果没有活干(没有软中断等待处理)就 schedule()切出,并从运行队列里面删除(由于任务状态已经变成TASK_INTERRUPTIBLE)

2、如果有活儿干,就把当前pending的软中断处理完,处理过程中检查如果本线程运行时间过长,则 schedule()切出(cond_resched()完成这一切),避免其他线程饿死。但切出时任务状态是TASK_RUNNING,不会移出运行队列(线程还有活儿没干完,得赶紧回来),由于移出前,关闭了内核抢占,很快就会重新调度到本线程的。

3、系统调度让其他进程运行一段时间后,本进程重新切换回来运行,重复第2步,一直到该处理得软中断处理完

4、一批软中断处理完后,设置任务状态是TASK_INTERRUPTIBLE,为无软新的软中断过来时切出去并移出运行队列准备。

假如:一次来了8个软中断要处理,需要连续处理完8个软中断,期间可以会切出;如果处理完这组最后一个软中断后正好切出(调用 cond_resched()时里面检查时间片到),然后一段时间后切换回来,发现切出的这段时间有新的软中断等待处理,则有继续处理。

static int ksoftirqd (void * __bind_cpu)

{

set_user_nice(current, 19);            

current->flags |= PF_NOFREEZE;

set_current_state(TASK_INTERRUPTIBLE);  

while (!kthread_should_stop()) {              

if (!local_softirq_pending())                    

schedule();

__set_current_state(TASK_RUNNING);  

while (local_softirq_pending()) {           

preempt_disable();                             

if (cpu_is_offline((long)__bind_cpu))

goto wait_to_die;

do_softirq();                                      

preempt_enable();

cond_resched();                                

}

set_current_state(TASK_INTERRUPTIBLE);  

}

__set_current_state(TASK_RUNNING);

return 0;

wait_to_die:  

preempt_enable();

set_current_state(TASK_INTERRUPTIBLE);

while (!kthread_should_stop()) {

schedule();

set_current_state(TASK_INTERRUPTIBLE);

}

__set_current_state(TASK_RUNNING);

return 0;

}

int __sched cond_resched (void)

{

if (need_resched()) {

__cond_resched();

return 1;

}

return 0;

}

static inline void __cond_resched (void)

{

do {

add_preempt_count(PREEMPT_ACTIVE);  

schedule();

sub_preempt_count(PREEMPT_ACTIVE);

} while (need_resched());

}

static inline int need_resched (void)

{

return unlikely(test_thread_flag(TIF_NEED_RESCHED)); 

}

上述软中断线程处理得经典框架可以作为有类似处理内核线程的通用框架 。

static int kmythread (...)

{

...

set_current_state(TASK_INTERRUPTIBLE);

while (!kthread_should_stop()) {

if (!local_softirq_pending())    /* 这段代码对于通用线程可以删除 */

schedule();

__set_current_state(TASK_RUNNING);

while (/* 有自己的数据处理,如:自己的队列里面有报文需要处理等 */) {

preempt_disable();

/* 干活... */

preempt_enable();

cond_resched();

}

set_current_state(TASK_INTERRUPTIBLE);

}

__set_current_state(TASK_RUNNING);

return 0;

}0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值