背景

有一个项目对实时性要求比较高,于是在linux内核上打了RT_PREEMPT补丁。

最终碰到的一个问题是,芯片本身性能不强,CPU资源不足,急需优化。

初步分析

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

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

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

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

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

中断线程化回顾

让我们来回顾下中断线程化的知识。

在Linux上,中断的优先级比进程高,一旦中断过来普通进程实时进程通通都要让路,让CPU先运行对应的中断处理程序,这就会对实时性造成很大的影响。

为了解决这个由中断带来的实时性问题,或者说由不确定运行时长的中断服务程序带来的实时性问题,RT_PREEMPT补丁引入了中断线程化的机制。

中断线程化之后,中断来了虽然还是会打断实时进程,但所执行的操作只是唤醒中断线程,原本的中断服务程序被放到了一个内核线程中,延迟执行。

这样中断执行的速度就很快也很有确定性,实时进程被打断后可以迅速再次运行,至于中断服务程序,就在优先满足实时进程的情况下,再被调度执行。

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

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

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

解决

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

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

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

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

本文地址:https://www.cnblogs.com/zqb-all/p/12229990.html

记一个实时Linux的中断线程化问题的更多相关文章

  1. linux中断线程化分析【转】

    转自:http://blog.csdn.net/qq405180763/article/details/24120895 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在为3.8版本的Li ...

  2. Linux 内核中断内幕

    转自:http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/index.html#resources Linux 内核中断内幕 ...

  3. Linux 内核中断内幕【转】

    转自:http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/ 本文对中断系统进行了全面的分析与探讨,主要包括中断控制器.中断分类 ...

  4. Linux kernel中断子系统之(五):驱动申请中断API【转】

    转自:http://www.wowotech.net/linux_kenrel/request_threaded_irq.html 一.前言 本文主要的议题是作为一个普通的驱动工程师,在撰写自己负责的 ...

  5. 转:一个跨WINDOWS LINUX平台的线程类

     来源:http://blog.csdn.net/dengxu11/article/details/7232681 继Windows下实现一个CThread封装类之后,这里我再实现一个跨WINDOWS ...

  6. Linux多线程编程的时候怎么查看一个进程中的某个线程是否存活

    pthread_kill: 别被名字吓到,pthread_kill可不是kill,而是向线程发送signal.还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sig ...

  7. 基于Xenomai的实时Linux分析与研究

    转自:http://blog.csdn.net/cyberlabs/article/details/6967192 引 言 随着嵌入式设备的快速发展,嵌入式设备的功能和灵活性要求越来越高,很多嵌入式设 ...

  8. Linux查看进程线程个数

    1.根据进程号进行查询: # pstree -p 进程号 # top -Hp 进程号 2.根据进程名字进行查询: # pstree -p `ps -e | grep server | awk '{pr ...

  9. Linux中-POSIX 线程详解

    一种支持内存共享的简捷工具   摘自https://www.ibm.com/developerworks/cn/linux/thread/posix_thread1/ 线程是有趣的 了解如何正确运用线 ...

随机推荐

  1. Linux学习笔记(一):什么是挂载?mount的用处在哪?

    关于挂载的作用一直不是很清楚,今天在阅读教材时看见了mount这个命令,发现它的用处很隐晦但非常强大.奈何教材说的不明朗,因此在网上整合了一些优秀的解释,看完之后豁然开朗. 1.提一句Windows下 ...

  2. Winform PPT切换图片效果

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. Faster Rcnn训练自己的数据集过程大白话记录

    声明:每人都有自己的理解,动手实践才能对细节更加理解! 一.算法理解 此处省略一万字.................. 二.训练及源码理解 首先配置: 在./lib/utils文件下....运行 p ...

  4. 奇葩的Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

    启动springboot的时候莫名其妙出现这个错误,我properties里面也没配置数据源啥的,但就是出现这个错误 解决方法: 在启动类上加@SpringBootApplication(exclud ...

  5. vue学习--组件之间的传值方式

    1.概述 vue由多个组件构成页面,在不同的组件中有不同的联系,组件之间的传值是十分有必要的 2.父子组件之间传值 --props和$emit 父传子:通过props 方法:子组件:props:['m ...

  6. hadoop搭建

    一.前期准备 1.1 静态ip,请查看虚拟机安装不放呢 1.2 hostname 以及 hosts文件修改 cat /etc/hostname 不同的机器设置不同的名字 cat /etc/hosts ...

  7. 带限制的广搜 codeforces

    You are playing some computer game. One of its levels puts you in a maze consisting of n lines, each ...

  8. 树上对抗搜索 - 树形dp

    Alice and Bob are going on a trip. Alice is a lazy girl who wants to minimize the total travelling d ...

  9. 深入理解es6中的Promise

    https://www.jianshu.com/p/9e4af5b77253 https://zhuanlan.zhihu.com/p/30797777 https://segmentfault.co ...

  10. 150行代码打造.net core生产力工具,你值得拥有

    你是否在初学 .net core时,被依赖注入所折磨? 你是否在开发过程中,为了注入依赖而不停的在Startup中增加注入代码,而感到麻烦? 你是否考虑过或寻找过能轻松实现自动注入的组件? 如果有,那 ...