linux内核源码分析之软中断

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核源码分析之软中断相关的知识,希望对你有一定的参考价值。

目录

软中断

软中断执行

软中断注册

软中断触发

软中断守护进程

软中断

软中断是在编译期间静态分配的,不像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;

软中断执行

 程序有删减

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唤醒软中断守护进程

软中断注册

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; 

软中断触发

raise_softirq(int nr)

软中断守护进程

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 ,直至没有标记出的软中断为止。 (内核免费课程链接:https://ke.qq.com/course/4032547?flowToken=1042391)

以上是关于linux内核源码分析之软中断的主要内容,如果未能解决你的问题,请参考以下文章

把握linux内核设计思想系列

linux内核源码分析中断work_queue

结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程

linux源码分析

Linux中断底半部机制

Linux内核中的下半部机制之tasklet