眼下正在调试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中断分析的更多相关文章

  1. stm32F4中断分析-HAL库

    详细可以参考: STM32使用HAL库操作外部中断——实战操作 https://www.cnblogs.com/wt88/p/9624103.html /** ******************** ...

  2. LINUX-内核-中断分析-中断向量表(3)-arm【转】

    转自:http://blog.csdn.net/haolianglh/article/details/51986987 arm中断概念 在<ARM体系结构与编程>第9章中说到,ARM 中有 ...

  3. STM32中按键中断分析

    在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...

  4. 一次数据库hang住的分析过程

    现象: 普通用户和sysdba都无法登陆,业务中断 分析过程: 1.先做hanganalyze和systemstate dump $sqlplus -prelim "/as sysdba&q ...

  5. FreeRTOS 启动进程调度后,程序卡死的部分原因分析。

    现象:1,RTOS  使用时 系统卡启动文件               B       .处. 原因分析:该种情况是由于定义开启了中断,但是未开启中断处理服务.程序执行到中断响应式无对应的程序响应 ...

  6. 非常好!!!Linux源代码阅读——中断【转】

    Linux源代码阅读——中断 转自:http://home.ustc.edu.cn/~boj/courses/linux_kernel/2_int.html 目录 为什么要有中断 中断的作用 中断的处 ...

  7. 《Tsinghua os mooc》第1~4讲 启动、中断、异常和系统调用

    资源 OS2018Spring课程资料首页 uCore OS在线实验指导书 ucore实验基准源代码 MOOC OS习题集 OS课堂练习 Piazza问答平台 暂时无法注册 疑问 为什么用户态和内核态 ...

  8. 认识Java Core和Heap Dump

    什么是Java Core和Heap Dump Java程序运行时,有时会产生Java Core及Heap Dump文件,它一般发生于Java程序遇到致命问题的情况下. 发生致命问题后,Java进程有时 ...

  9. Java Core和HeapDump

    什么是Java Core和Heap Dump Java程序运行时,有时会产生Java Core及Heap Dump文件,它一般发生于Java程序遇到致命问题的情况下. 发生致命问题后,Java进程有时 ...

随机推荐

  1. Entity Framework(实体框架 EF)

    什么是Entity Framework呢(下面简称EF)? EF(实体框架)是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架.ORM(对象关系映射框架):指的是面向 ...

  2. Circular dependencies cannot exist in RelativeLayout

    循环布局错误!!! <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  3. [BZOJ4423][AMPPZ2013]Bytehattan(对偶图+并查集)

    建出对偶图,删除一条边时将两边的格子连边.一条边两端连通当且仅当两边的格子不连通,直接并查集处理即可. #include<cstdio> #include<algorithm> ...

  4. 通过wifi上网,桥接模式下virtualBox虚拟机无法连上网的解决办法

    https://jingyan.baidu.com/article/948f59242e601dd80ff5f929.html

  5. Educational Codeforces Round 12 C. Simple Strings 贪心

    C. Simple Strings 题目连接: http://www.codeforces.com/contest/665/problem/C Description zscoder loves si ...

  6. PHP中getenv()和$_SERVER的区别

    PHP中getenv()和$_SERVER的用法区别: getenv 取得系统的环境变量,环境变量的格式为name=value. 语法: string getenv(string varname); ...

  7. 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 ...

  8. minor gc和full gc

    Minor GC ,Full GC 触发条件 Minor GC触发条件:当Eden区满时,触发Minor GC. Full GC触发条件: (1)调用System.gc时,系统建议执行Full GC, ...

  9. openfire Hazelcast插件集群配置

    原文:http://blog.csdn.net/frankcheng5143/article/details/48708899 注意虽然hazelcast 官方已经有了3.5.2版本,但是openfi ...

  10. bionase

    BIONASE BIONASE是一个革命性的新设备,针对过敏性鼻炎(花粉病或枯草热)以及大多其他类型的鼻炎.BIONASE能够缓解以及有效阻止与过敏性鼻炎相关的临床症状,例如:鼻塞,打喷嚏,头疼以及流 ...