Linux中断学习笔记(1)

lambertCategories Linux中断

什么是中断

CPU获取外设状态变化有两种方式:
  • Polling:不断跟外设询问它的状态
  • 当外设状态变化后主动通知CPU
CPU要负责处理系统中各种各样的业务,如果频繁地轮询外设状态,必然会对整个系统的吞吐量产生影响,影响操作系统的正常运作。 中断便是外设通知CPU其状态变化的一种机制。CPU会有中断线,由中断控制器的输出线连接。中断控制器作用:
  • 中断优先级处理
  • 接收中断控制器ACK
  • 分发中断
中断控制器连接到MCU的中断输入引脚(在ARM就是IRQ-Interrupt Request or FIQ-Fast Interrupt Request信号线)。中断控制器驱动负责Kernel中断号与物理中断号的Mapping。 当外设没有变化的时候,CPU可以专心地处理其他事务。外设准备好资料时,通过中断控制器通知CPU,CPU再对其进行相应的处理。

Linux的中断处理

顶半部(Top Half)和底半部(Bottom Half)

中断会将正在运行的程序给打断(操作系统会保留相应的执行数据以便返回)。外设中断有时要处理的数据量很大,为了避免中断处理长期占用CPU导致系统中其他事务无法正常进行,Linux将中断处理分为顶半部和底半部。顶半部主要负责响应中断,处理该外设一些必须的业务,同时将需要复杂处理的事务放到底半部执行。 Linux中中断的顶半部是不能被Block的,原因: 操作系统并没有为中断分配相应的进程管理单元,当中断服务例程因为发生Block而被系统Schedule出去后,便无法再返回到该中断服务例程。而因为中断被调度出的进程,被schedule后却不能得到调度。 实现底半部有多种方式,常用的是Tasklet(特殊的软中断)和Workqueue(内核线程)

软中断和Tasklet

当中断上半部执行结束后,操作系统会调度执行软中断。具体实现以linux-4.x为例:
./kernel/softirq.c

void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)                //中断向量表调用相应的IRQ处理函数
{
    struct pt_regs *old_regs = set_irq_regs(regs);                      //保留中断现场

    irq_enter();                                                        //进入中断处理前的必要处理,如关闭硬件中断,关闭抢占(preempt),禁止ksoftirqd启动处理(softirq)-- 因为稍后会看到,中断结束后会做处理
    generic_handle_irq(irq);                                            //执行外设驱动注册的irq handler
    irq_exit();                                                         //进入到irq_exit
    set_irq_regs(old_regs);
}
void irq_exit(void)
{
#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
    local_irq_disable();
#else
    WARN_ON_ONCE(!irqs_disabled());
#endif
    account_irq_exit_time(current);
    preempt_count_sub(HARDIRQ_OFFSET);                                 //打开抢占
    if (!in_interrupt() && local_softirq_pending())                    //如果有软中断pending,执行softirq
        invoke_softirq();
    tick_irq_exit();
    rcu_irq_exit();
    trace_hardirq_exit(); 
}
可以看到,软中断是在中断处理进程退出后,立即执行。软中断处理函数,会检查当前系统中有哪些软中断,然后循环执行。因为系统仍有很多任务要处理,包括之前被抢占的任务,因此kernel不会无限度的将时间片都留给软中断。它设置了一个软中断循环执行的最大次数。当超过这个次数后,就退出软中断执行,并将内核线程ksoftirqd叫起。 ksoftirqd是内核线程,他与系统中其他线程包括用户态进程一起接受系统调度。因此保证了未完成的软中断也可再后来继续执行完毕。 Tasklet是一种特殊的软中断。Workqueue是一种特殊的内核线程。它们都是实现中断下半部的方式。具体用法可在有使用需求时查看。

irq 在多处理器系统的分发

  • 中断亲和力:多处理系统中,操作系统会按照一定策略把中断分配到各CPU Core来处理。中断亲和力高的CPU Core,操作系统会倾向于把中断交给其处理
  • 通过修改/proc/irq/smp_affinity 可以改变Linux的中断亲和力
  • 内核线程kirqd:周期性执行do_irq_balance()。Track最近时间间隔每个Core的接收中断次数,动态做Balance
 

相关文章

Linux中断学习笔记(2) — 嵌入式设备中断... 在Linux中断学习笔记(1)提到,外设通过中断控制器连接到CPU的中断线。嵌入式系统也不例外。 ARM嵌入式系统GIC架构 ARM官网所举图为例:ARM的中断控制器GIC(General Interrupt Controller)将从外设输入的中断通过CPU的IRQ信号线(ARM中主要为FIQ...
Linux虚拟文件系统(4)– 路径名查找... 前言 几乎所有Linux的文件操作,例,read、write、mkdir等都会涉及到路径名查找操作。而文件查找对Linux内核来说,主要指的是找到文件路径对应的Dentry节点。其主要过程就是对路径字符串进行一级级解析(以路径名中的.. , . , /等字符作为解析依据),找到路径的最后一级目录。...
Linux电源管理介绍-1 前言 为了节省功耗,需要让系统在不需要工作的时候尽可能的休眠(甚至断电)。同时,为了不影响到系统功能的正常运作,又必须保证休眠不能打断正在进行的重要事务,且能在适时还原回来。因此,一个高效运行的Low Power框架必不可少。 本文以Linux 4.4内核为基础,介绍Linux的Lo...
Linux虚拟文件系统(2)– 初始化流程... 本文介绍Linux虚拟文件系统的初始化过程。如下图: +-----> start_kernel() | | +-----> vfs_caches_init_early() | | +-----> vfs_caches_init() | ...
Linux虚拟文件系统(1)   VFS简介 说明:本系列文章均以Linux 4.4为原型进行分析 Linux将系统中很多资源都抽象成文件,如Socket、设备节点、以及内存。可以如此做,归功于Linux操作系统的虚拟文件系统(VFS)。 有了VFS,无论底层文件系统格式是FAT、ext格式甚至是内存,...

版权声明:本站文章除非特别声明,均为L&H原创。允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。

本文链接:Linux中断学习笔记(1) @ L&H site


2 thoughts on “Linux中断学习笔记(1)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

90 − 86 =

This site uses Akismet to reduce spam. Learn how your comment data is processed.