为什么中断不能睡眠

【论文精度】生成式预训练模型——BART(Bidirectional and Auto-Regressive Transformers) ​ BART是一个预训练的seq2seq的去噪自编码(denoising autoencoder)模型,BART以下方式进行训练①用任意的噪声函数(noising function)去破坏文本;②学习一个模型来重建原始文本。它使用一个标准的基于transformer的神经机器翻译架构,可以看作是BERT(双向编码器)、GPT(left-to-right解码器)以及其他预训练方案的推广。 阅读详情

这个问题有很多人问过,我看了下Linux得内核代码,原因如下:(当然我不能保证一定对,如果有牛人理解得更好,欢迎指正)

1、 中断处理的时候,不应该发生进程切换,因为在中断context中,唯一能打断当前中断handler的只有更高优先级的中断,它不会被进程打断,如果在 中断context中休眠,则没有办法唤醒它,因为所有的wake_up_xxx都是针对某个进程而言的,而在中断context中,没有进程的概念,没 有一个task_struct(这点对于softirq和tasklet一样),因此真的休眠了,比如调用了会导致block的例程,内核几乎肯定会死。

2、schedule()在切换进程时,保存当前的进程上下文(CPU寄存器的值、进程的状态以及堆栈中的内容),以便以后恢复此进程运行。中断发生后,内核会先保存当前被中断的进程上下文(在调用中断处理程序后恢复);

但在中断处理程序里,CPU寄存器的值肯定已经变化了吧(最重要的程序计数器PC、堆栈SP等),如果此时因为睡眠或阻塞操作调用了schedule(),则保存的进程上下文就不是当前的进程context了.所以不可以在中断处理程序中调用schedule()。

3、2.4内核中schedule()函数本身在进来的时候判断是否处于中断上下文:

if(unlikely(in_interrupt()))

BUG();

因此,强行调用schedule()的结果就是内核BUG,但我看2.6.18的内核schedule()的实现却没有这句,改掉了。

4、中断handler会使用被中断的进程内核堆栈,但不会对它有任何影响,因为handler使用完后会完全清除它使用的那部分堆栈,恢复被中断前的原貌。

5、处于中断context时候,内核是不可抢占的。因此,如果休眠,则内核一定挂起。

-------------------------------------------------------

 

原帖地址:http://bbs.chinaunix.net/thread-2115820-1-1.html

 

这里引用个人认为比较OK的解析:

 

呵呵,我最喜欢这种讨论了。先来献丑了,说说我的看法。
先把中断处理流程给出来

 

  1. 1.进入中断处理程序--->2.保存关键上下文---->3.开中断(sti指令)--->4.进入中断处理程序的 handler--->5.关中断(cli指令)---->6.写EOI寄存器(表示中断处理完成)---->7.开中断。
复制代码


硬中断:
对应于上图的1、2、3步骤,在这几个步骤中,所有中断是被屏蔽的,如果在这个时候睡眠了,操作系统不会收到任何中断(包括时钟中断),系统就基本处于瘫痪状态(例如调度器依赖的时钟节拍没有等等……)

软中断:
对应上图的4(当然,准确的说应该是4步骤的后面一点,先把话说保险点,免得思一克又开始较真 )。这个时候不能睡眠的关键是因为上下文。
大家知道操作系统以进程调度为单位,进程的运行在进程的上下文中,以进程描述符作为管理的数据结构。进程可以睡眠的原因是操作系统可以切换不同进程的上下文,进行调度操作,这些操作都以进程描述符为支持。
中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到保存),其次,没有人来唤醒它,因为它不是操作系统的调度单位。
此外,中断的发生是非常非常频繁的,在一个中断睡眠期间,其它中断发生并睡眠了,那很容易就造成中断栈溢出导致系统崩溃。

如 果上述条件满足了(也就是有中断描述符,并成为调度器的调度单位,栈也不溢出了,理论上是可以做到中断睡眠的),中断是可以睡眠的,但会引起很多问题.例 如,你在时钟中断中睡眠了,那操作系统的时钟就乱了,调度器也了失去依据;例如,你在一个IPI(处理器间中断)中,其它CPU都在死循环等你答复,你确 睡眠了,那其它处理器也不工作了;例如,你在一个DMA中断中睡眠了,上面的进程还在同步的等待I/O的完成,性能就大大降低了……还可以举出很多例子。 所以,中断是一种紧急事务,需要操作系统立即处理,不是不能做到睡眠,是它没有理由睡眠。

======================================================

 

另一篇:

 

http://blog.openrays.org/blog.php?do=showone&tid=455

 

其结论:

 

