IRQ in Linux 5.4

在 Linux 内核中,中断请求 (IRQ) 对于管理硬件中断至关重要,它允许硬件设备向处理器发出信号,表示它们需要注意。IRQ 的处理对于响应迅速且高效的系统性能至关重要。以下是 Linux 内核 5.4 中 IRQ 的详细说明,涵盖了它们的注册、处理和相关数据结构:

1. IRQ 基础知识

IRQ是发送给处理器的硬件信号,用于中断当前代码执行并处理特定事件,例如来自键盘的输入或到达的网络数据包。

中断控制器是一种对这些中断进行优先排序并将其分派给 CPU 的硬件。

2. IRQ 数据结构

Linux Kernel 5.4 中用于处理 IRQ 的关键数据结构包括:

  • struct irq_desc:代表每个中断的描述符,包含 IRQ 编号、处理程序、状态和亲和性等信息。
  • struct irq_chip:代表中断控制器硬件操作。
  • struct irqaction:表示发生中断时要采取的操作,包括处理函数和标志。

3. IRQ 注册

设备使用类似 的函数注册其中断处理程序request_irq()。以下是 IRQ 处理程序注册的简化视图:

arduino 复制代码
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
  • irq:中断号。
  • handler:中断发生时调用的函数。
  • flags:控制中断行为的标志。
  • name:中断的名称。
  • dev:指向设备特定数据的指针。

例子:

arduino 复制代码
static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
    // Handle the interrupt
    return IRQ_HANDLED;
}

int my_device_init(void)
{
    int irq = 10;  // Example IRQ number
    int ret;

    ret = request_irq(irq, my_irq_handler, IRQF_SHARED, "my_device", &my_device_data);
    if (ret) {
        pr_err("Failed to request IRQ %d\n", irq);
        return ret;
    }
    return 0;
}

4. IRQ 处理

当发生中断时,处理器停止执行当前指令并跳转到中断处理程序。流程如下:

  1. 中断发生:硬件设备发出中断信号。
  2. 中断控制器:控制器确定优先级并将中断发送给 CPU。
  3. 中断处理
    • CPU 确认中断并执行为特定 IRQ 注册的中断处理程序。
    • 处理程序执行后,控制权将返回给被中断的任务。

5. 上半部分和下半部分

Linux 将中断处理分为两部分:

  • 上半部:初始中断处理程序,它快速执行以确认中断并可能调度下半部。
  • 下半部:将大部分处理推迟到以后进行。类型包括软中断、小任务和工作队列。

6. IRQ 亲和性

IRQ 亲和性决定了哪些 CPU 处理特定中断。可以使用proc文件系统来控制:

bash 复制代码
echo 2 > /proc/irq/10/smp_affinity  # Set IRQ 10 to CPU 2

7. IRQ 管理功能

  • free_irq():释放先前分配的 IRQ。
  • disable_irq():禁用给定的 IRQ 线。
  • enable_irq():启用给定的 IRQ 线路。

8.示例演练

下面是一个简化的示例来说明 IRQ 注册和处理:

arduino 复制代码
#include <linux/module.h>
#include <linux/interrupt.h>

#define MY_IRQ 10

static irqreturn_t my_irq_handler(int irq, void *dev_id)
{
    pr_info("IRQ %d: Interrupt occurred\n", irq);
    // Handle the interrupt
    return IRQ_HANDLED;
}

static int __init my_module_init(void)
{
    int ret;

    ret = request_irq(MY_IRQ, my_irq_handler, IRQF_SHARED, "my_device", &my_device_data);
    if (ret) {
        pr_err("Failed to request IRQ %d\n", MY_IRQ);
        return ret;
    }

    pr_info("Module loaded, IRQ %d registered\n", MY_IRQ);
    return 0;
}

static void __exit my_module_exit(void)
{
    free_irq(MY_IRQ, &my_device_data);
    pr_info("Module unloaded, IRQ %d freed\n", MY_IRQ);
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Author");
MODULE_DESCRIPTION("IRQ handling example");

9.中断上下文和同步

中断处理程序在中断上下文中运行,这意味着它们不能阻塞、休眠或执行可能阻塞的操作。通常需要同步才能在中断处理程序和内核的其他部分之间安全地共享数据。自旋锁通常用于此目的。

10. 总结

  • 注册 :用于request_irq()注册中断处理程序。
  • 处理:上半部分快速处理,将较长的任务推迟到下半部分。
  • 亲和性(Affinity):控制哪个 CPU 处理中断。
  • 同步:确保中断处理程序和其他上下文之间的安全数据访问。

理解和管理 IRQ 对于开发高效且响应迅速的内核模块和设备驱动程序至关重要。Linux Kernel 5.4 继续使用这些基础概念,并进行了增强和优化,以实现更好的性能和可扩展性。

相关推荐
尘似鹤43 分钟前
linux驱动学习---有些节点不会生成platform_device,怎么访问它们
linux
iCxhust1 小时前
windows环境下在Bochs中运行Linux0.12系统
linux·运维·服务器·windows·minix
七七七七074 小时前
【计算机网络】深入理解ARP协议:工作原理、报文格式与安全防护
linux·服务器·网络·计算机网络·安全
鬼火儿7 小时前
SpringBoot】Spring Boot 项目的打包配置
java·后端
cr7xin7 小时前
缓存三大问题及解决方案
redis·后端·缓存
lhxcc_fly7 小时前
Linux网络--8、NAT,代理,网络穿透
linux·服务器·网络·nat
摇滚侠8 小时前
Spring Boot3零基础教程,Spring Boot 应用打包成 exe 可执行文件,笔记91 笔记92 笔记93
linux·spring boot·笔记
间彧8 小时前
Kubernetes的Pod与Docker Compose中的服务在概念上有何异同?
后端
yuanManGan8 小时前
走进Linux的世界:初识操作系统(Operator System)
android·linux·运维
间彧8 小时前
从开发到生产,如何将Docker Compose项目平滑迁移到Kubernetes?
后端