gpt4 book ai didi

c - 了解最新(3.0.0 及更高版本)Linux 内核中 CONFIG_SMP、自旋锁和 CONFIG_PREEMPT 之间的链接

转载 作者:行者123 更新时间:2023-12-02 20:38:41 24 4
gpt4 key购买 nike

为了给您提供完整的背景信息,我的讨论始于我在基于 ARM Cortex A8 的 SoC(单处理器)上运行 SMP linux (3.0.1-rt11) 的观察。我很想知道禁用 SMP 支持是否会带来任何性能优势。如果是的话,它将对我的驱动程序和中断处理程序产生什么影响。

我做了一些阅读,发现了两个相关主题:自旋锁和内核抢占。我做了更多的谷歌搜索和阅读,但这一次我得到的只是一些陈旧且矛盾的答案。所以我想让我尝试一下 stackoverflow。

我的疑问/问题的起源是 Linux 设备驱动程序第三版第 5 章中的这段:

Spinlocks are, by their nature, intended for use on multiprocessor systems, although a uniprocessor workstation running a preemptive kernel behaves like SMP, as far as concurrency is concerned. If a nonpreemptive uniprocessor system ever went into a spin on a lock, it would spin forever; no other thread would ever be able to obtain the CPU to release the lock. For this reason, spinlock operations on uniprocessor systems without preemption enabled are optimized to do nothing, with the exception of the ones that change the IRQ masking status. Because of preemption, even if you never expect your code to run on an SMP system, you still need to implement proper locking.

我的疑问/疑问是:

a) Linux 内核默认在内核空间中是抢占式的吗?如果是,这种抢占仅限于进程还是中断处理程序也可以被抢占?

b) Linux 内核(ARM 上)是否支持嵌套中断?如果是,每个中断处理程序(上半部分)是否有自己的堆栈,或者它们共享相同的 4k/8k 内核模式堆栈?

c) 如果我禁用 SMP (CONFIG_SMP) 和抢占 (CONFIG_PREEMPT),驱动程序和中断处理程序中的自旋锁是否有意义?

d) 内核如何处理执行上半部分时引发的中断,即它们将被禁用或屏蔽吗?

经过一番谷歌搜索后,我发现了这个:

For kernels compiled without CONFIG_SMP, and without CONFIG_PREEMPT spinlocks do not exist at all. This is an excellent design decision: when no-one else can run at the same time, there is no reason to have a lock.

If the kernel is compiled without CONFIG_SMP, but CONFIG_PREEMPT is set, then spinlocks simply disable preemption, which is sufficient to prevent any races. For most purposes, we can think of preemption as equivalent to SMP, and not worry about it separately.

但是 source 上没有内核版本或日期。谁能确认它对于最新的 Linux 内核是否仍然有效?

最佳答案

a) Linux 是否是抢占式的取决于你是否这样配置
使用CONFIG_PREEMPT。没有默认值。如果您运行 make config,则必须进行选择。

b) 中断确实嵌套在 Linux 上;当正在处理中断时,其他中断可能会关闭。在 ARM 和许多其他架构上都是如此。它们都在同一个堆栈上。当然,用户空间堆栈不用于中断!

c) 如果禁用 SMP 和抢占,代码中的自旋锁如果是常规自旋锁,则将减少为无操作,而 IRQ 自旋锁 (spin_lock_irqsave/spin_lock_irqrestore )将变成中断禁用/启用。因此,后者仍然至关重要;它们可以防止运行代码的任务之间发生竞争并中断运行代码。

d) “上半部分”传统上是指中断服务例程。驱动程序的上半部分代码通过中断运行。下半部分由任务调用(读取或写入数据或其他)。中断处理的详细信息是特定于体系结构的。

I most recently worked very closely with Linux interrupts on a particular MIPS architecture. On that particular board, there were 128 interrupt lines maskable via two 64 bit words. The kernel implemented a priority scheme on top of this, so before executing a handler for a given interrupt, the lower ones were masked via updates of those 2x64 bit registers. I implemented a modification so that the interrupt priorities could be set arbitrarily, rather than by hardware position, and dynamically by writing values into a /proc entry. Moreover, I put in a hack whereby a portion of the numeric IRQ priority overlapped with real-time priority of tasks. So RT tasks (i.e. user space threads) assigned to certain range of priority levels were able to implicitly suppress a certain range of interrupts while running. This was very useful in preventing badly-behaved interrupts from interfering with critical tasks (for instance, an interrupt service routine in the IDE driver code used for the compact flash, which executes busy loops due to a badly designed hardware interface, causing flash writes to become the de-facto highest priority activity in the system.) So anyway, IRQ masking behavior isn't written in stone, if you're in control of the kernel used by customers.

问题中引用的陈述仅适用于常规自旋锁(spin_lock 函数/宏),而不适用于 IRQ 自旋锁(spin_lock_irqsave)。在单处理器上的可抢占内核中,spin_lock 只需禁用抢占,这足以将所有其他任务排除在内核之外,直到 spin_unlock。但是spin_lock_irqsave必须禁用中断。

关于c - 了解最新(3.0.0 及更高版本)Linux 内核中 CONFIG_SMP、自旋锁和 CONFIG_PREEMPT 之间的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14380417/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com