5. 中断处理时可否睡眠问题

Linux 设计中,中断处理时不能睡眠,这个内核中有很多保护措施,一旦检测到内核会异常。

当 一个进程A因为中断被打断时,中断处理程序会使用 A 的内核栈来保存上下文,因为是“抢”的 A 的CPU,而且用了 A 的内核栈,因此中断应该尽可能快的结束。如果 do_IRQ 时又被时钟中断打断,则继续在 A 的内核栈上保存中断上下文,如果发生调度,则 schedule 进 switch_to,又会在 A 的 task_struct->thread_struct 里保存此时时种中断的上下文。

假如其是在睡眠时被时钟中断打断,并 schedule 的话,假如选中了进程 A,并 switch_to 过去,时钟中断返回后则又是位于原中断睡眠时的状态,抛开其扰乱了与其无关的进程A的运行不说,这里的问题就是:该如何唤醒之呢??

另外,和该中断共享中断号的中断也会受到影响。

 

======================================================

 

再一篇,也分析的很到位:

 

http://blog.csdn.net/maray/article/details/5770889

 

其结论:

Linux是以进程为调度单位的,调度器只看到进程内核栈,而看不到中断栈。在独立中断栈的模式下,如果linux内核在中断路径内发生了调度(从技术上讲,睡眠和调度是一个意思),那么linux将无法找到“回家的路”,未执行完的中断处理代码将再也无法获得执行机会。


————————————————————————————————————————————————————————————————

为什么软中断中也不能睡眠

    这个问题实际上是一个老生常谈的问题,答案也很简单,Linux在软中断上下文中是不能睡眠的,原因在于Linux的软中断实现上下文有可能是中断上下文,如果在中断上下文中睡眠,那么会导致Linux无法调度,直接的反应是系统Kernel Panic,并且提示dequeue_task出错。所以,在软中断上下文中,我们不能使用信号量等可能导致睡眠的函数,这一点在编写IO回调函数时需要特别注意。在最近的一个项目中,我们在dm-io的callback函数中去持有semaphore访问竞争资源,导致了系统的kernel panic。其原因就在于dm-io的回调函数在scsi soft irq中执行,scsi soft irq是一个软中断,其会在硬中断发生之后被执行,执行上下文为中断上下文。


 


       中断上下文中无法睡眠的原因大家一定很清楚,原因在于中断上下文不是一个进程上下文,其没有一个专门用来描述CPU寄存器等信息的数据结构,所以无法被调度器调度。如果将中断上下文也设计成进程上下文,那么调度器就可以对其进行调度,如果在开中断的情况下,其自然就可以睡眠了。但是,如果这样设计,那么中断处理的效率将会降低。中断(硬中断、软中断)处理都是些耗时不是很长,对实时性要求很高,执行频度较高的应用,所以,如果采用一个专门的后台daemon对其处理,显然并不合适。


 


       Linux对中断进行了有效的管理,一个中断发生之后,都会通过相应的中断向量表获取该中断的处理函数。在Linux操作系统中都会调用do_IRQ这个函数,在这个函数中都会执行__do_IRQ(),__do_IRQ函数调用该中断的具体执行函数。在执行过程中,该函数通过中断号找到具体的中断描述结构irq_desc,该结构对某一具体硬件中断进行了描述。在irq_desc结构中存在一条链表irqaction,这条链表中的某一项成员都是一个中断处理方法。这条链表很有意思,其实现了中断共享,例如传统的PCI总线就是采用共享中断的方法,该链表中的一个节点就对应了一个PCI设备的中断处理方法。在PCI设备驱动加载时,都需要注册本设备的中断处理函数,通常会调用request_irq这个函数,通过这个函数会构造一个具体的irq action,然后挂接到某个具体irq_desc的action链表下,实现中断处理方法的注册。在__do_IRQ函数中会通过handle_IRQ_event()函数遍历所有的action节点,完成中断处理过程。到目前为止,中断处理函数do_IRQ完成的都是上半部的工作,也就是设备注册的中断服务程序。在中断上半部中,通常都是关中断的,基本都是完成很简单的操作,否则将会导致中断的丢失。耗时时间相对较长,对实时性要求不是最高的应用都会被延迟处理,都会在中断下半部中执行。所以,在中断上半部中都会触发软中断事件,然后执行完毕,退出服务。


 


       __do_IRQ完成之后,返回到do_IRQ函数,在该函数中调用了一个非常重要的函数irq_exit(),在该函数中调用invoke_softirq(),invoke_softirq调用do_softirq()函数,执行软中断的操作。此时,程序的执行环境还是中断上下文,但是与中断上半部不同的是,软中断执行过程中是开中断的,能够被硬中断而中断。所以,如果用户的程序在软中断中睡眠,操作系统该如何调度呢?只有kernel panic了。另外,软中断除了上述执行点之外,还有其他的执行点,在内核中还有一个软中断的daemon处理软中断事务,驱动程序也可以自己触发一个软中断事件,并且在软中断的daemon上下文中执行。但是硬中断触发的事件都不会在这个daemon的上下文中执行,除非修改Linux中的do__IRQ代码。


 


       上述对软中断的执行做了简要分析,我对Linux中的硬中断管理机制做了一些代码分析,这一块代码量不是很大,可移植性非常的好~~建议大家阅读,对我上述的分析和理解存在什么不同意见,欢迎大家讨论。



