local_irq_disable:
local_irq_disable的功能是屏蔽当前CPU上的所有中断,通过操作arm核心中的寄存器来屏蔽到达CPU上的中断,此时中断控制器中所有送往该CPU上的中断信号都将被忽略。
Kernel/arch/arm/include/asm/irqflag.h

static inline void arch_local_irq_disable(void)
{asm volatile("   cpsid i         @ arch_local_irq_disable"::: "memory", "cc");
}

kernel/include/linux/irqflags.h

#define raw_local_irq_disable()     arch_local_irq_disable()#define local_irq_disable() \do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)

disable_irq:
在全局范围内屏蔽某一个中断号(irq num)。该irq num对应的irq handler不会在任何一个CPU上执行。这个操作是通过设置中断控制器中的寄存器来对指定中断进行屏蔽,而其他未屏蔽的中断依然可以正常送往CPU。

413 void disable_irq(unsigned int irq)414 {415     if (!__disable_irq_nosync(irq))416         synchronize_irq(irq);417 }372 static int __disable_irq_nosync(unsigned int irq)373 {374     unsigned long flags;375     struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_     CHECK_GLOBAL);376 377     if (!desc)378         return -EINVAL;379     __disable_irq(desc, irq, false);380     irq_put_desc_busunlock(desc, flags);381     return 0;382 }383360 void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)361 {362     if (suspend) {363         if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))364             return;365         desc->istate |= IRQS_SUSPENDED;366     }367 368     if (!desc->depth++)369         irq_disable(desc);370 }

chip.c

216 void irq_disable(struct irq_desc *desc)
217 {
218     irq_state_set_disabled(desc);
219     if (desc->irq_data.chip->irq_disable) {
220         desc->irq_data.chip->irq_disable(&desc->irq_data);
221         irq_state_set_masked(desc);
222     }
223 }160 static void irq_state_set_disabled(struct irq_desc *desc)
161 {
162     irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
163 }

一个中断处理的流程是这样的:
关CPU中断——–>mask and ack interrupt controller——–>设备驱动中注册的irq_handler ——>unmask interrupt controller——–>开CPU中断
我们需要在irq_handler中做如下处理,其中包含了一个启动下半部softirq的操作(可选)。
ack device irq——–>copy data to ram——>raise softirq

在代码中,是这样的调用流程:
High level irq handler
–> mask_ack_irq
–>chip->irq_mask
–>chip->irq_ack
–> handle_irq_event (就是调用irq_handler的处理)
–>chip-> irq_unmask

对于中断的处理,内核有一套自己的流程,它会调用high level irq handler来做最上层的处理,内核中定义了多种high level irq handler,比如电平触发方式的处理函数handle_level_irq,还有边缘触发方式的处理函数handle_edge_irq等等。每个handler都需要在特定场景下才能使用,它会被赋值给irqchip驱动,并由chip来调用使用。

具体可以参考蜗窝上的文章,对两种场景有比较详细的介绍。我们接下来讨论电平触发的场景,来看看如何在所有CPU上进行屏蔽中断的。其他场景可以举一反三。


void handle_level_irq(unsigned int irq, struct irq_desc *desc)
{ raw_spin_lock(&desc->lock); mask_ack_irq(desc); if (unlikely(irqd_irq_inprogress(&desc->irq_data))) if (!irq_check_poll(desc)) goto out_unlock; desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);--和retrigger中断以及自动探测IRQ相关 kstat_incr_irqs_this_cpu(irq, desc); if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) { desc->istate |= IRQS_PENDING; goto out_unlock; } handle_irq_event(desc); cond_unmask_irq(desc);
out_unlock: raw_spin_unlock(&desc->lock);
}

从代码中可以看到,在函数中首先做的就是mask_ack_irq,在其中会调用chip中的回调来设置硬件。

static inline void mask_ack_irq(struct irq_desc *desc){if (desc->irq_data.chip->irq_mask_ack)desc->irq_data.chip->irq_mask_ack(&desc->irq_data);else {desc->irq_data.chip->irq_mask(&desc->irq_data);if (desc->irq_data.chip->irq_ack)desc->irq_data.chip->irq_ack(&desc->irq_data);}irq_state_set_masked(desc);}

该函数中调用的就是chip中的irq_mask和irq_ack来操作chip中的寄存器.其中的irqd_irq_disabled就是用来判断该中断是否被其他CPU给disable了,这里的disable就是调用disable_irq函数来做的,由此可见,使用disable_irq会在所有的CPU上把中断号给屏蔽掉。

