由SnpUniqueFwd和SnpUnique混合使用引发的思考
一致性与内存屏障:一场在CHI总线上的花活
前几日,在 xhs 上刷到一则颇有意思的讨论:关于SnpUniqueFwd和SnpUnique混合使用的话题,以及这种混用究竟会在底层引发什么灾难性的影响。在讨论这个哑谜之前,先得理清这两个概念的底牌是什么。
Coherence(缓存一致性)和 Consistency(内存一致性)到底是俩兄弟还是父子,真不好分清。咱们拿《王者荣耀》瞎举个例子:Coherence 就像是红蓝 Buff 的存活状态,不管十个玩家的网络延迟有多大,只要红 Buff 被打掉了,所有人最终看到这个野怪坑位肯定都是空的(死磕单一对象);而 Consistency 关乎的是全图的因果律,它就像是英雄的连招顺序。比如对面打野先“交了闪现(事件 A)”,然后才“放出大招秒人(事件 B)”。如果在你的手机屏幕上看到的画面是:自己突然先掉血被秒了,然后对面打野才从墙外闪现进来,这种违背常理的吃书现象就叫因果律崩溃(它管的是多个独立事件在全局的先后呈现顺序)。这个例子不是非常恰到,这两个毕竟有非常明显的层次关系。
在多核架构的世界里,缓存分布在不同的核心上,依赖监听事务去同步。SnpUnique是一种非转发类型的监听请求(Non-forwarding snoop),为了获取缓存行的独占(Unique)副本,它会严谨地要求系统内所有持有该副本的节点立刻将缓存销毁(作废缓存,强制转换为 Invalid (I) 态)。属于妥...
内存怪谭
写在前面
本系列主要用于记录Linux内核内存BUG相关的故事,以及一些内存奇闻轶事。
shmem - sleep in atomic context
这个BUG在我们龙蜥cloud-kernel的4.19中用stress-ng压测复现。通常情况下,这个BUG对系统稳定性影响并不是很大,仅仅在CONFIG_PREEMPT_COUNT打开的情况下才会,而这个config属于debug类型,一般情况下不会打开。接下来,就分享一下这个怪异的BUG是如何在CONFIG_PREEMPT_COUNT打开的情况下触发的。
首先
#ifdef CONFIG_PREEMPT_COUNT
#define preempt_disable() \
do { \
>-------preempt_count_inc(); \
>-------barrier(); \
} while (0)
#define preempt_enable() \
do { \
>-------barrier(); \
>-------preempt_count_dec(); \... arm64 TLB 硬件设计
TLB flush 硬件行为
arm64 与 x86 在 tlb flush 差异挺大,比如 flush 的范围、同步机制。x86 的 tlb flush 一般是(1)只处理当前核,其他核是否需要刷有操作系统内核去判断,这算是同步机制的范畴,依赖软件发起 IPI 到需要的核,(2)而 arm64 的 TLBI 的范围是整个共享域,以不成熟的经验,arm64 一般只会设计一个共享域,是否其他核也需要同步,是由硬件上去判断。
先从最简单的场景,TLBI 只刷一个核开始。
首先,TLBI 在硬件上并不是一个高优的指令,在执行 TLBI 时,首先会将其存到具有 4 个条目的后台任务队列 STQ 中,等 MMU 主流水线有空闲周期时,开始处理 STQ 队列中的任务。下面是其中一个条目,命名分别是 stq0-stq3:
always_ff @(posedge clk)
begin: u_mm_stq0_type_q_1_0_grp
if (mm_stq0_en == 1\'b1) begin
mm_stq0_type_q[1:0] <= `PERSEUS_DFF_DELAY l2_cpu_snp_type[1:0];
mm_stq0_va_q[`PERSEUS_MMU_VA] <= `PERSEUS_DFF_DELAY l2_cpu_snp_addr[`PERSEUS_MMU_SNP_VA_RANGE];
mm_stq0_va_valid_q <= `PERSEUS_DFF_DELAY l2_cpu_snp_va_valid_ql;...