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 继续使用这些基础概念,并进行了增强和优化,以实现更好的性能和可扩展性。

相关推荐
Ljubim.te6 分钟前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
cooldream200920 分钟前
Linux性能调优技巧
linux
千里码aicood1 小时前
【2025】springboot教学评价管理系统(源码+文档+调试+答疑)
java·spring boot·后端·教学管理系统
QMCY_jason1 小时前
Ubuntu 安装RUST
linux·ubuntu·rust
慕雪华年1 小时前
【WSL】wsl中ubuntu无法通过useradd添加用户
linux·ubuntu·elasticsearch
苦逼IT运维1 小时前
YUM 源与 APT 源的详解及使用指南
linux·运维·ubuntu·centos·devops
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
仍有未知等待探索2 小时前
Linux 传输层UDP
linux·运维·udp
liuxin334455662 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
zeruns8022 小时前
如何搭建自己的域名邮箱服务器?Poste.io邮箱服务器搭建教程,Linux+Docker搭建邮件服务器的教程
linux·运维·服务器·docker·网站