V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
villivateur
V2EX  ›  问与答

有人在瑞芯微的 RK35xx 平台上遇到过缓存一致性问题吗?

  •  
  •   villivateur · 19 天前 · 919 次点击

    最近我一个项目涉及这个平台的内核开发。内核有两个线程,使用 wait_event 进行通讯,有大约万分之一的概率,事件发送方设置事件后,接收方获取不到状态。

    类似这个问题: https://stackoverflow.com/questions/23262893/wait-event-timeout-exits-on-timeout-with-condition-set

    如果我把两个线程绑定到同一个 CPU 核心上,问题就消失了。

    之前我搞这个平台的 AMP 架构的时候,也出现过裸机核心与 Linux 核心缓存不一致的问题。

    14 条回复    2025-03-05 15:17:30 +08:00
    cnnblike
        1
    cnnblike  
       19 天前
    https://developer.arm.com/documentation/100941/0101/Memory-attributes
    内存一致性看这个,一般说来是不在一个 cluster 的时候容易遇到这个

    做 amp 的话,内核态 解决方案 https://developer.arm.com/documentation/ddi0500/e/system-control/aarch32-register-summary/c7-system-operations?lang=en

    做进程通信的话,整个 core affinity ,或者弄个 memory-barrier 应该也行
    villivateur
        3
    villivateur  
    OP
       19 天前
    @cnnblike 不在一个 cluster 的情况,按我的理解,应该非常容易出现缓存不一致,而不是极低的概率出现。AMP 的方案我现在也不干了,只是提一嘴。另外 wait_event 相关的内核 API 是自带内存屏障的,理论上不需要手动加。
    cnnblike
        4
    cnnblike  
       19 天前
    @villivateur 不在一个 cluster 的情况不大可能说实话,你直接说 rk 什么型号吧
    https://linaro-dev.linaro.narkive.com/f2kFnMmW/why-is-the-the-smp-mb-in-arm64-s-barrier-h-dmb-ish
    ”In Arm V8 Architecture Reference Manual£¬there is an example (see beblow) to explain the shareability attribute of clusters. It is easy to know: each cluster is corresponding to a Inner shareable domain; the two cluster comprise a Outer shareable domain.“
    cnnblike
        5
    cnnblike  
       19 天前
    如果是 rk3568 或者是 rk3566 上的核间通信,因为内存不一致触发问题说实话可能性很低,按 arm 的定义(和推荐实现),单一一个 cluster 的所有核都在同一个 innershareable 上,理论上 cluster 内所有核能看到的,都是一样的。
    如果是 rk3588 ,那是有可能的,我猜你把一个小核分出来跑 amp ,或者干脆是在 cortex-m 核上跑 amp 通信,那就触发缓存不一致了
    villivateur
        6
    villivateur  
    OP
       19 天前
    @cnnblike 目前这个问题,出在 RK3588 上,是 SMP 架构,全部 8 个核心都是 Linux 。但你这么一说我开始怀疑是大小核的问题,我要去验证下看看如果两个线程都跑在小核或者都跑大核,看看还有没有问题。

    另外,之前我在 RK3568 上面跑 AMP ,是 core 3 裸核,开了一块内存,core3 往里面写数据,Linux 核心(另外三个核)读不到,必须 Linux 先写一下这块内存才能读到
    ivan_wl
        7
    ivan_wl  
       19 天前
    看下反汇编是不是有内存屏障指令,触发 event 前应该是 dmb ishst ,另外一个 cpu 在被唤醒后应该先做 dmb ishld
    cnnblike
        8
    cnnblike  
       19 天前
    @villivateur
    内存段和 shareable 的设置和 tlb 有关系,在内核的 mm 那块的逻辑里,具体说是 The arch/arm64/mm/cache-*.S 和 arch/arm64/mm/proc-*.S
    还有一个可能性,我不知道你是用 mem=xxx MB 设置的内存还是用 reversed_memory 设置的内存,所以可能行为会有不同。

    如果你用的 jailhouse 的话,他那个实现对大小 cluster 的支持可能是不对的,看此处注释:
    https://github.com/siemens/jailhouse/blob/master/hypervisor/arch/arm64/entry.S#L453-L458
    cnnblike
        9
    cnnblike  
       19 天前
    @villivateur 我最近也在研究这块,有兴趣的话,记得把结论也发我一下
    cnnblike
        10
    cnnblike  
       19 天前
    我仔细分析了一下你遇到的问题,感觉像是这样:
    1. rk3588 这个问题是应该是因为那个页面被设置成了 write-back 而不是 write-through ,由于是闲时写,所以在你系统的内存总线空闲的时候会写入,然后叠加 wb 会在写入的时候刷 L1 ,更新另一个 cluster 的 L2 ,所以显得触发概率低,所以我建议你跑一个高内存总线开销的用户态程序,应该能让任务出问题

    2. rk3568 的场合,你的页表上对这个页面可能没设置 SH ,看这里 https://zhuanlan.zhihu.com/p/532838098
    villivateur
        11
    villivateur  
    OP
       19 天前
    @cnnblike 嗯,有道理,对于内存管理我也还没入门,目前正在复现不同核心的现象,复现很耗时,我有进展了 @你
    villivateur
        12
    villivateur  
    OP
       17 天前
    @cnnblike 这两天验证了一下该问题与大小核的关系。复现情况是:两个线程都在大核或者都在小核,暂时没有复现问题。如果一个大核一个小核,就可以复现。
    cnnblike
        13
    cnnblike  
       17 天前
    @villivateur https://docs.kernel.org/driver-api/device-io.html
    看一下这个,你需要的可能是 ioremap 或者 ioremap_nc
    cnnblike
        14
    cnnblike  
       17 天前
    正确的做法可能是用 memremap ,用 dts+memremap 这样的形式会比较好点:

    https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841683/Linux+Reserved+Memory

    memremap(r.start, resource_size(&r), MEMREMAP_WT);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   941 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:44 · PVG 04:44 · LAX 13:44 · JFK 16:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.