ALT_SMP 和 ALT_UP 的作用是什么?

问题描述 投票:0回答:2

我刚刚导航到 Linux Arm 内核树,我在汇编文件中看到 ALT_SMP 和 ALT_UP 的用法,它们到底是做什么用的?

linux arm
2个回答
0
投票

参考 https://github.com/torvalds/linux/blob/master/arch/arm/include/asm/assembler.h#L169

ALT_SMP
应该表示仅在
SMP, Symmetric MultiProcessing
系统中执行。

#ifdef CONFIG_SMP
#define ALT_SMP(instr...) \
9998: instr
#define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\
9997: instr ;\
.if . - 9997b != 4 ;\
.error "ALT_UP() content must assemble to exactly 4 bytes";\
.endif ;\
.popsection
// skipped
#else
#define ALT_SMP(instr...)
#define ALT_UP(instr...) instr

考虑到这种情况,

UP
应该意味着
Uni Processor

也来自于linux-arm-kernel上的

邮件

ALT_{UP,SMP} 宏用于在运行时修补指令 取决于我们是否运行在 SMP 平台上。这是 一般用外行汇编代码完成,但也有需要 在内联汇编中实现此功能(例如自旋锁)。


0
投票

TLDR:当支持arm32 smp的内核在单处理器机器上运行时,在某些地方,与smp机器相比,必须以不同的方式进行操作。对于这些地方,ALT_SMP 宏提供 smp 特定的 cpu 指令,而 ALT_UP - 它的单处理器替代方案。

当 CONFIG_SMP_ON_UP 启用时,ALT_SMP 和 ALT_UP 宏仅对 arm32 有效。现在,当选择 CONFIG_SMP 时,即当我们构建 smp 内核时,默认启用 CONFIG_SMP_ON_UP。启用 CONFIG_SMP_ON_UP 意味着我们希望我们的 smp 内核也能够在非 smp(即单处理器,UP)机器上运行。

问题是在 UP 机器上,有些事情必须由启用 smp 的内核以不同的方式完成。例如。 UP机器可能缺少wfe指令。或者必须使用不同的指令使 tlb 缓存条目无效(请参阅

tlb-v7.S
中的 v7wbi_flush_kern_tlb_range):

ALT_SMP(mcr p15, 0, r0, c8, c3, 1)  @ TLB invalidate U MVA (shareable)
ALT_UP(mcr  p15, 0, r0, c8, c7, 1)  @ TLB invalidate U MVA

这就是 ALT_SMP 和 ALT_UP 宏的用途 - 它们提供相同代码的 smp 和 UP 变体。通过检测机器类型并修补代码位置(如有必要),在内核启动时选择正确的变体。

ALT_SMP 和 ALT_UP 宏成对出现,每个宏恰好包装一条 cpu 指令。 ALT_SMP 包装了指令的 smp 变体 - 这是主要代码路径,它进入内核 ELF 的通常 .text 部分。 ALT_UP 包装指令的替代 UP 变体,该变体进入特殊的 .alt.smp.init ELF 部分以及 smp 指令内存位置的偏移量(来自 assembler.h):

#define ALT_SMP(instr...)                     \
9998:   instr
#define ALT_UP(instr...)                      \
        .pushsection ".alt.smp.init", "a"     ;\
        .align  2                             ;\
        .long   9998b - .                     ;\
9997:   instr                                 ;\
        .popsection

如果启用了 CONFIG_SMP_ON_UP,则在内核启动的早期 __fixup_smp 例程(head.S的一部分)会检测机器的类型(smp 或 UP)。如果机器是 smp,则什么也不做 - 请记住,smp 是主代码路径,因此所有 ALT_SMP 指令都保留在原处。如果机器处于 UP 状态,则调用 __fixup_smp_on_up 进行实时内核代码修补 - 将 SMP_ALT cpu 指令替换为 ALT_UP 替代指令。

如上所述,ALT_UP 指令变体和相应 ALT_SMP mem 位置的偏移量作为 8 字节记录(4 字节偏移量 + 4 字节指令)存储在 .alt.smp.init 部分中。在最终内核链接期间,目标文件中的所有这些部分都通过内核链接器脚本vmlinux.lds合并到一个 .init.smpalt 部分中。 .init.smpalt 的起始/结束内存地址由 __smpalt_begin 和 __smpalt_end 符号表示。在修补期间迭代 8 字节记录时,这些符号用作数组边界。

禁用 CONFIG_SMP_ON_UP 时,vmlinux.lds 在最终内核映像中不会创建 .init.smpalt 部分,即原始 .alt.smp.init 部分将被丢弃。也没有编译机器类型检测/指令修补代码。使用 SMP_ALT 指令。

© www.soinside.com 2019 - 2024. All rights reserved.