一种Linux下共享中断的处理方法

简介:

 前段时间调试一款芯片的时候,碰到一个奇怪的问题:只要在板卡上插入一个PS2键盘,启动内核时系统就可能会进入串口中断函数去执行,过一会系统就panic不往下继续执行。后来经过分析出现问题时的panic的堆栈,借助EJTAG工具,读到这个时候的串口的中断状态位,竟然发现串口并没有真正产生中断。那么,串口本身没有中断,内核怎么又会跑到串口的中断服务函数去执行呢?


    我们知道Linux的中断可以分为I/O 中断 、时钟中断和处理器核间中断。其中I/O中断是Linux 系统响应外部IO事件的重要方式。尽管不同的平台和体系结构实现的方法不一样,但是都支持不同的设备共享同一个中断向量 。例如在PCI的总线结构中,几个设备可以共享同一个IRQ线,也即它们共享一个中断号,各自的中断服务例程挂在这个中断号上。当CPU响应这个IRQ时,会逐一检查挂在这个中断向量上的例程,并且执行那些真正有中断的例程。但是串口明显不属于PCI,不可能用到PCI的中断线和中断引脚寄存器,那又是什么原因导致kernel panic呢?


    带着上面的这些问题,和硬件工程师和芯片设计的同事深入讨论了各种可能性,最后结合芯片板卡原理图,发现这个板子上的低速设备都集成在芯片内部,这些低速设备包括串口、LPC只是控制器、SPI控制、I2C控制器、NAND控制器等,其中CPU UART和LPC的中断信号都路由到同一个CPU的中断引脚。 具体的连接图如下所显:



通过上图最左侧的部分可以看到,CPU UART和CPU LPC控制器的中断请求信号经过逻辑或后,输出到了CPU 芯片内Interrupt Pending Bit2。一旦CPU检测到任何一个Interrupt Pending位被设置起来,它就会根据约定的顺序逐一查询各个Interrupt Pending Bit,并且执行中断路由到这个bit上的设备驱动的中断服务例程。


在老版本的板卡设计中,CPU LPC上没有接任何设备,当时没有碰到前面提到的问题。后来,由于客户的需求,板卡上CPU LPC端口上可以连接PS2 键盘和鼠标,问题也随之暴露。因此,我猜测问题的根源是由于没有对共享IP2的连接到LPC上的设备的中断进行处理。按照这一思路,检查了之前的中断分发处理函数,发现果然在处理IP2时,只调用了do_irq(58)。参考内核中串口驱动的代码可以知道,第一个CPU UART的中断号默认是58。因此在这种情况下一旦接入的PS2键盘或鼠标发出中断信号,现有的代码就会不分青红皂白地去执行do_irq(58)。显然,这不是期望的行为,需要查询各自的中断状态位来检测到底该响应那个设备的中断。在最新的Linux 4.2内核主干分支里,我们仍然可以找到这部分有待完善的代码:arch/mips/loongson64/loongson-3/irq.c:


void mach_irq_dispatch(unsigned int pending)

{

       if (pending & CAUSEF_IP7)

               do_IRQ(LOONGSON_TIMER_IRQ);

#if defined(CONFIG_SMP)

       else if (pending & CAUSEF_IP6)

               loongson3_ipi_interrupt(NULL);

#endif

       else if (pending & CAUSEF_IP3)

               ht_irqdispatch();

       else if (pending & CAUSEF_IP2)

               do_IRQ(LOONGSON_UART_IRQ);

       else {

               pr_err("%s : spurious interrupt\n", __func__);

               spurious_interrupt();

       }

}


    另外,该芯片中LPC上的中断信号是电平触发,根据LPC配置寄存器的定义,当中断完成之后,需要清除LPC SIRQ,这就需要添加响应的中断ack和eoi等函数。与此相反的是,兼容NS16550A的串口上的中断是边沿触发,不需要程序去清除:当传输保存寄存器为空时,串口的ISR的bit 1会被设置起来,一旦写数据到传输保存寄存器,这个bit就会被清掉;当接收FIFO中字符的个数达到trigger的水平时,ISR的bit 2会被设置起来,直到程序读接收FIFO。


    根据上面的两点思路,修改了响应的代码,重新编译内核,重新做了大量测试,没有再复现前文提到的问题。通过这个例子,我们可以看到:除了PCI中断这种共享中断向量的机制之外,还有不同物理设备的中断信号路由到同一个中断引脚但使用不同中断号的情况。针对这种情况。工程师需要综合芯片结构、硬件连接、中断路由及内核中断处理流程,全面考虑各种情况,给出完善、健壮的解决方案。但比较这两者的异同之后,不难发现其实本质还是一样的:不管中断号是否一样,任何路由到CPU内部中断或者外部中断控制器上的设备,都应享用被服务的机会,不能遗漏。


















本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1690309 ,如需转载请自行联系原作者





相关文章
|
28天前
|
网络协议 Shell Linux
【Shell 命令集合 网络通讯 】Linux 提供SMB共享 smbd命令 使用指南
【Shell 命令集合 网络通讯 】Linux 提供SMB共享 smbd命令 使用指南
38 0
|
3月前
|
网络协议 Linux 网络安全
Linux服务器配置指南:网络、用户管理、共享服务及DNS配置详解
Linux服务器配置指南:网络、用户管理、共享服务及DNS配置详解
149 0
|
4月前
|
人工智能 Ubuntu Linux
linux配置魔搭社区modelscope时的whl下载中断问题和解决方案
本文提供了断点续传和手动安装两个方案。
112 3
|
4月前
|
存储 安全 Linux
Linux中断(tasklet,工作队列,内核线程的使用)
Linux中断(tasklet,工作队列,内核线程的使用)
38 0
|
4月前
|
存储 Linux API
Linux系统对中断的处理
Linux系统对中断的处理
50 0
|
13天前
|
Linux 虚拟化 芯片
Linux 中断子系统中GIC 中断控制器基本分析
Linux 中断子系统中GIC 中断控制器基本分析
60 0
|
5月前
|
存储 网络协议 Linux
基于ARM+Linux中断系统详细分析
基于ARM+Linux中断系统详细分析
基于ARM+Linux中断系统详细分析
|
6月前
|
网络协议 虚拟化 Windows
75Linux - VMware虚拟机三种联网方法( Host-Only私有网络共享主机:默认使用VMnet1 )
75Linux - VMware虚拟机三种联网方法( Host-Only私有网络共享主机:默认使用VMnet1 )
62 0
|
7月前
|
存储 Linux
如何在 Linux 上创建共享 VxFS 文件系统?
如何在 Linux 上创建共享 VxFS 文件系统?
51 0
|
7月前
|
Linux
Linux内核分析与应用5-中断
Linux内核分析与应用5-中断
44 0