Linux 的清 CPU cache 的函数是哪个?

2023-09-05 22:11:43 +08:00
 amiwrong123

目前我正在 linux 上,写一个用户态的一个 c 程序。里面有一个逻辑是,去写了一段 RAM ,但写的动作实际上只发生在了 x86 CPU 的 cache 里面,还没有真正写到 RAM 里,然后这导致了错误发生(可以认为我需要结合 DMA 做一些操作,但 DMA 需要读到的东西还在 CPU 的 cache 里面呢)。

所以我想知道,linux 里有提供这种函数吗?(类似 arm ,都会提供这种函数的)

另外,我在网上搜,搜到的 全是 shell 里执行的命令:sync; echo 1 > /proc/sys/vm/drop_caches。这个关键词到底该怎么搜索。

2342 次点击
所在节点    程序员
33 条回复
codehz
2023-09-05 23:05:50 +08:00
udmabuf 能 O_SYNC 的原因是加了这个参数后,就会在内核里用 dma_sync_single_for_cpu 来同步 cpu 缓存(
其他普通的实现可不一定有这个)
amiwrong123
2023-09-05 23:13:13 +08:00
@codehz #19
理解你说的意思,就是说,如果一个进程 malloc 了一片空间,这片空间只是属于这个进程的,但可能进程调度,把 RAM 的东西从内存条上调度走了。
不过我这个应该没有这个担心,因为不是用户态 malloc 的空间,是直接 搞了一块 连续的物理地址出来,再映射到虚拟地址。
amiwrong123
2023-09-05 23:14:38 +08:00
@codehz #21
代码是这样的,是用 devmem 获得的 fd ,获得时是使用了 O_SYNC 的(不知道为啥,还是没起作用)。然后用这个 fd 进行 mmap ,获得了一个虚拟地址。
nuk
2023-09-05 23:20:24 +08:00
Memory barrier 吧,硬件不同实现不同
codehz
2023-09-05 23:21:23 +08:00
@amiwrong123 前面说的被调度走指的不是说内存映射也炸了
而是说 dma 硬件处理上可能会有不低概率观察到只进行到一半的修改(
后面补充的 o sync 就是为了应对你说的这个的 dev mem 的问题,正经解决方法就是用 udmabuf 那个模块去映射,效率也高一点
nuk
2023-09-05 23:52:18 +08:00
原来是 DMA ?如果直接 mmap /dev/mem 的话,DMA 的内存区域本身就是 uncache 的,如果 dynamic DMA ,那不能直接用户态 mmap 创建 dma 内存,需要内核模块先分配 dma 内存。
liuminghao233
2023-09-06 00:07:48 +08:00
内存屏障做的是 cache 可见性同步,不能保证刷入 ram
你需要 CLFLUSH ,可以把 l1 l2 l3 的 cache 都刷掉
用 _mm_clflush 应该就可以
ryd994
2023-09-06 00:31:47 +08:00
memory barrier 只是避免编译器优化,缓存一致性仍然由 CPU 自己维护,也就无法解决 dma 的问题。
dma 是设备修改内存,CPU 无法维护缓存一致性
volatile 就是最简单的办法。

正规做法是
dma_map_single(), dma_sync_single_for_device(), dma_unmap_single(), dma_sync_single_for_cpu()
这几个 API 。合理使用的话,它们会处理 dma 一致性问题
ryd994
2023-09-06 00:34:24 +08:00
顺带一提,我用的关键字是
dma sync cpu cache

你不应该搜 Linux cache 。因为,cache 有很多种。CPU cache 也是 cache ,Page cache 也是 cache 。一般用户是不可能需要清 CPU cache 的,只有写驱动的人才需要。所以直接搜 cache ,大部分内容都是 Page cache
feather12315
2023-09-06 00:55:32 +08:00
__builtin___clear_cache

@polaa #20 这个 func
jimages
2023-09-06 01:05:05 +08:00
WBINVD 指令,不过这个执行只能在特权模式下执行,你需要看一下操作系统有没有提供这个指令的函数,比如 windows 好像提供了 https://learn.microsoft.com/en-us/cpp/intrinsics/wbinvd?view=msvc-170
linux 不太清楚
jimages
2023-09-06 01:08:46 +08:00
这个 repo 写了一个 linux 扩展,你也许可以使用 https://github.com/batmac/wbinvd/blob/master/wbinvd.c
codehz
2023-09-07 19:05:37 +08:00
@ryd994 udmabuf 是在 O_SYNC 的时候做了 dma_sync_single_for_cpu 的,所以直接 mmap 也可以了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/971217

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX