`
xitong
  • 浏览: 6188801 次
文章分类
社区版块
存档分类
最新评论

对问题“为什么执行softirq时不能被抢占?”的解答

 
阅读更多

1.首先,在irq_exit中调用do_softirq前已经退掉了preempt_count中的HARDIRQ_MASK,因此softirq此时如果不在preempt_count加上SOFTIRQ_MASK位还是会被抢占的,我们看到softirq是在硬件中断后执行的,因此如果硬件中断是任意上下文的话那么softirq也是任意上下文,我们知道任意上下文下的睡眠或者调度会使得被中断的进程不确定而且对被中断的进程不公平,因此 softirq也不能睡眠,这也是一个约定,但是此时在未进入softirq的处理前却是可以被抢占的,因为硬件中断处理已经完成,软件中断是相对不急的,因此仅在此时它可以被抢占,然而一旦进入do_softirq的话,那么softirq逻辑就又开始在这个被中断的进程的上下文大做文章了,因此不能被抢占,也不能调度,原因和上述硬件中断一样。

2.至于SOFTIRQ_MASK位,它是防止软中断被重入而设置的,看看do_softirq中有个local_bh_disable,就是它递增了preempt_count的SOFTIRQ_MASK位,使得在退出此次softirq处理前不能再进入,另外它也保证了在执行softirq的时候不被抢占。

3.如果就到我上面说的为止,一切显得很合理,但是我们知道softirq是不急的动作,如果没完没了的执行它的话,那么对被中断的进程仍然不公平,毕竟softirq一直在此进程上下文执行着,于是你说的softirqd就出来了,内核专门开了一个softirq服务线程来处理软中断,我们看到在do_softirq(void)中:

int max_restart = MAX_SOFTIRQ_RESTART; //最大的softirq执行次数

if (pending && --max_restart) //如果没有到最大次数,继续执行

goto restart;

...

if (pending) //如果在执行上次softirq途中又pending了新的softirq请求并且已经不能再继续执行softirq了,那么唤醒softirqd吧。

wakeup_softirqd();

就是这样的,上面的if(pending)判断以及唤醒softirqd的逻辑在于不能给鼻子上脸,给了softirq MAX_SOFTIRQ_RESTART的执行机会就够意思了,如果还有请求,抱歉,本次进程还忙着呢,不能再帮你了,你还是去请求softirqd吧,人家是专业的执行softirq的。做事不能太霸道了,softirq在硬件中断完成后获得执行机会,而且还递增了被中断进程的 preempt_count导致不能抢占,这不但给当前进程增加不确定性,还导致了别的就绪进程无法抢占当前被中断的进程,这样十分不好。

4.linux 巧妙的处理了中断和性能的关系,你不是说中断中不能睡眠并且不能执行太久吗?那么好我引入了软中断softirq,如果softirq中能睡眠并且能长期占用cpu那还不是和没有引入一样吗?那么好,linux又引入了softirqd,干脆给它一个进程上下文。

5.注意,softirq的执行函数不能主动睡眠,但是在softirqd中却是可以被抢占的,睡眠和抢占是两个概念,前者主动后者被动。而且不能睡眠是在softirq的处理函数中,可以抢占是在softirq外,在执行过程中还是不能抢占的。

aha,说了这么多有点罗嗦了,总结一下:

softirq不能被抢占是因为它有可能在任意进程上下文执行,所谓抢占必须在确定上下文中执行,不能睡眠也是因为它可能在任意上下文执行。至于softirqd只是为了不使softirq长期占用cpu而提出的一个手段而已,应该这么认为:以 softirq为主,以ksoftirqd为辅。

如此给你带来的问题也同样困扰了linux内核的开发者们,于是工作队列就出来了...下文太精彩,闪!

接下来又回邮件问:

>> 因此仅在此时它可以被抢占,然而一旦进入do_softirq的话,那么softirq逻辑就又开始在这个被中断的进程的上下文大做文章了,因此不能被抢占,也不能调度,原因和上述硬件中断一样。
这里在do_softirq之前都可以被抢占了..在进入do_softirq后的话,更加可以的啊. 为什么进入do_softirq时要禁止呢?
>> 5.注意,softirq的执行函数不能主动睡眠,但是在softirqd中却是可以被抢占的,睡眠和抢占是两个概念,前者主动后者被动。而且不能睡眠是在softirq的处理函数中,可以抢占是在softirq外,在执行过程中还是不能抢占的。
用softirqd内核线程处理softirq时,完全是进程的上下文了. 为什么还不能主动睡眠,以及在执行过程中就抢占呢?

我的回答:

这里在do_softirq之前都可以被抢占了..在进入do_softirq后的话,更加可以的啊. 为什么进入do_softirq时要禁止呢?
答: 进入do_softirq之前是内核的控制机制,有确定的行为,但是一旦进入你自己的softirq处理函数,那里面怎么执行就只有你自己知道了,比如你 抢了一把锁,然后做事,内核此时根本不知道你做了些什么,为了不使事情混乱不可收拾,比如你在占有锁时被抢占了就会有问题,于是内核约定不允许抢占 softirq。
用softirqd内核线程处理softirq时,完全是进程的上下文了. 为什么还不能主动睡眠,以及在执行过程中就抢占呢?
答:是进程上下文了,但是softirq并不是都在拥有进程上下文的softirqd中执行,更多的要在硬件中断后紧接着执行,那时它就是任意上下文了,引入softirqd的目的仅仅是不想让softirq过多的占据任意上下文,这其实是最大约束原则。
其实不要把softirq想得太神秘,它其实和硬件中断机制在代码上是统一的。

然后又问:

谢谢...
第二问题是基本明白了..也猜到了.呵呵.
第一个问题,在加锁时,spin_lock()其实会禁止抢占的.
我不想深究了.就理解成内核的约定了.为了尽快的返回被中断的进程.

我的回答:

呵呵,深究起来确实会没有完的,比如加锁就一定禁用抢占吗,要加的不是自旋锁呢?呵呵,不说了。其实理解linux的最好方法就是调试而不是深入 代码细节,我以前初涉内核的时候就总进入一些死胡同,比如在一个地方spin_lock,然后我就为找不到unspin_lock而茶饭不思,后来才发现 是别的文件里面unspin_lock了,呵呵。在调试内核前一定要先了解内核的架构,其实linux内核设计得相当好的。我在张江,有时间一定交流交流,呵呵...

分享到:
评论

相关推荐

    Linux的内核软中断(softirq)执行分析.zip_leavinghzf_linux_theory989

    linux软中断,分析内核中中断的流程以及怎样修改这部分内容,经过调试可以使用

    Linux软中断softirq机制流程图

    这个流程图粗略地描述了softirq, tasklet, bottomhalt, task queue这些对象之间的联系及调用流程。 主要依据:《Linux内核的Softirq机制》和《软中断概况》 图中可能存在错误,希望您的指正!

    Linux中断(interrupt)子系统之一:软件中断(softIRQ).docx

    Linux中断(interrupt)子系统之一:软件中断(softIRQ).docx

    locking-selftest-spin-softirq.rar_decide

    provide all the vectors, so that EQ creation response can decide which one to use.

    locking-selftest-spin-softirq.rar_Extras

    Asus Eee PC extras for Linux v2.13.6.

    linux时间子系统

    对linux时间子系统研究,整理出的文档 可以作为手册进行查阅

    简单谈谈Linux内核定时器

    软件意义上的定时器最终依赖硬件定时器来实现, 内核在时钟中断发生后检测各定时器是否到期 , 到期后的定时器处理函数将作为软中断在底半部执行 。实质上,时钟中断处理程序会 换起TIMER_SOFTIRQ软中断 ,运行当前...

    trace-irqoff:中断关闭或软中断关闭延迟跟踪器

    在实际问题中,业务经常会遇到网络延迟高问题,这种问题分析下来。基本是如下几种可能原因: 中断关闭时间太长 softirq 关闭时间太长 以上是我们根据经验猜测可能出现的原因,实际问题中,我迫切的需要确定是否以上...

    linux 内核同步机制

    本文档介绍在linux内核中两个不同进程或者过程访问和使用同一共享资源时,处理顺序的随机性,可能出现访问错误。结果依赖于多个任务的相对执行顺序(竟态条件)。其中处理竟态条件的同步机制在不同内核过程中处理的...

    win-collector:夜莺的Windows代理

    以下仅列出差异部分cpumetriclinuxwindowscpu.softirq支持不支持cpu.steal支持不支持cpu.iowait支持不支持cpu.nice支持不支持cpu.guest支持不支持cpu.core.softirq支持不支持cpu.core.steal支持不支持cpu.core.io...

    linux操作系统内核技术-uestc课件

     6中断处理程序被分解为top half和bottom half的原因,介绍linux的softirq,tasklet,ksoftirqd和work queue,分析进程与top half,bottom half的竞争情形和同步。(4小时)  7掌握内核同步原理和方法:原子操作,...

    tibeecompare:用于比较执行跟踪的应用程序

    西藏比较 用于比较执行跟踪的应用程序。先决条件构建系统的SCons建造 ./bootstrap.sh./configuremake必需的事件此工具需要具有以下事件的跟踪: 标准 LTTng 事件: sched_ttwu 调度开关sched_process_fork sched_...

    性能优化–CPU使用率

    steal 当系统运行在虚拟机中时,被其他CPU占用的时间。 gust 通过虚拟化,运行其他操作系统的时间。 gust_nice 以低优先级运行虚拟化的时候。 CPU使用率 = 1- 空闲时间/CPU总时间 用户态占用过多的CPU,应着重排查...

    Linux2.6内核标准教程(共计8-- 第1个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第6个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第3个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第4个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第2个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第7个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

    Linux2.6内核标准教程(共计8--第5个)

    1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 ...

Global site tag (gtag.js) - Google Analytics