在 x86 上发送 IPI 后内存写入是否可见?

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

我已经阅读了 Intel 64 and IA-32 Architectures SDM vol 3A, 9.2 MEMORY ORDERING,但有一个问题一直困扰着我。

如果我先写入内存地址,然后使用 x2APIC 发送处理器间中断(IPI),这意味着发送 IPI 不需要写入内存(只需使用 wrmsr)。另一个核心接收IPI并读取内存,它会读取正确的值吗?

例如:

最初 x = 0

处理器 0:

mov [ _x], 1
wrmsr       # use x2APIC to send IPI

处理器 1:

# resive IPI, in the interrupt service routine:
mov r1, [ _x]

r1 = 0 允许吗?

assembly x86 operating-system memory-barriers msr
3个回答
3
投票

这是一个有趣的问题。从表面上看,人们会认为由于

WRMSR
是一条序列化指令,它会刷新前面的内存写入,一切都很好。即使如此,引用手册:

这些指令强制处理器完成所有修改 通过先前的指令到标志、寄存器和内存并耗尽 所有缓冲写入内存在获取下一条指令之前 并被处决。

(强调我的)

它没有说明发送 IPI 的顺序,因为这是当前指令的一部分,而不是下一条指令的一部分。因此,从理论上讲,这意味着另一个核心可以在原始核心仍在忙于刷新内容时执行

mov r1, [ _x]
,但考虑到目标核心需要服务可能具有更高延迟的中断,这种可能性很小。

正如 @harold 提到的,这一点没有实际意义,因为

WRMSR
并不总是序列化。阅读我最初错过的脚注:

WRMSR 到 IA32_TSC_DEADLINE MSR(MSR 索引 6E0H)和 X2APIC MSR(MSR 索引 802H 至 83FH)未序列化。

所以绝对不能保证对

x
的写入会被刷新。


2
投票

摘自英特尔® 64 和 IA-32 架构软件开发人员手册第 3A 卷:系统编程指南,第 1 部分

11.12.3 x2APIC 模式 MSR 接入

为了允许在 x2APIC 模式下高效访问 APIC 寄存器,在写入 APIC 寄存器时放宽了 WRMSR 的序列化语义。因此,系统软件不应使用“WRMSR to APIC registers in x2APIC mode”作为串行化指令。对 APIC 寄存器的读写访问将按程序顺序进行。对 APIC 寄存器的 WRMSR 可能会在所有先前的存储全局可见之前完成;软件可以防止这种情况 通过在 WRMSR 之前插入序列化指令或序列 MFENCE;LFENCE。

RDMSR 指令未串行化,并且在 x2APIC 模式下读取 APIC 寄存器时,此行为保持不变。使用 RDMSR 指令访问 APIC 寄存器的系统软件不应预期出现串行化行为。 (注:基于 MMIO 的 xAPIC 接口被系统软件映射为未缓存区域。因此,对 xAPIC-MMIO 接口的读/写在 xAPIC 模式下具有序列化语义。)

但是,我仍然不知道这是否适用于 amd 处理器。


0
投票

处理器 1 在处理 IPI 时可能没有观察到处理器 0 写入的值。在通过 X2APIC 发送 IPI 之前需要设置屏障,因为写入 x2APIC MSR 不是序列化指令。

这是Linux内核中进行跨核函数调用时的代码。在将 IPI 发送到目标 CPU 之前,它有“mfence; lfence”。

static void x2apic_send_IPI(int cpu, int vector)
{
    u32 dest = per_cpu(x86_cpu_to_apicid, cpu);

    /* x2apic MSRs are special and need a special fence: */
    weak_wrmsr_fence();
    __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL);
}

/*
 * Make previous memory operations globally visible before
 * a WRMSR.
 *
 * MFENCE makes writes visible, but only affects load/store
 * instructions.  WRMSR is unfortunately not a load/store
 * instruction and is unaffected by MFENCE.  The LFENCE ensures
 * that the WRMSR is not reordered.
 *
 * Most WRMSRs are full serializing instructions themselves and
 * do not require this barrier.  This is only required for the
 * IA32_TSC_DEADLINE and X2APIC MSRs.
 */
static inline void weak_wrmsr_fence(void)
{
    alternative("mfence; lfence", "", ALT_NOT(X86_FEATURE_APIC_MSRS_FENCE));
}
© www.soinside.com 2019 - 2024. All rights reserved.