首页 > 系统相关 >Linux 中断 request_threaded_irq request_irq

Linux 中断 request_threaded_irq request_irq

时间:2022-08-31 19:58:06浏览次数:83  
标签:threaded 中断 irq request 线程 进程 执行

 

https://blog.csdn.net/mcsbary/article/details/103728816

总结:
request_threaded_irq:中断处理线程化,很好解决高频率的中断响应,类似异步处理
request_irq:类似于同步处理事务,适合非高频率中断响应。

 

 

https://zhuanlan.zhihu.com/p/151888181

 

Linux 中断处理分为顶半部(top half)和底半部(bottom half),一般要求在顶半部里处理优先级比较高的事情,处理时间应尽量短,在处理完成后就激活底半部,在底半处部理其余任务。底半部的处理方式主要有soft_irq, tasklet, workqueue三种,它们的使用方式和适用情况各有不同。

soft_irq 用在对执行时间要求比较紧急或者非常重要的场合。 tasklet 和 work queue 在普通的driver里用的较多,主要区别是tasklet是在中断环境中执行,而work queue 则是在进程中执行,因此可以使用sleep()。

Linux 中断的优先级比进程高,一旦中断过来普通进程实时进程通通都要给中断处理程序让路,如果顶半部处理任务较多就会对实时进程造成很大的影响,并且这种影响存在较大的不确定性因此难以准确评估。为了解决这些实时性相关问题,Linux RT_PREEMPT 补丁引入了中断线程化的机制。在新的机制中,中断虽然还会打断实时进程,但中断处理程序所执行的操作仅仅是唤醒中断线程,原本的中断服务程序主体放到一个内核线程中延迟执行,这样中断执行的速度就很快也很确定,实时进程被打断后可以迅速再次运行,而中断服务程序会在实时进程挂起之后被系统调度执行。

Linux 2.6.30里,在ingo molnar的RT tree里存在有一段时间的interrupt thread终于merge到mainline了。此时如果使用request_threaded_irq申请的中断,handler 不是在中断环境里执行,而是在新创建的线程里执行,这样该handler非常像执行workqueue,拥有所有work queue的特性,但是省掉了创建、初始化、调度workqueue的步骤,处理起来非常简单。

让我们看看这个接口:

int request_threaded_irq(
unsigned int irq, 
irq_handler_t handler, 
irq_handler_t thread_fn, 
unsigned long irqflags, 
const char *devname,
void *dev_id)

其中,

irq 是中断号,

handler 是在发生中断时首先要执行的处理程序,非常类似于顶半部,该函数最后会返回 IRQ_WAKE_THREAD 来唤醒中断线程。handler 一般设为NULL,用系统提供的默认处理。

thread_fn 是要在线程里执行的处理程序,非常类似于底半部。

后三个参数基本和request_irq相同。

irqsflags 新增加了一个标志IRQF_ONESHOT,用来声明需要在中断线程执行完后才能打开该中断。对于电平有效的中断类型,如果不设置该标志可能会出现死锁情形:CPU 执行完成顶半部代码后会打开中断,此时如果中断信号电平没有变化(中断源在等待CPU发出reset信号),CPU会立刻重复响应该中断,导致永远没有机会进入线程处理,也就永远不会reset该中断。


下边一个实际例子来说明它的应用。在手机平台中,检测耳机的插入一般是通过耳机插孔中机械变化导致一个baseband gpio的电平的变化,在该gpio中断里进行耳机插入处理。但是耳机插入一般都有个抖动的过程,需要消抖处理。最简单的办法是在中断发生后,延时一段时间(例如200ms),然后再检查GPIO状态是否稳定来确定是否有效插入。如果用老的中断方式,不得不用workqueue的方式,你需要在顶半里激活一个delay 200ms的workqueue,然后在workqueue里检查。如果用线程化的处理方式,则只需要在thread_fn里sleep 200ms,然后再检查即可。

 

中断线程化的反例

有一个项目对实时性要求比较高,于是在linux内核上打了RT_PREEMPT补丁。最终碰到的一个问题是,芯片本身性能不强,CPU资源不足,急需优化。

初步分析

看了下cpu占用率,除了主应用之外,有一个名为irq/38-twi0的进程引起了我们的注意,因为它竟然占据了10%的cpu。