避开STM32H7的‘保护陷阱’:从Option Byte机制深度解析读写保护原理与预防 本文深度解析STM32H723VGT6的Option Byte保护机制,详细讲解RDP读保护和WRP写保护的工作原理及配置方法,并提供硬件设计防御策略和软件预防性编程技巧,帮助开发者避免误触发保护机制导致芯片锁定的问题。 阅读详情

相关推荐

SAP 成本分摊逻辑与案例(含具体数据)

摘要: SAP成本分摊通过**分配(Allocation)与分摊(Assessment)**两种方式,将间接成本中心费用按预设规则(如人数、工时、比例等)结转至直接成本对象。分配保留原始成本要素(如电费、工资),适用于需明细追踪的场景;分摊则打包为次级成本要素(如管理费用),简化核算。实操案例涵盖行政费用分配(按人数)、水电车间分摊(按工时)、机修作业分摊(作业成本法)及内部订单结算,系统通过KSV1/KSU1配置循环规则,KSV5/KSU5执行结转。关键点在于选择匹配业务的分摊基础,合理配置次级成本要素,

金牌架构师 487

中断时应该做的事

在平常的嵌入式开发中我们经常会用到中断,但是有很多人不知道中断发生时我们应当做些什么? 在这里我提前说一下,主要讲的是mcu的终端逻辑(app指的是mcu的主程序,boot指的是升级程序) 复杂嵌入式软件(app) 在一个逻辑复杂的嵌入式软件中,存在着很多个外部中断,并且可能存在着不同的优先级,此时中断的使用不在简单。每一个中断来临时的代码运行流程应该是,中断来临跳入中断函数,首先关闭全局中断避免新的中断来临,这么说可能有点抽象,我们打一个比方我们有两个串口(UART),uatr0首先进入中断函数,中

qq_36813351的博客 828

YOLOv13改进策略【小目标改进】| Shape-NWD:融合改进,结合Shape-IoU和NWD 更好地适应小目标特性

Bw−wgt2h−hgt2weight2Bweight2w−wgt​2h−hgt​2​其中weight2weight = 2weight2。

Limiiiing的博客 544

中断处理程序、中断上下文中处理延时及一些函数的调用规则(调IIC中断驱动有感)

1,中断处理程序中不能使用有睡眠功能的函数,如ioremap,kmalloc,msleep等,理由是中断程序并不是进程,没有进程的概念,因此就没有休眠的概念; 2,中断处理程序中的延时可以用忙等待函数来代替,如ndelay,udelay,mdelay等,这些函数在实现上本质是根

samantha_sun的专栏 4474

中断上下文

中断服务例程(ISR)是直接与硬件交互的非常重要的代码片段。它们拥有立刻执行的特权,以提高系统的性能;对应它们也需要准守一些注意事项,以便整个系统更为有序的运行,具体如下: 中断上下文代码绝不可以停止运行(即让出CPU)。中断处理函数不能通过调用schedule_timeout()等睡眠函数放弃处理器,在从中断处理函数中调用一个内核API前,应该仔细分析它,以确保其内部不会触发阻塞等待。例如,i...

weixin_39821531的博客 1296

内核中的竞争、互斥、中断上、下半部

目录一、内核中的竞争状态和互斥1、一些概念2、解决竟态的方法3、自旋锁和信号量的使用要点二、中断的上下半部1、中断处理的注意点2、中断下半部2种解决方案详解3、tasklet使用实战4、workqueue实战演示5、中断上下半部处理原则 一、内核中的竞争状态和互斥 浅谈可重入函数与不可重入函数:https://blog.csdn.net/chenyefei/article/details/82682241 1、一些概念 (1)竞争状态(简称竟态) 并发:多CPU、多任务、多中断操作一块相同的代码,在未运行完

小嵌同学的博客 1282