当在一个CPU上调用了disable_irq的时候,可能另一个CPU已经接收了中断了,但是在handler的处理中可以看到,它会判断是否被其它CPU disable了,如果disable了,它会把这个中断标志设置为IRQS_PENDING,但并不会去执行irq handler,而是直接退出,此时也没有调用unmask函数,由此就屏蔽了该中断,注意这里的mask和ack只是对于中断控制器到CPU上的信号进行了屏蔽,而外设到中断控制器上的中断信号并没有消失。
而在使能中断函数enable_irq中,我们可以看到它会调用unmask来取消该中断的屏蔽。由于是电平触发,所以当unmask后,中断控制器立刻就会感知到外设上的中断信号。由此进入中断处理流程。

local_irq_disable和disable_irq的区别相关推荐

  1. local_irq_disable

    local_irq_disable仅仅是设置当前CPU的中断屏蔽位 disable_irq 是禁用全部cpu中断(只是当前irq) 如果你要禁止所有的中断该怎么办? 在2.6内核中,可以通过下面两个函 ...

  2. 【转】spin_lock、spin_lock_irq、spin_lock_irqsave区别

    为什么80%的码农都做不了架构师?>>>    转自:http://blog.csdn.net/luckywang1103/article/details/42083613 void ...

  3. 互斥与同步——local_irq_enable与local_irq_disable

    互斥与同步--local_irq_enable与local_irq_disable 内核版本:2.6.30 平台:arm 在单处理器不可抢占系统中,使用local_irq_enable和local_i ...

  4. 六、系统软中断、tasklet、工作队列work queue的区别及使用

    前言:这篇文章不会对系统软中断.tasklet.工作队列work queue的内核实现机制进行深入分析,仅仅是谈一下这几种机制的不同以及简单的使用.有描述不对的地方,欢迎大家指出. 说明:在分析具体代 ...

  5. get_user_pages和get_user_pages_fast的区别

    最近工作中经常遇见get_user_pages和get_user_pages_fast,虽然知道他们都是用来pin住一个页的,但是依然没搞明白后者是如何实现fast的,两者的区别具体在哪.刚好利用周末 ...

  6. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

    1. 基本概念 PRC 远程过程调用 Remote Procedure Call,其就是一个节点请求另外一个节点提供的服务.当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手 ...

  7. C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别

    最近看公司代码的时候发现在判断指针是否为空的时候,有的时候用的是 NULL, 有的时候用的是 nullptr 感觉很奇怪,好奇心驱使我查了下两者的区别,发现还是有很多细节需要学习的. 1. NULL ...

  8. gcc 和 g++ 的联系和区别,使用 gcc 编译 c++

    GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器. 实际使用中我们更习惯使用 gcc 指令编译 C 语言程序 ...

  9. Python2 与 Python3 区别

    Python2.x 与 Python3.x 区别 1. print 函数 Python2 中 print 是语句(statement),Python3 中 print 则变成了函数.在 Python3 ...

最新文章

  1. redis批量操作及性能分析
  2. Tomcat 最新版安装与使用手册,tomcat更改端口号方法,tomcat控制台乱码问题解决方法
  3. Lvs+keepalived   实现负载均衡、故障剔除(DR模式)
  4. kali2017添加国内更新源 + 配置并开启sshd
  5. error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
  6. lamda过滤_java 使用Lambda和filter对对象集合过滤
  7. ICCV 2019 | 基于轻量级新架构OSNet的域适应改进ReID
  8. python程序设计课后答案第三单元_最新Python程序设计课后习题答案-第一单元
  9. ssas如何创建分区_Analysis Services(SSAS)多维设计技巧–创建尺寸
  10. 在linux4.19内核下的UPD720201驱动里添加固件下载的代码
  11. DID会固定年份吗_互助问答第31期:固定效应与随机效应选择和面板数据处理
  12. Linux内核原语(九)——互斥体(mutex)
  13. 益聚星荣:如何有理有据地给元宇宙泼一盆冷水?
  14. Docker编译安装httpd
  15. 数据分析统计学基础笔记
  16. hdu 1430 魔板
  17. Java 中 Pair 类的五种替代方案
  18. mysql update用法_mysql update语句的用法详解
  19. 三星电子首次尝鲜“纯EUV极紫外光刻”生产线
  20. 飞利浦43php5292,说说使用感受飞利浦43PFF5292T3质量如何?分析怎么样?爆料真实使用心得...

热门文章

  1. Spark之核心架构
  2. 细说java.util.HashMap
  3. [20181015][模拟赛]
  4. HackerRank python练习——Sherlock and Squares
  5. html对象下边框呈三角形,html5 - CSS-三角形边框无法正确呈现IE8 - 堆栈内存溢出...
  6. 台式计算机用电量是多少,台式计算机的功率是多少?台式计算机多少电量[详细介绍]...
  7. make:Windows安装make
  8. NodeJS使用crypto进行MD5加密
  9. CHB-MIT波士顿儿童医院癫痫EEG脑电数据处理-癫痫发作预测(六)
  10. 骂人的c语言,法语中骂人你就只会Merde?