最近在一次稳定性测试中,发现Kernel Log中出现了如下的Warring,如下:

WARNING: CPU: 4 PID: 2956 at /space/builder/repo/sprdroid6.0_trunk_k318_dev/kernel/kernel/irq/manage.c:444 __enable_irq+0x50/0x94()
Unbalanced enable for IRQ 227Call trace:
c4 [<ffffffc00008b480>] dump_backtrace+0x0/0x164
c4 [<ffffffc00008b600>] show_stack+0x1c/0x28
c4 [<ffffffc0009ceefc>] dump_stack+0x74/0xb8
c4 [<ffffffc0000bb340>] warn_slowpath_common+0x98/0xc0
c4 [<ffffffc0000bb3dc>] warn_slowpath_fmt+0x74/0x88
c4 [<ffffffc00010eb50>] __enable_irq+0x4c/0x94
c4 [<ffffffc00010ebd8>] enable_irq+0x40/0x80
c4 [<ffffffc000630a38>] spidev_ioctl+0x6e4/0xbc0
c4 [<ffffffc0002016f0>] do_vfs_ioctl+0x374/0x5b8
c4 [<ffffffc0002019c0>] SyS_ioctl+0x8c/0xa4
c4 ---[ end trace 3e8cbdaab32a5c30 ]---

根据Kernel log的提示,在内核源码中找到出错的地方:

<kernel/irq/manage.c>
--------------------------------------------------------
void __enable_irq(struct irq_desc *desc, unsigned int irq)
{switch (desc->depth) {case 0:err_out:WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);break;case 1: {if (desc->istate & IRQS_SUSPENDED)goto err_out;/* Prevent probing on this irq: */irq_settings_set_noprobe(desc);irq_enable(desc);check_irq_resend(desc, irq);/* fall-through */}default:desc->depth--;}
}

可以看到当desc->depth等于0的时候,就会出现上述的log。

而出现此问题的原因是什么? 或者是谁导致出现了这种情况?

通过栈调用关系可以看出,应用程序通过ioctl命令去操作底层的指纹识别的过程出现的。
SyS_ioct->do_vfs_ioctl->spidev_ioctl->enable_irq->__enable_irq

从调用关系看,最后调用__enable_irq的时候desc->depth=0,出现了“Unbalanced enable for IRQ”, 而根据字面意思是“使能不匹配的IRQ”。

根据提示猜想,是不是enable_irq需要与disable_irq成对的匹配调用。

基于此猜想,可以通过disable_irq与enable_irq的源代码验证猜想。


先看disable_irq的代码:

<kernel/irq/manage.c>
---------------------------------------------------------------------
void __disable_irq(struct irq_desc *desc, unsigned int irq)
{if (!desc->depth++)irq_disable(desc);
}

从代码可以看出disable_irq的时候,对desc->depth做++操作。

<kernel/irq/manage.c>
---------------------------------------------------------------------
void __enable_irq(struct irq_desc *desc, unsigned int irq)
{switch (desc->depth) {case 0:err_out:WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);break;case 1: {if (desc->istate & IRQS_SUSPENDED)goto err_out;/* Prevent probing on this irq: */irq_settings_set_noprobe(desc);irq_enable(desc);check_irq_resend(desc, irq);/* fall-through */}default:desc->depth--;}
}

而__enable_irq代码是对desc->depth做–操作了。

根据一个做++操作,一个做–操作。可以得出disable_irq与enable_irq需要成对的使用。

而出现上述的原因就是在没有调用disable_irq的前提下,直接调用enable_irq,那时候desc->depth等于0,这时候enable_irq就会出现Warring, 也就是说这次的enable_irq没有起作用的。

假设驱动中先disable_irq,这时候desc->depth++了, desc->depth就等于1, 而这时候再次enable_irq就会走进case 1的分支中去。 然后desc->depth–了,最后desc->depth等于0

所以根据分析,出现上述的原因就是enable_irq与disable_irq在驱动中没有匹配使用导致的。