中断上下文注意事项

1. 如果你的中断上下文进入睡眠,它是一项应该被处以监禁的罪行。中断处理函数不能通过调用schedule_timeout()等睡眠函数放弃处理器,在中断处理函数中调用一个内核API之前,应该仔细分析它以确保其内部不会触发阻塞等待。例如,input_register_device()表面上看起来没有问题,但是它内部以GFP_KERNEL为参数调用了kmalloc()。 2. 为了在中断处理

jmflovezlf的专栏 894

关于中断上下文为什么不能睡眠

这个问题有很多人问过,我看了下Linux得内核代码,原因如下:(当然我不能保证一定对,如果有牛人理解得更好,欢迎指正) 1、 中断处理的时候,不应该发生进程切换,因为在中断context中,唯一能打断当前中断handler的只有更高优先级的中断,它不会被进程打断,如果在 中断context中休眠,则没有办法唤醒它,因为所有的wake_up_xxx都是针对某个进程而言的,而在中断context

8193

为什么中断上下文中不能睡眠

中断发生以后,CPU跳到内核设置好的中断处理代码中去,由这部分内核代码来处理中断。这个处理过程中的上下文就是中断上下文。 为什么可能导致睡眠的函数都不能中断上下文中使用呢? 首先睡眠的含义是将进程置于“睡眠”状态,在这个状态的进程不能被调度执行。然后,在一定的时机,这个进程可能会被重新置为“运行”状态,从而可能被调度 执行。 可见,“睡眠”与“运行”是针对进程而言的,代表进程的task_struct结构记录着进程的状态。内核中的“调度器”通过task_struct对进 程进行调度。 但是,中断上下文却不是

markey1的博客 1445

为什么中断过程中不能进行睡眠

运行在中断中的代码不能进行睡眠,或者阻塞!因为代码是运行在中断上下文中,并非进程上下文中,如果将中断进行睡眠的话,调度器无从得知下一个应该调度的进程,系统无法继续进行!         关于调度器在中断过程中无法调度其他进程的问题,是由于系统设计的原因!当然你也可以将你的系统设计成在中断过程中,可以进行睡眠或阻塞!但这样会增加你系统设计的复杂程度!因为在设计过程中,你需要考虑好多,复杂的情况!所

LinuxEngineer的专栏 3926

为什么可能导致睡眠的函数都不能中断上下文中使用呢

这个时候不能睡眠的关键是因为上下文。 大家知道操作系统以进程调度为单位,进程的运行在进程的上下文中,以进程描述符作为管理的数据结构。进程可以睡眠的原因是操作系统可以切换不同进程的上下文,进行调度操作,这些操作都以进程描述符为支持。 中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到

liwentongliunian的专栏 429

中断不能睡眠的原因

转载地址原文地址 这个说起来有点多,一一来看: 1,中断要根据前后文来说,一般说中断上下文中不能睡眠,这个中断是指硬件事件发生,触发CPU停止当前活动转而去处理硬件请求. 2,根据硬件请求响应处理逻辑的实时紧要与否,将整个中断处理过程分为上半部和下半部. 3,上半部也就是所谓的硬中断处理逻辑,其要求cpu在收到硬件请求后必须马上处理的事情,比如网卡收到数据包了,把数据包从网卡缓存拷贝到主存(可以由DMA完成,但寄存器的修改以及资源设定还是要由cpu去做)的逻辑就需要cpu立即去做,不做的话,网络新来的数据包

afootball的博客 1308

为什么中断不能 sleep

为什么在 Linux 的 ISR 里,不能 call scheduler?

lyndon 1621

linux进程上下文、中断上下文介绍,以及为什么中断不能睡眠

linux内核的软中断处理程序中能不能睡眠? 这是一个值得讨论的问题。 答案其实很简单,那就是不能。 因为Linux的软中断处理程序的运行上下文有可能是中断上下文。(注意此处是有可能,而并非一定) 那我们首先来了解下上下文,那什么是进程上下文?什么是中断上下文呢? 1.先来看进程上下文 我们知道:用户空间的应用程序,通过系统调用,进入内核空间。 所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。 2.再来看中断上下文

ludongguoa的博客 3433

中断处理程序中不能出现睡眠代码的原因

由于异常为同步事件,由当前进程执行所引发,所以可以说,异常处于被打断进程的上下文之中,为当前被打断的进程服务,所以在异常处理过程中,可以调用任何内核态的函数,也可以睡眠。因为睡眠时(应为是)有意义的,同时也是合理的;而中断为异步事件,虽然使用当前被打断进程的内核栈、处于被打断进程的上下文之中,但是和当前被中断进程没有必然的关系,同时中断处理程序和外部的一个具体设备相对应,这就要求中断处理程序能快速

