Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux kernel 围绕自旋锁irqsave的困惑:中断状态在什么嵌套情况下保持?_Linux Kernel_Spinlock_Smp_Preemption - Fatal编程技术网

Linux kernel 围绕自旋锁irqsave的困惑:中断状态在什么嵌套情况下保持?

Linux kernel 围绕自旋锁irqsave的困惑:中断状态在什么嵌套情况下保持?,linux-kernel,spinlock,smp,preemption,Linux Kernel,Spinlock,Smp,Preemption,有很多关于旋转锁的Q&A,但我还是很困惑。我认为这是因为提问和回答假设了不同的设置,或者在提问或回答时没有清楚地解释关于它是SMP还是抢占式内核的设置(也混合了一些旧信息) 我的第一个问题是:(Q1)在SMP情况下,schedule()是否在每个处理器上同时运行(我知道调度是由jiffies定时器中断启动的)?在我下面的问题中,我假设是的。如果有人能简单地向我解释一下进程在调度期间是如何在处理器核心之间移动的,我将不胜感激 我试图理解当使用spin\u lock/unlock\u irqsave

有很多关于旋转锁的Q&A,但我还是很困惑。我认为这是因为提问和回答假设了不同的设置,或者在提问或回答时没有清楚地解释关于它是SMP还是抢占式内核的设置(也混合了一些旧信息)

我的第一个问题是:(Q1)在SMP情况下,
schedule()
是否在每个处理器上同时运行(我知道调度是由jiffies定时器中断启动的)?在我下面的问题中,我假设是的。如果有人能简单地向我解释一下进程在调度期间是如何在处理器核心之间移动的,我将不胜感激

我试图理解当使用
spin\u lock/unlock\u irqsave
时是如何、为什么使用的。这是我的问题

假设有一个代码调用
spin\u lock\u irqsave
,并且在调用
spin\u lock\u irqsave()
时,中断状态(启用)为“禁用”。此代码是否可以在中断上下文中运行?可能不会,因为如果中断在相应的本地处理器中被禁用,ISR本来就不应该启动。因此,调用
spin\u lock\u irqsave
的代码必须在进程上下文中。好的,中断先前已被禁用,但进程正在尝试使用
spin\u lock\u irqsave
锁定

在什么情况下中断会被禁用?我认为有两种情况

案例1:先前的中断例程已被此进程抢占(调用此
spin\u lock\u irqsave
)。这很奇怪,因为ISR不能被抢占。(Q2)顺便问一下,在抢占式内核中,ISR可以被进程抢占吗?(Q3)我想是因为
preempt\u count()
,将
d定义为
(当前线程信息()->preempt\u count)
,所以
preempt\u disable
只对进程有效,不中断。中断是否也有当前线程信息

案例2:以前的正常进程已通过
spin\u lock\u irq
(或
irqsave
)获得锁。但这也很奇怪,因为在锁定之前,
spin\u lock\u irq
(或
irqsave
)会禁用任务的抢占和中断,告诉调度程序在调度程序计时器中断后不要切换到其他任务。所以这种情况不可能是真的

我知道我必须进一步研究SMP和内核抢占的进程调度,也许我误解了什么。有人能澄清一下我的问题吗?非常感谢你的阅读

有很多关于旋转锁的Q&A,但我还是很困惑。我认为这是因为提问和回答假设了不同的设置,或者在提问或回答时没有清楚地解释关于它是SMP还是抢占式内核的设置(也混合了一些旧信息)

我只能同意。自旋锁虽然本质上很简单,但如果包含在现代Linux内核的上下文中,它就根本不是一个简单的主题。我不认为仅仅通过阅读随机和特定于大小写的堆栈溢出答案就可以很好地理解自旋锁

我强烈建议你读一读这本书,它可以在网上免费获得。特别是,第5章的“自旋锁”一节非常有助于理解自旋锁在不同情况下的用处

Q1)在SMP情况下,
schedule()
是否在每个处理器上同时运行?[…]如果有人能简单地向我解释一下进程在调度期间如何移动处理器内核,我将不胜感激

是的,如果你愿意的话,你可以这样看。每个CPU(即每个单处理器内核)都有自己的计时器,当给定CPU上出现计时器中断时,该CPU执行内核注册的计时器中断处理程序,该处理器调用调度器,调度器重新调度进程

系统中的每个CPU都有自己的runqueue,它保存处于可运行状态的任务。任何任务最多只能包含在一个运行队列中,并且不能同时在多个不同的CPU上运行

任务的CPU相关性决定了任务可以在哪个CPU上运行。默认的“正常”关联允许任务在任何CPU上运行(特殊配置除外)。根据它们的关联性,任务可以由调度程序从一个运行队列移动到另一个运行队列,或者如果需要,可以通过
sched_setaffinity
syscall(下面解释了如何移动)

建议阅读:

假设有一个代码调用
spin\u lock\u irqsave
,并且在调用
spin\u lock\u irqsave()
时,中断状态(启用)为“禁用”。此代码是否可以在中断上下文中运行?可能不会

为什么不呢?这是可能的。代码可以在中断上下文中运行,但不会被其他中断调用。请看我答案的底部

案例1:先前的中断例程已被此进程抢占(调用此
spin\u lock\u irqsave
)。这很奇怪,因为ISR不能被抢占

你说得对,这很奇怪。不过,这不仅奇怪,而且是不可能的。在Linux上,任何时候都可以启用或禁用中断(这两者之间没有任何限制)。中断实际上没有“优先级”(就像任务一样),但我们可以将其分为两类:

  • 不可抢占的中断,必须在完全控制CPU的情况下从头到尾运行。这些中断将系统置于“禁用中断”状态,并且不会发生其他中断
  • 可重入并允许其他中断发生的可抢占中断。如果在服务此中断时发生另一个中断,则进入嵌套中断场景,这类似于任务的嵌套信号处理程序场景