linux内核源码分析之软中断

目录

1、软中断

2、软中断执行

3、软中断注册

4、软中断触发

5、软中断守护进程


1、软中断

软中断是在编译期间静态分配的,不像tasklet能动态分配

软中断机制的核心部分是一个表,包含32个softirq_action类型的数据项,软中断由softirq_action结构表示。

struct softirq_action
{
	void	(*action)(struct softirq_action *);
};

最多32个软中断,这是一个定值,数目没法动态改变。

static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

2、软中断执行

 程序有删减

asmlinkage __visible void __softirq_entry __do_softirq(void)
{
    ...
	pending = local_softirq_pending();
	local_irq_enable();
	h = softirq_vec;

	while ((softirq_bit = ffs(pending))) {
		h += softirq_bit - 1;
		vec_nr = h - softirq_vec;
		prev_count = preempt_count();

		kstat_incr_softirqs_this_cpu(vec_nr);

		trace_softirq_entry(vec_nr);
		h->action(h);
		trace_softirq_exit(vec_nr);
        ...
		h++;
		pending >>= softirq_bit;
	}

	pending = local_softirq_pending();
	if (pending) {
		if (time_before(jiffies, end) && !need_resched() &&
		    --max_restart)
			goto restart;

		wakeup_softirqd();
	}
}
  •  局部变量pending保存local_softirq_pending宏的返回值,它是待处理的软中断32位位图,如果第n位被设置1,那么第n位对应类型的软中断等待处理
  • 指针h指向 softirq_vec的第一项
  • 如果pending的第一位被置为1,则h->action(h)被调用
  • 指针加1,所以现在它指向softirq_vec的第二项
  • 位掩码pending右移一位,依次移动
  • 现在h指针指向数组第二项,peding掩码位置到了第一位上
  • 重复执行,直到pending变为0 ,循环最多执行32次
  • 如果在MAX_SOFTIRQ_RESTART次重启处理过程之后,仍然有未处理的软中断,那么应该如何?内 核将调用wakeup_softirqd唤醒软中断守护进程

3、软中断注册

kernel/softirq.c 
void open_softirq(int nr, void (*action)(struct softirq_action*), void *data) 
{ 
    softirq_vec[nr].data = data; 
    softirq_vec[nr].action = action; 
}

4、软中断触发

raise_softirq(int nr)

5、软中断守护进程

kernel/softirq.c 
static int ksoftirqd(void * __bind_cpu) 
    ... 
    while (!kthread_should_stop()) { 
    if (!local_softirq_pending()) { 
        schedule(); 
    } 
    __set_current_state(TASK_RUNNING); 
    while (local_softirq_pending()) { 
        do_softirq(); 
        cond_resched(); 
    } 
    set_current_state(TASK_INTERRUPTIBLE); 
    } 
    ... 
}
在系统启动时用 initcall 机制,在 调用 init 不久,即创建了系统中的软中断守护进程。
每次被唤醒时,守护进程首先检查是否有标记出的待决软中断,否则明确地调用调度器,将控制转交到其他进程。
如果有标记出的软中断,那么守护进程接下来将处理软中断。进程在一个 while 循环中重复调用两个函数do_softirq cond_resched ,直至没有标记出的软中断为止。

参考:
《深入理解linux内核》
《Linux内核深度解析》

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为了维护世界和平_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值