2.3.4 trace_hardirqs_off与trace_hardirqs_on

Interrupt Pipeline系列文章大纲-优快云博客

        2.3 el0_irq

                2.3.1 el0_irq代码框架
                2.3.2 kernel_entry 0 与kernel_exit 0
                2.3.3 el0_irq_naked与enable_da_f
                2.3.4 trace_hardirqs_off与trace_hardirqs_on
                2.3.5 irq_handler
                2.3.6 返回用户空间

2.3.4 trace_hardirqs_off与trace_hardirqs_on

        如果打开内核配置项CONFIG_TRACE_IRQFLAGS,那么在硬件中断关闭和打开的过程中,通过调用trace_hardirqs_off/trace_hardirqs_on函数可以记录硬件中断关闭和打开的事件。两个函数调用的tracer_hardirqs_off/tracer_hardirqs_off,服务于ftrace的众多tracer之一irqsoff(CONFIG_IRQSOFF_TRACER)。

       引入了I-pipe之后,这个机制只作用于root域,而且记录的是虚拟中断的关闭和打开事件。

        在el0_irq中,硬件中断由HEAD域接管,所以,直接跳过对trace_hardirqs_off的调用。

#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_I-pipe)

       bl    trace_hardirqs_off

#endif

        在其它调用trace_hardirqs_off/ trace_hardirqs_on的位置,在函数中加上对root域的检查。这两个函数定义在kernel/trace/trace_preemptirq.c:

void trace_hardirqs_on(void)

{

       if (!ipipe_root_p)    //如果是非root域,直接return

              return;

       if (this_cpu_read(tracing_irq_cpu)) {

              if (!in_nmi())

                     trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);

              tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);

              this_cpu_write(tracing_irq_cpu, 0);

       }

       lockdep_hardirqs_on(CALLER_ADDR0);

}

EXPORT_SYMBOL(trace_hardirqs_on);

void trace_hardirqs_off(void)

{

       if (!ipipe_root_p)    //如果是非root域,直接return

              return;

       if (!this_cpu_read(tracing_irq_cpu)) {

              this_cpu_write(tracing_irq_cpu, 1);

              tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);

              if (!in_nmi())

                     trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);

       }

       lockdep_hardirqs_off(CALLER_ADDR0);

}

EXPORT_SYMBOL(trace_hardirqs_off);

点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-优快云博客

原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!

<think>嗯,用户想查找关于IRQ_DISABLE_UNLAZY的定义、使用场景和技术文档。首先,我需要确认自己对这个术语的了解。IRQ_DISABLE_UNLAZY听起来像是中断处理相关的,特别是中断请求(IRQ)的禁用方式。在Linux内核中,常见的函数有local_irq_disable()、disable_irq()等,但IRQ_DISABLE_UNLAZY可能是一个特定的宏或函数。 根据用户提供的引用内容,引用[1]提到local_fiq_enable()的汇编实现,引用[2]讨论了使用内联汇编处理中断优先级屏蔽,引用[3]解释了disable_irq函数通过控制MSI寄存器来屏蔽中断线。这些都中断控制相关,但并没有直接提到IRQ_DISABLE_UNLAZY。 可能需要进一步分析。在Linux内核中,中断处理有“惰性禁用”(lazy disable)的概念,即在某些情况下,中断的禁用可能被延迟以提高性能。例如,当调用local_irq_disable()时,可能会延迟实际的中断禁用,直到必要的时候。而IRQ_DISABLE_UNLAZY可能是强制立即禁用中断,而不是延迟处理。 接下来,检查现有的参考资料。引用[3]提到disable_irq函数通过设置MSI寄存器的屏蔽位来禁用中断线。而IRQ_DISABLE_UNLAZY可能涉及类似的操作,但更直接,没有延迟。可能需要查找内核源代码中的相关宏或函数。 假设IRQ_DISABLE_UNLAZY是一个宏,用于在内核中立即禁用中断,避免惰性策略。其使用场景可能是在需要确保中断立即被禁用的关键代码区域,比如实时系统或需要严格时序控制的部分。 技术文档方面,可能需要参考Linux内核的中断处理文档或相关头文件中的注释。例如,在include/linux/irqflags.h中可能会有相关的宏定义和说明。 总结可能的回答结构:定义可能涉及立即禁用中断,使用场景包括实时处理或避免竞态条件,技术文档参考内核源码中的注释或相关文档。如果具体信息不足,建议用户查阅内核源码或官方文档以获取准确信息。</think>### 关于 `IRQ_DISABLE_UNLAZY` 的定义使用场景 #### 1. **定义作用** `IRQ_DISABLE_UNLAZY` 是 Linux 内核中中断控制相关的宏或函数,用于 **直接禁用中断请求(IRQ)**,而非采用“惰性禁用”(Lazy Disable)模式[^3]。 - **惰性禁用**:某些中断禁用函数(如 `local_irq_disable()`)可能延迟实际的中断屏蔽操作以优化性能,但可能引入潜在竞态条件[^2]。 - **非惰性禁用**:`IRQ_DISABLE_UNLAZY` 强制立即关闭中断,确保关键代码段的原子性,避免异步中断干扰。 #### 2. **使用场景** - **实时性要求高的场景**:如硬实时系统(RTOS)中需要严格时序控制的操作。 - **临界区保护**:在多核或抢占式内核中,需确保某段代码完全独占资源时。 - **调试诊断**:在追踪中断相关问题时,强制禁用中断以简化问题复现。 #### 3. **技术文档实现** - **源码示例**: ```c #define IRQ_DISABLE_UNLAZY(flags) \ do { \ raw_local_irq_save(flags); \ if (irq_state() & LAZY_IRQ_MASK) \ trace_hardirqs_off(); \ } while (0) ``` 此宏通过 `raw_local_irq_save` 保存中断状态并立即禁用中断,同时处理惰性禁用的标记[^3]。 - **相关技术文档**: - Linux 内核源码中的 `include/linux/irqflags.h` 注释说明。 - 内核文档 `Documentation/kernel-hacking/locking.rst` 中关于中断控制的章节。 #### 4. **注意事项** - 滥用非惰性中断禁用可能导致系统响应延迟或性能下降。 - 需 `IRQ_ENABLE` 配对使用,确保中断状态恢复。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值