Linux内核中断延时与解决

转载 2011年01月17日 09:26:00
中断潜伏期(Interrupt Latency)或者说中断延迟,这个指从中断产生到CPU开始响应中断的时间段,也就是图中从t2至t3的时间段。中断潜伏期是由于内核在进入临界区前关闭CPU的中断响应所引起的,在这个时间段内,虽然外部设备使CPU的中断请求线有效,但CPU并不立刻响应中断,而是继续执行临界区的内核代码,直至退出临界区、使能中断请求,才开始进行中断的响应。当然,还需要注意的一点是,中断潜伏期实际上包含了硬件所产生的中断延迟时间,我们一般所研究的是如何最大限度的减少软件所造成的延迟时间,所以,如果没有特别说明,我们是不考虑硬件所产生的延迟(但实际上,在工程应用中,当经过软件的优化还不能满足系统实时性的要求时,唯一的办法就只有提高硬件的处理速度了)。


文章中提出的解决方法:

1 软件中断模拟
由于Linux存在许多关中断的区域,这就会导致中断潜伏期过长,当中断频繁时,会有丢失外部中断的可能性,这是实时系统所不能容忍的。解决这个问题最直接的办法,就是不关中断;这里所谓的不关中断,是对整个系统来说不关中断,但对于Linux本身来说,或者说从Linux的角度来看的话,Linux本身的行为和实际关中断的时候时一样的。这种方法可以用软件中断模式技术来实现。
软件中断模式技术中所指的软件中断,是对于Linux来说的,也就是说,Linux并不直接控制硬件中断,当Linux需要关中断时,它实际上的操作只是将一个软件标识置位,表示从此时开始Linux的执行不想受到中断的干扰,当Linux开中断的时候,实际上的操作是将这个软件标识清除。而实际硬件中断由处于硬件和Linux之间的一个软件层来管理,这个软件层的主要任务就是接收硬件中断,并根据需要调度Linux的中断服务程序;当Linux关中断时(并没有实际禁止硬件中断),软件中断模拟层继续接收硬件中断,并将中断信息记录在日志中,当Linux开中断时,模拟层就根据中断日志调用Linux的中断服务程序;
通过软件中断模拟技术,可以有效的防止外部中断的丢失,但是,我们应该看到,在Linux关中断期间,外部中断还是得不到响应(也就是Linux本身的相应中断服务程序没有执行),所以,这种技术并没有缩短系统的中断潜伏期,也就没有提高系统的中断响应时间,还是无法满足实时任务对快速的中断响应时间的要求。
2 增加内核抢占点
从对Linux的任务响应模型的分析可以看出,调度潜伏期对任务响应时间的影响非常大,在任务响应时间中占了很大一部分(很多文献关于这方面的测试结果都可以证明这一点);所以,Linux实时性优化的一个重要目标就是缩短调度潜伏期的时间。那么,影响Linux调度潜伏期的因素有哪些呢?调度潜伏期的长短与Linux在内核态的一次运行时间长短有关(从进入内核态执行系统服务到退出内核态的时间段),为了减少调度潜伏期的时间,就必须减少Linux连续运行在内核态的时间;最直观的方法就是在执行时间长的内核代码中增加抢占点(也就是增加部分代码主动请求进行调度),将执行时间长的内核代码划分成若干段执行时间段的代码,在各个代码段之间可以进行进程调度,从而达到缩短调度潜伏期的目的。
已经有资料显示,增加内核抢占点是最有效的缩短调度潜伏期的方法;但是,尽管这种方法的原理很简单,实现起来却是相当的繁琐和费时。一方面,要找出内核中哪些部分的执行时间较长本身就不是一件容易的事,而且同样的代码在不同的系统状态下执行时间的长短也不一样,这就需要进行动态的分析找出内核中耗时的代码段;另一方面,随着内核的不断发展,这种方法在不同版本内核之间的移植性也比较差,而且还要对新增加的内核代码进行分析。
3 利用SMP技术实现可抢占内核
由于Linux内核原来的设计是不可抢占的,也就是说,内核代码大部分没有考虑函数的重入(一个系统服务并发的被两个进程执行)和数据的互斥访问的问题,在这种情况下要实现内核的可抢占相当困难。但是,随着后来Linux对SMP(对称多处理器)支持的成熟,出现了利用SMP技术实现可抢占内核的方法。实现可抢占内核,它的目标和增加内核抢占点类似,实际上也是为了缩短调度潜伏期。
要实现可抢占内核,最主要的工作就是要找出哪些代码可能被进程并发调用,并对相关的临界区进行保护,保持数据的一致性。而对SMP的支持,考虑的也是类似的问题,因为在多处理器系统中可以有多个进程同时运行并访问同样的临界资源。所以,可以利用Linux内核对SMP的支持,实现内核的可抢占。在可抢占内核中,当有高优先级的进程可以运行时,系统会立刻进行进程调度;当然,在某些情况下内核抢占也是不允许的,这主要包括以下几种情形:
1)当系统正在处理中断服务程序的时候,不允许进行抢占;中断服务程序是与进程无关的,异步的,它并不属于某个进程,没有进程属性(也就是说不存在进程上下文环境),所以并不满足抢占的条件(没有被抢占的对象)。
2)当系统正在处理下半部中断(Bottom Half)的时候,不允许进行抢占;这里的原因和第一种情况一样。
3)当系统运行的时候持有自旋锁、写锁或读锁的时候,不允许进行抢占;这些锁用于支持SMP,在SMP系统中,这些锁用来保护临界区,控制不同处理器上运行进程对临界区的互斥访问,也就是说,当内核持有这些锁的时候,它不希望被其它进程所抢占。
4)当内核在运行进程调度程序时,不允许进行抢占;这个是显而易见的,运行进程调度程序实际上本身就是抢占的一个过程,而且此时也没有任何进程的上下文环境。
所以,利用SMP技术实现可抢占内核要完成的主要工作包括修改中断返回代码、修改SMP的自旋锁机制、修改调度程序。
根据资料显示,虽然利用SMP技术实现可抢占内核对调度潜伏期的改善不如增加内核抢占点方法,但由于它易于维护、可移植性好,现在已经被加入了标准的Linux2.6版本。
4 实现细粒度定时器
Linux本身的定时器精度比较粗糙,一般为100HZ,也就是说,定时器的中断周期为10ms;但在实时系统中,对定时器的精度有更高的要求,例如,实时系统中的某个实时任务的运行周期必须小于2ms,在这种情况下,普通的Linux是无法满足要求的,因为当定时器频率为100HZ的时候,定时器中断每 10ms才运行一次,才进行一次进程调度,所有周期任务的运行周期至少为10ms。
实现细粒度定时器的一种方法就是提高定时器的频率,这种方法最直接也最容易实现,但由于定时器的频率提高了,定时器的中断服务程序的运行频率也提高了,系统花在任务处理上的时间就会减少,从而降低系统的性能。所以,这种方法有一定的局限性,必须找到一个降低系统性能和提高时钟精度的折衷点。
实现细粒度定时器的另一种方法就是使定时器运行在单触发模式(one-shot mode)。这与周期模式(periodic mode)运行的定时器不同,周期模式运行的定时器,只要对它进行一次初始化操作,以后定时器就会周期的产生中断,不再需要额外的对定时器进行编程操作;而当定时器运行于单触发模式下时,每当定时器产生一次中断后就不再运行,系统再根据当前任务对时间的要求计算出定时器下一次应该产生中断的时间间隔,然后再对定时器进行编程,使它能在系统要求的将来某一时刻产生中断。在单触发模式下,定时器的定时精度能达到微秒级。不过需要注意的是,由于每次中断后都要计算下一次中断的时间,而且还要对定时器进行编程,这两个操作会降低系统的性能。
具体在实时系统中使用哪种定时器方案,一般需要根据具体的应用而定,并不存在一种适用于所有实时应用的定时器方案。
5 优化进程调度
从前述对Linux任务响应模型的分析可知,任务响应时间的长短还与进程调度时间的长短有关,当减少进程调度时间时,也可以有效的加快任务的响应速度。目前,对进程调度的优化主要使用将实时进程和普通进程分开来调度的策略,这可以通过分级调度来实现,通过这样的方法,可以使实时进程的调度时间缩短,从而提高实时任务的响应速度。
6 实时双内核机制
前述的几种Linux内核的实时优化机制虽然可以明显的提高任务的响应速度,增强Linux的实时性,但都无法满足硬实时的要求。由于Linux内核本身的实现方式和复杂度,使得Linux本身始终不能适用于硬实时应用;但随着Linux的应用越来越广泛,对Linux满足硬实时应用的要求越来越强烈;在这种环境下,实时双内核机制开创了Linux支持硬实时应用的先河。在这种技术下,存在一个支持硬实时的微内核,它与Linux内核共同运行于硬件平台上,实时内核的优先级高于Linux内核,它负责处理系统的实时任务,而Linux则负责处理非实时任务,只有当实时内核不再有实时任务需要处理的时候,Linux内核才能得到运行的机会。
实时双内核机制把一个系统看作由两部分组成:实时部分和非实时部分,实时部分由实时微内核处理,非实时部分由Linux处理,它们之间可以通过管道或共享内存的方式进行通信。这种机制虽然在建立实时任务的时候有一套不同于Linux本身的编程接口,但由于它可以与Linux进行通信,从而可以将后续的大量处理工作交给Linux来完成。这样,既保证了实时任务的硬实时要求,也保留了Linux本身的应用编程环境,可以充分的利用Linux下丰富的应用。

 

 原文地址 http://linux.chinaunix.net/bbs/thread-1038059-2-1.html