做一个有技术追求的人 4015

中断处理handler不能sleep

1.进入中断处理程序--->2.保存关键上下文---->3.开中断(sti指令)--->4.进入中断处理程序的handler--->5.关中 ... 里面很多说法不是很同意, 个人认为中断处理handler不能sleep原因应该不是上面那些. 我们都是从理论讲下面这些问题, 因为linux在很多地方做了保护, 所以直接sleep或者schedule()会导致内核异常. 首

5531

中断不可睡眠的一些理解

LINUX中到是有中断还没有完全返回就调用schedule()而睡眠过去的例子。 可以猜是哪里。 我觉得,中断和异常不同,中断是异步的,异常和系统调用是同步的。 异常比如缺页异常发生时,当前任务在异常处理完成之前不能继续运行,该异常处理过程和当前任务天然相联系,运行在当前进程的上下文中。 中断的发生很可能是与当前任务无关的,如果把中断处理实现为强行与当前

计算机的自我意识 4433

面试官:为什么中断不能sleep | Linux 内核

大家好,我是老吴。今天是周一,大家工作顺利吗?这篇文章给大家分享一点小知识:为什么中断不能睡眠?网上很多文章尝试解释这个问题,看后我觉得头皮发麻。下面,我试着总结一下原因。明确问题首先,...

嵌入式Hacker 1042

中断处理中不能睡眠的原因

这个问题实际上是一个老生常谈的问题,答案也很简单,Linux在软中断上下文中是不能睡眠的,原因在于Linux的软中断实现上下文有可能是中断上下文,如果在中断上下文中睡眠,那么会导致Linux无法调度,直接的反应是系统KernelPanic,并且提示dequeue_task出错。所以,在软中断上下文中,我们不能使用信号量等可能导致睡眠的函数,这一点在编写IO回调函数时需要特别注意。在最近的一个项目中

拖油塔 1994

中断为什么不能sleep | Linux内核

在面试官:为什么中断不能sleep | Linux 内核一文中,作者逐层深入地讲解了为什么中断为什么不能sleep,并给出了ISR 里处理耗时工作的解决办法,建议先行阅读。 文中把问题“中断为什么不能sleep”逐步精确为“为什么在 Linux 里,ISR 被设计成不能睡眠”,讲得很好。但是,对于接下来讲解为什么不能sleep这一部分,(可能是因为我操作系统基础不好)对我来说讲解逻辑却显得不怎么清晰。下面就记录一下自己的理解。 结合下图讲解一下。假如系统正在执行thread 1,其中有操作criti

stone322的博客 866

中断上下文能够睡眠吗?

http://www.ednchina.com/ART_51707_29_0_OA_021acc67.HTM    这个问题实际上是一个老生常谈的问题,答案也很简单,Linux在软中断上下文中是不能睡眠的,原因在于Linux的软中断实现上下文有可能是中断上下文,如果在中断上下文中睡眠,那么会导致Linux无法调度,直接的反应是系统Kernel Panic,并且提示dequeue_task出错。

ke13590955160的专栏 3811

中断上半部,下半部/软中断/tasklet/工作队列

在阅读本文之前,可以先行阅读:中断上下文、进程上下文本文回答了为什么引入中断上部分、下部分以及上半部和下半部各自的分工;同时重点分析了下半部的三种机制及tasklet和工作队列的使用模块,能对整个框架有一个清晰的认识。1. 为什么引入中断上半部、下半部(1)为了解决一个矛盾体:又想中断处理程序运行快,又想中断处理程序完成的工作量多。 (2)中断处理程序本身局限性,使得它只能完成整个中断处理流程的上

Jason Gel 的专栏 3930

欧姆龙PLC CP1E直读密码安全解密软件CP1E UM密码 上传解密破解软件.zip

欧姆龙PLC CP1E USB下载口 安全直读解密软件欧姆龙PLC CP1E解密UM上传密码使用USB下载口如遇到个别PLC解不了的也是正常的,直读解密即使有解不了也不会破坏程序(注意打钩扩展的加密方式PLC解不了)如介意者请不要购买

松下焊接器人说明书 标准弧焊机器人示教器说明书 编程手册 Ver150226

松下机器人最新YA系列机器人示教器操作说明书,松下焊接器人说明书 标准弧焊机器人示教器说明书 编程手册 Ver150226

上一篇: VFS的数据结构
猕猴大哥
博客等级 码龄18年 25粉丝 12原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值