为了给你完整的上下文,我的讨论开始于观察我在基于ARM皮层A8的SoC上运行SMP linux(3.0.1-rt11),这是一个单处理器.我很想知道通过禁用SMP支持是否会有任何性能优势.如果是,它会对我的驱动程序和中断处理程序产生什么影响.
我做了一些阅读并遇到了两个相关的主题:自旋锁和内核抢占.我没有做更多的谷歌搜索和阅读,但这次我得到的是一些陈旧和矛盾的答案.所以我想让我试试stackoverflow.
我的怀疑/问题的起源是来自Linux设备驱动程序第3版第5章的这一段:
就其本质而言,自旋锁旨在用于多处理器系统,尽管就并发性而言,运行抢占式内核的单处理器工作站的行为类似于SMP.如果一个非抢占式单处理器系统进入锁定旋转,它将永远旋转; 没有其他线程能够获得CPU来释放锁.出于这个原因,在没有启用抢占的单处理器系统上的自旋锁操作被优化为什么也不做,除了那些改变IRQ屏蔽状态的操作.由于抢占,即使您从未期望您的代码在SMP系统上运行,您仍然需要实现正确的锁定.
我的疑惑/问题是:
a)默认情况下,Linux内核是否在内核空间中抢先一步?如果是,此抢占是否仅限于进程或中断处理程序也可以被抢占?
b)Linux内核(在ARM上)是否支持嵌套中断?如果是,每个中断处理程序(上半部分)是否都有自己的堆栈,或者它们共享相同的4k/8k内核模式堆栈?
c)如果我禁用SMP(Config_SMP)并且抢占(Config_preempt)将在我的驱动程序和中断处理程序中旋转锁定有意义吗?
d)内核如何处理在执行上半部分时引发的中断,即它们是被禁用还是被屏蔽?
经过一些谷歌搜索我发现了这个:
对于没有CONFIG_SMP编译的内核,如果没有CONFIG_PREEMPT,则根本不存在自旋锁.这是一个很好的设计决策:当没有其他人可以同时运行时,没有理由拥有锁.
如果在没有CONFIG_SMP的情况下编译内核,但设置了CONFIG_PREEMPT,那么自旋锁只会禁用抢占,这足以防止任何比赛.在大多数情况下,我们可以认为抢占等同于SMP,而不是单独担心它.
但是源上没有内核版本或日期.任何人都可以确认它是否仍然适用于最新的Linux内核?
我尝试了这三个版本的小程序,我得到了一些有趣的结果.任何人都可以帮助我了解每种情况下的编译器行为.
version 1.0
int A;
int A;
int A;
int main ()
{
return 0;
}
Result: Got compiled with one copy of A in BSS.
Version 2.0
int main ()
{
int A;
int A;
int A;
return 0;
}
Result: Failed to compile with complaining for re-declaration.
Version 3.0
int A;
int main()
{
static int A;
return0;
}
result: Compiled with two copy of A in BSS. one is A and another a.<some numeric tag>.
Run Code Online (Sandbox Code Playgroud)