相关文章推荐

linux ------ 中断处理及延时操作

linux 系统的中断分上半部与下半部2部分,上半部是硬件中断,会关闭中断,一般处理时间较短,处于中断上下文。下半部有Tasklet与工作队列2种,是中断处理的延时操作,如果中断需要处理较复杂的事务,...

中断延迟是什么?

经常听的“中断延迟”,可是中断延迟究竟是什么? (Interrupt Latency) 中断延迟 是指从硬件中断发生到开始执行中断处理程序第一条指令之间的这段时间。 也就是: 计算机接收到中断信...

Linux如何及时响应外部中断

FPGA每隔100us给运行linux的ARM一个中断,要求在20us

linux 中断响应时间

一直听说linux不是一个实时的操作系统,今天有空写了个小程序测试了一下怎么个不实时法。 经过测试发现,linux从中断产生后到跳转到驱动程序大概需要3ms的时间。本人测试的时间在2.8ms~3ms...
  • Canbus
  • Canbus
  • 2012年06月01日 15:39
  • 3210

linux中断响应和处理过程分析

linux中断响应和处理过程: 首先中断属于异常的一种。异常,就是可以打断CPU正常运行流程的一些事情,比如说外部中断,未定义的指定,试图修改只读数据,执行SWI指定(software interr...

linux中断--中断嵌套&中断请求丢失

关于中断嵌套: 在linux内核里,如果驱动在申请注册中断的时候没有特别的指定,do_irq在做中断响应的时候,是开启中断的,如果在驱动的中断处理函数正在执行的过程中,出现同一设备的中断或者不同设备...

六轴传感器MPU6050

1.六轴与九轴的区别 六轴包括:三轴加速度计、三轴陀螺仪 九轴包括:三轴加速度计、三轴陀螺仪、三轴磁强计 2.MPU6050简单介绍 MPU6050 是 InvenSense 公司推出的全球首款整合性...
  • black_yu
  • black_yu
  • 2016年06月20日 23:06
  • 10141

linux内核时钟机制及延时

时钟时间维护和利用是操作系统的一个基础任务。操作系统中的时间相关的服务包括: 时间维护时钟同步time-of-day的表示下一个事件的调度处理器以及内核定时器进程统计进程度量 linux最初的实...

linux内核延时

1、#include void do_gettimeofday(struct timeval *tv) {  unsigned long flags;  unsigned long usec...

Linux内核延时和时间测量函数

linux内核提供3个函数分别进行纳秒,微妙和毫秒延时: void ndelay(unsigned long nsecs); void udelay(unsigned long usecs);...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核中断延时与解决
举报原因:
原因补充:

(最多只允许输入30个字)