这个irq开头的进程是做什么的呢?原来这是一个被线程化了的中断服务程序,负责处理i2c中断的。这个项目i2c总线上挂载了多个设备,压力是比较大的。

第一个想法是能否减少设备数量或者减低采集频率,但这会影响到应用的算法表现,暂时不考虑。

第二个想法是优化代码,但打开中断服务程序的源码一看,其实现非常简单,基本就只是从硬件寄存器中把接收到的数据取出来而已,看来从这里入手也希望不大。

再仔细想想,这个进程执行的操作这么简单,CPU占用率却这么高,那么主要就是因为其执行的频率过高,每次执行其实都会伴随着进程调度以及上下文切(context switching)换带来的开销,这部分是否可以进行优化呢?

从中断线程化的初衷看,当前这种场景根本就不适用中断线程化。

  1. 这个中断服务程序非常简单,没必要线程化。强行线程化对实时性的改善不大,反而会带来不必要的开销。

2. 这个中断服务程序非常关键,其中采集的数据的实时性也非常重要,不应该被延迟执行。中断切换回实时进程后,实时进程依赖这些数据,还是要等这个进程把数据取出。

解决

解决方式很简单,对于这个具体的中断,取消线程化,让它变回一个朴素的中断。中断线程化的机制虽好,也要分情况来使用,不然反而会造成系统的巨大负担。

代码改动是在request_irq时,传入IRQF_NO_THREAD标志,即可避免这个中断被线程化。

实际做改动还要注意,RT_PREEMPT使用rt_mutex代替传统的禁用抢占的spin_lock,因此如果需要用真正的spin_lock,需要使用raw_spin_lock_t

在这个具体的例子中,中断大概为一万两千次/秒,取消线程化之后,CPU占用率下降了约10%,效果显著。

标签:threaded,中断,irq,request,线程,进程,执行
From: https://www.cnblogs.com/sinferwu/p/16644341.html

相关文章

  • seafile onlyoffice k8s traefik Cross origin requests are only supported for prot
    这个问题我实际上是用答案倒推寻找的原因完整报错:hasbeenblockedbyCORSpolicy:Crossoriginrequestsareonlysupportedforprotocolschemes:http,data,chr......
  • python request post from 提交表单
    前言一个http请求包括三个部分,为别为请求行,请求报头,消息主体,类似以下这样:请求行请求报头消息主体HTTP协议规定post提交的数据必须放在消息主体中,但是协议并没有规定必......
  • 2022-08-30 第二小组 张晟源(javaweb,request,response)
    JavaWebHttpServletRequest//请求  所有和请求相关的操作  当请求来的时候,request就被实例化HttpServletResponse//响应   所有和响应的操作  当请求来......
  • requestAnimationFrame简单用法
    面试题:用js实现一个无限循环的动画。首先想到的是定时器<!doctypehtml><htmllang="en"><head><title>Document</title></head><body><divid="aaa"></div><......
  • PostMan请求Web Api接口提示“Bas Request”错误
    一、如果PostMan请求WebApi接口提示“HTTPError400.Therequesthostnameisinvalid”错误出现上述错误的场景:1.在测试服务器上,项目是直接通过VisualStudio直接启......
  • Django_request学习
    Django_request(1)请求方式这里使用一个接口测试软件postman可以看到里面有非常多的发起请求的方式,最常用的就是GET和POST请求,但是这些方法无法在网页的url里显示在学......
  • 3,python3 windows 安装,及 windows python 环境 requests模块安装
    1,安装python环境1,执行安装包,双击->python-3.10.4-amd64.exe->勾选选自定义安装和勾选添加环境变量  2,勾选安装所有用户和设置安装路径  3,cmd->python,验证Py......
  • setTimeout、setInterval 和 requestAnimationFrame
    与setTimeout和setInterval不同,requestAnimationFrame不需要设置时间间隔,大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘......
  • PowerShell教程 - Web requests(Web请求)
    更新记录转载请注明出处。2022年8月29日发布。2022年8月29日从笔记迁移到博客。Webrequests(Web请求)发起Web请求Abackgroundinwebrequestsisvaluablebefo......
  • python before_request详解
    before_request顾名思义,就是在request请求之前做的事情。它会在每一个请求来的时候,都会先去请求before_request注册的函数。before_request需要注册一个函数,可以不需要参......