disable_irq/enable_irq使用不匹配相关推荐

  1. joyfire linux笔记 感谢原作者

    内核分析 目 录 index.html 更新记录 发布 申明 GPL GFDL 系统管理 程序编写 内核分析 启动 启动步骤 setup.s head.s bootsect.s compressed/ ...

  2. 两款带有WiFI的MicroPython模块:ESP32,ESP8266

    文章目录 ▌01 两款WiFi开发板 1.ESP32开发板 (1)焊接模块的接口插针 (2)加电测试 3.刷新ESP32固件 2.ESP8266开发板 (1)接入微机USB (2)连接Thonny ▌ ...

  3. swi 指令能用在C语言吗,内嵌汇编指令的应用举例

    下面是在C语言程序中嵌入式汇编程序的例子.通过这几个例子,可帮助用户更好地理解内嵌汇编的特点及用法. (1)  字符串复制 本例主要介绍如何使用指令BL调用子程序. 注意,在内嵌的SWI和BL指令中, ...

  4. micropythonesp8266刷固件_MicroPython入坑记2:ESP8266/ESP32刷固件

    先来个刷写过程: 其实各种刷ESP8266/ESP32的软件都可以搞(比如刷NodeMCU的软件),不过我这还是出问题了:刷完后无限输出乱码.然后参照Micropython官方的教程,用esptool ...

  5. MSI Howto中文版

    1. 什么是MSI MSI全称Message Signaled Interrupt. 当设备向一个特殊地址写入时,会向CPU产生一个中断,即也MSI中断. MSI能力最初在PCI 2.2里定义,在PC ...

  6. MSI及MSIX详解

    在PCI总线中,所有需要提交中断请求的设备,必须能够通过INTx引脚提交中断请求,而MSI机制是一个可选机制.而在PCIe总线中,PCIe设备必须支持MSI或者MSI-X中断请求机制,而可以不支持IN ...

  7. 设备驱动--中断开关执行的匹配

    近期项目生产过程中出现概率为万分之几异常,此中异常实在是折磨人啊!连续几天的熬夜复现分析,总算是找到异常原因:为加强自己对问题的认知特编辑此文对问题做进一步梳理. 1 问题现象 开机偶见TP失效: 2 ...

  8. 中断API之enable_irq

    void enable_irq(unsigned int irq) 用于使能一个irq. void disable_irq(unsigned int irq)则用于禁止一个irq其使用的例程如下: s ...

  9. local_irq_disable和disable_irq的区别

    local_irq_disable: local_irq_disable的功能是屏蔽当前CPU上的所有中断,通过操作arm核心中的寄存器来屏蔽到达CPU上的中断,此时中断控制器中所有送往该CPU上的中 ...

  10. re2正则表达式匹配引擎的c接口版本cre2的中文使用手册

    前言 re2 官方地址: https://github.com/google/re2 cre2 官方地址: https://github.com/marcomaggi/cre2 1 基本类型定义 不透 ...

最新文章

  1. delphi 中怎么知道某一个月有多少天
  2. vue引用公用的头部和尾部文件。
  3. Intel Realsense D435 在C/C++中表示的frame_set就是python中的frames?【wait_for_frames()】
  4. ViewPager 在 ScrollView 中显示不全的解决方法
  5. JZOJ 5907. 【NOIP2018模拟10.16】轻功(qinggong)
  6. 关于 SAP CloudFoundry 应用的 Resilience
  7. 多个圆点,鼠标选取两个,求两个点的距离,用于计算像素尺寸(halcon实现)
  8. ssm异常捕获和处理
  9. window安装gcc编译器
  10. Spring Cloud —— 消息队列与 RocketMQ
  11. 在html中写三角,css3怎么写三角形?
  12. java如何实现线程_java中线程的三种实现方式
  13. b树删除节点每次只能删一个吗_【面试索引】BTree、B+Tree、红黑树、B*Tree数据结构...
  14. 中国银行计算机笔试题库,中国银行计算机笔试题
  15. 南京审计学院计算机专业老师,南京审计学院如此对待一位好老师!!(转载)
  16. 原理 CDN加速原理
  17. HTML期末学生作业~HTML+CSS+JavaScript仿猫眼电影在线网站
  18. dax-自定义周做同比和环比
  19. Flutter之路由与导航
  20. 【附源码】计算机毕业设计java在线答题系统设计与实现

热门文章

  1. 20172327 2017-2018-2 《程序设计与数据结构》第九周学习总结
  2. 实现自动登录:Filter 实现思路和方式
  3. React中state与props介绍与比较
  4. 修改系统文件内容的经典错误总结
  5. Java IO源码目录
  6. 【FPGA-F3】阿里云FAAS平台,极大简化FPGA开发部署流程 1
  7. 仿微信选项卡主页面创建
  8. 《黑客秘笈——渗透测试实用指南(第2版)》—第1章1.6学习
  9. 深入Jetty源码之HttpGenerator
  10. iOS开发UI篇—Button基础