2015-09-27 118 views
1

我有一个Linux内核模块,用于计算多个CPU(内核地址空间)中的网络数据包统计信息。我定期清除相应的内存块,强烈需要此操作对所有CPU立即生效,否则会扭曲后续的统计值。我的目标CPU是Power PC,所以它的缓存一致性非常宽松。因此,我需要在清零内存后手动刷新所有CPU的数据缓存。在Linux内核模块中刷新CPU数据缓存

所以我应该把我刚刚清理步骤之后:

memset(ptr, 0, size); 
// what's going here? 
+0

有关缓存和TLB的所有api位于[Documentation/cachetlb.txt](https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/ cachetlb.txt?id = refs/tags/v4.2.1),但我也想知道哪一个符合你的要求。 –

+1

短语'需要此操作才能立即生效所有CPU'对于多线程编程没有意义。如果统计值是某个**不变**的一部分,所有CPU都应该遵守**,则在访问它们时需要使用锁定(自旋锁,互斥锁)。在某些情况下,*原子操作*或*内存障碍*以较低的成本提供相同的保证。 Linux内核中还有许多其他的同步机制。但是,鉴于信息不足以作出适当的选择。 – Tsyvarev

+0

假设我们处于CPU X的延迟中断处理程序中。有一块内存负责累积由CPU Y(由CPU Y处理)接收到的以太网数据包的统计信息。可能这个块被复制到CPU Y数据缓存中。现在我们从CPU X中清除这个块,并且需要保证这些值(块的一部分)不会随后由CPU Y增加。我知道同步在这里是明显的想法,但对于这种情况来说太昂贵了。 – ababo

回答

0

一些深思熟虑之后,我意识到这里的问题是不是真的链接到数据缓存刷新。其实我试图避免一个平庸的竞争条件(第一个CPU清除价值,而第二个增加它)。在我的情况下,通过互斥锁保护数据的成本太高,因此值得使用原子标志通知拥有的CPU自行清除值。