local_irq_restore
时间: 2023-08-21 08:06:19 浏览: 114
`local_irq_restore` 是一个内核函数,用于恢复中断状态,并且允许中断在执行时被触发。这个函数通常与 `local_irq_save` 函数一起使用,用于保护临界区避免中断的发生。`local_irq_restore` 函数会将中断状态恢复为调用 `local_irq_save` 时保存的状态。
在 Linux 内核中,中断是一种处理外部事件的机制,当外部事件发生时,中断处理程序会中断当前的执行流程,执行相应的处理逻辑。为了避免竞态条件和数据不一致性,某些临界区代码需要关闭中断,以确保在执行期间不会被中断打断。当临界区代码执行完成后,可以使用 `local_irq_restore` 函数恢复中断状态,并允许中断再次触发。
需要注意的是,`local_irq_restore` 函数只能恢复当前CPU的中断状态,并且在多CPU系统中,需要使用 `local_irq_restore` 函数对每个CPU进行恢复操作。
相关问题
raise_softirq_irqoff源码
`raise_softirq_irqoff()` 函数是 Linux 内核中用于触发软中断的函数之一,其定义在 `include/linux/interrupt.h` 头文件中。
函数原型如下:
```c
void raise_softirq_irqoff(unsigned int nr);
```
该函数的参数 `nr` 代表要触发的软中断号,软中断号的取值范围为 `0 ~ NR_SOFTIRQS-1`,其中 `NR_SOFTIRQS` 定义在 `include/linux/interrupt.h` 头文件中,表示软中断的最大数量。
函数实现如下:
```c
void raise_softirq_irqoff(unsigned int nr)
{
unsigned long flags;
local_irq_save(flags);
__raise_softirq_irqoff(nr);
local_irq_restore(flags);
}
```
该函数首先保存当前 CPU 的中断状态,然后调用 `__raise_softirq_irqoff()` 函数触发软中断,最后恢复之前保存的中断状态。
`__raise_softirq_irqoff()` 函数实现如下:
```c
void __raise_softirq_irqoff(unsigned int nr)
{
unsigned long mask = 1UL << nr;
unsigned long *ptr = __get_cpu_var(softirq_pending);
barrier();
*ptr |= mask;
}
```
该函数首先计算出对应软中断的掩码 `mask`,然后通过 `__get_cpu_var()` 函数获取当前 CPU 的软中断挂起位图指针 `ptr`,最后将对应软中断的位设置为 1。
需要注意的是,`raise_softirq_irqoff()` 函数必须在关闭中断的情况下调用,否则在多 CPU 系统中可能会导致软中断的竞争条件。
__doi_softirq大概讲讲这个函数内部每一行什么意思
`__do_softirq` 是一个内核函数,用于处理软中断(softirq)。下面是每一行的解释:
```c
notrace void __do_softirq(void)
```
这是函数的声明,表示这是一个无返回值的函数,同时也禁止对该函数进行跟踪。
```c
struct softirq_action *h;
unsigned long flags;
```
定义了两个变量,`h` 是一个指向 `softirq_action` 结构体的指针,`flags` 是一个无符号长整型数。
```c
local_irq_save(flags);
```
保存当前中断状态并关闭中断。
```c
__local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET);
```
禁用软中断。
```c
h = softirq_vec;
```
将 `softirq_vec` 赋值给变量 `h`,`softirq_vec` 是一个 `softirq_action` 类型的数组,存储了系统支持的软中断处理函数。
```c
do {
```
开始一个循环。
```c
struct softirq_action *this = READ_ONCE(*h);
```
将 `h` 指向的地址处的值读取出来,赋值给变量 `this`。`READ_ONCE` 是一个宏,用于安全地读取一个变量的值。
```c
if (this) {
```
判断 `this` 是否为空。
```c
this->action(this);
```
如果不为空,则执行 `this` 中存储的函数指针,也就是调用该软中断的处理函数。
```c
} else {
```
如果为空,则说明该软中断处理函数已经被移除,跳过本次循环。
```c
h++;
```
指向下一个 `softirq_action` 结构体。
```c
} while (this);
```
循环直到 `this` 为空。
```c
local_bh_enable();
```
启用软中断。
```c
local_irq_restore(flags);
```
恢复原来的中断状态。
阅读全文