edge中断分析
眼下正在调试msix中断,在測试过程中发现会概率性的丢失中断。Msix中断默认是edge触发的中断,edge触发的中断是在中断相应pin发生电平信号跳变的时候,会发出一个中断请求。
由于跳变是一瞬间的。不会像level触发中断那样一直保持电平不变,这样就可能会漏掉某一个跳变的瞬间,表现就是丢失了一个中断。
内核中处理edge触发中断的函数为handle_edge_irq,此函数有do_IRQ函数调用而来。
void handle_edge_irq(unsigned int irq, struct irq_desc *desc) { raw_spin_lock(&desc->lock); /*由于接收到中断,所以清除以下两个标志*/ desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); /*IRQ是否被禁止,或者正在处理中。或者没有挂接中断处理函数*/ if (unlikely(irqd_irq_disabled(&desc->irq_data) || irqd_irq_inprogress(&desc->irq_data) || !desc->action)) { if (!irq_check_poll(desc)) { desc->istate |= IRQS_PENDING; /*设置irq处于挂起状态*/ mask_ack_irq(desc); /*向硬件发ACK,屏蔽中断*/ goto out_unlock; } } kstat_incr_irqs_this_cpu(irq, desc); /*process/interrupts中相应irq计算加1*/ /*cpu对此IRQ的回应,表示准备接收此IRQ的下一个中断*/ desc->irq_data.chip->irq_ack(&desc->irq_data); do { if (unlikely(!desc->action)) { /*没有挂接中断处理函数*/ mask_irq(desc); /*屏蔽IRQ*/ goto out_unlock; } /*IRQ处于中断挂起状态*/ if (unlikely(desc->istate & IRQS_PENDING)) { if (!irqd_irq_disabled(&desc->irq_data) && irqd_irq_masked(&desc->irq_data)) unmask_irq(desc); } /*处理中断*/ handle_irq_event(desc); } while ((desc->istate & IRQS_PENDING) && /*有挂起的中断须要处理*/ !irqd_irq_disabled(&desc->irq_data)); /*irq没有禁止*/ |
istate成员刚開始在irq_desc结构体中没找到,事实上它的定义例如以下
#define istate core_internal_state__do_not_mess_with_it
istate相应的是core_internal_state__do_not_mess_with_it成员。
IRQS_REPLAY标志是用来拯救丢失的中断。此标志在check_irq_resend函数中设置,通过中断控制器APIC上的中断信号又一次向cpu发中断。而不是通过外设硬件来重发中断。这里进入到了handle_edge_irq函数表示已经收到了中断。不须要重发,所以清除此标志。
IRQS_WAITING标志表示中断的到来,这里收到了中断,因此也清除此标志。
此标志在handle_xxx_irq函数的開始都会清除掉。
假设<1>当前irq被禁止,<2>当前irq正在处理中,<3>当前irq没有挂接处理函数。则我们不处理接收到的此IRQ。假设满足上面的条件,我们就设置此IRQ为IRQS_PENDING挂起状态,并屏蔽中断,然后返回。放弃中断的处理过程,留给正在处理此IRQ中断的cpu来处理此次pending的中断。
irq_ack函数的底层实现是写eoi寄存器。是cpu对此IRQ的回应,表示irq希望清除此IRQ的pending状态(用于清除APIC IRR的pending位),准备接收下一个中断。这样其它的cpu就能够接收此IRQ进行处理了。
程序接下来是一个while循环,循环的条件是此IRQ没有被禁止而且有pending的待处理的中断。
由于在处理中断的过程中,由于ack了。可能其它的cpu又接收到了此IRQ新的中断。
假设此IRQ没有挂接中断处理函数,就直接屏蔽此IRQ,返回。
假设irq处于IRQS_PENDING状态。中断没有被禁止可是被屏蔽的情况下。调用unmask_irq取消屏蔽。想想为什么会处于IRQS_PENDING状态。并这样处理?前面讲到当此IRQ正在处理中,新接收到的中断,就会设置IRQS_PENDING状态。并屏蔽此IRQ。
Edge触发方式的中断easy丢中断,因此在处理中断时候不能长时间的屏蔽IRQ。
在handle_edge_irq函数一上来就推断在irq没用被禁止,没用正在处理的情况下,仅仅是ack回应了硬件。没用屏蔽irq,表示另外的cpu能够接收此IRQ的中断。
edge中断分析的更多相关文章
- stm32F4中断分析-HAL库
详细可以参考: STM32使用HAL库操作外部中断——实战操作 https://www.cnblogs.com/wt88/p/9624103.html /** ******************** ...
- LINUX-内核-中断分析-中断向量表(3)-arm【转】
转自:http://blog.csdn.net/haolianglh/article/details/51986987 arm中断概念 在<ARM体系结构与编程>第9章中说到,ARM 中有 ...
- STM32中按键中断分析
在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...
- 一次数据库hang住的分析过程
现象: 普通用户和sysdba都无法登陆,业务中断 分析过程: 1.先做hanganalyze和systemstate dump $sqlplus -prelim "/as sysdba&q ...
- FreeRTOS 启动进程调度后,程序卡死的部分原因分析。
现象:1,RTOS 使用时 系统卡启动文件 B .处. 原因分析:该种情况是由于定义开启了中断,但是未开启中断处理服务.程序执行到中断响应式无对应的程序响应 ...
- 非常好!!!Linux源代码阅读——中断【转】
Linux源代码阅读——中断 转自:http://home.ustc.edu.cn/~boj/courses/linux_kernel/2_int.html 目录 为什么要有中断 中断的作用 中断的处 ...
- 《Tsinghua os mooc》第1~4讲 启动、中断、异常和系统调用
资源 OS2018Spring课程资料首页 uCore OS在线实验指导书 ucore实验基准源代码 MOOC OS习题集 OS课堂练习 Piazza问答平台 暂时无法注册 疑问 为什么用户态和内核态 ...
- 认识Java Core和Heap Dump
什么是Java Core和Heap Dump Java程序运行时,有时会产生Java Core及Heap Dump文件,它一般发生于Java程序遇到致命问题的情况下. 发生致命问题后,Java进程有时 ...
- Java Core和HeapDump
什么是Java Core和Heap Dump Java程序运行时,有时会产生Java Core及Heap Dump文件,它一般发生于Java程序遇到致命问题的情况下. 发生致命问题后,Java进程有时 ...
随机推荐
- Entity Framework(实体框架 EF)
什么是Entity Framework呢(下面简称EF)? EF(实体框架)是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架.ORM(对象关系映射框架):指的是面向 ...
- Circular dependencies cannot exist in RelativeLayout
循环布局错误!!! <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- [BZOJ4423][AMPPZ2013]Bytehattan(对偶图+并查集)
建出对偶图,删除一条边时将两边的格子连边.一条边两端连通当且仅当两边的格子不连通,直接并查集处理即可. #include<cstdio> #include<algorithm> ...
- 通过wifi上网,桥接模式下virtualBox虚拟机无法连上网的解决办法
https://jingyan.baidu.com/article/948f59242e601dd80ff5f929.html
- Educational Codeforces Round 12 C. Simple Strings 贪心
C. Simple Strings 题目连接: http://www.codeforces.com/contest/665/problem/C Description zscoder loves si ...
- PHP中getenv()和$_SERVER的区别
PHP中getenv()和$_SERVER的用法区别: getenv 取得系统的环境变量,环境变量的格式为name=value. 语法: string getenv(string varname); ...
- Can't deserialize with binaryFormatter after changing namespace of class
After changing the namespace of my class I can no longer deserialize the objects. I've implemented S ...
- minor gc和full gc
Minor GC ,Full GC 触发条件 Minor GC触发条件:当Eden区满时,触发Minor GC. Full GC触发条件: (1)调用System.gc时,系统建议执行Full GC, ...
- openfire Hazelcast插件集群配置
原文:http://blog.csdn.net/frankcheng5143/article/details/48708899 注意虽然hazelcast 官方已经有了3.5.2版本,但是openfi ...
- bionase
BIONASE BIONASE是一个革命性的新设备,针对过敏性鼻炎(花粉病或枯草热)以及大多其他类型的鼻炎.BIONASE能够缓解以及有效阻止与过敏性鼻炎相关的临床症状,例如:鼻塞,打喷嚏,头疼以及流 ...