我目前正在构建内核模块,我想以一种非常优化的方式面对SMP问题。
目前,我有一组对象,每个对象都绑定到一个特定的CPU。以下代码说明了这一点:
struct my_object {
int a_field;
};
struct my_object cpu_object[NR_CPUS];
/*
* cpu_object[i] is "bound" to CPU number "i" !
*/
对smp_processor_id()
的简单调用将为我提供运行当前代码的处理器。所以如果我有一个函数foo
使用上面描述的CPU绑定对象做一些工作,它可能看起来像:
void foo()
{
int cpu = smp_processor_id();
do_some_work_with(cpu_object[cpu]);
}
问题是:如何保证
cpu
分配与do_some_work_with
之间没有CPU切换?do_some_work_with()
只能在cpu
?当时,我想到的解决方案是:
smp_processor_id
do_some_work_with()
对我而言,这是非常野蛮的,我想知道是否有更聪明,更轻松的方式。
提前致谢。
编辑:
正如评论中所述,我编辑解释为什么我觉得我需要这些功能。
我必须在文件系统级别上执行动态加密
为此,我将使用内核内置加密支持(struct crypto_tfm
和朋友)。这是原始问题......
在多核计算机上,可以同时执行多个R / W操作。常见的fs层可以做到并做得很好。但是,我来这里搞砸了:
struct crypto_tfm
的对象负责加密操作crypto_tfm
转化由于这些原因,我需要处理多个转换对象。我必须找到一个允许并发R / W的有效方案。我觉得我的“Y”是“简单,整洁......错误的解决方案”。 任何建议都会非常感激。
注意:如果我使用的解决方案与我在原始问题中提供的解决方案类似,我会将其限制为非常短的部分,以避免对CPU负载平衡造成严重影响。
答案 0 :(得分:2)
因此,根据您编辑过的问题,我不得不说我认为您的解决方案是错误的。
正确的做法是拥有一个“每个操作”crypto_tfm
,它遵循跨越CPU的操作。使用“当前CPU”在这里不是正确的事情。 [如果这个系统在具有热插拔CPU的系统上运行,并且有人断开了您的任务正在运行的CPU,并且从不将其放回原位,会发生什么?]
如果为每个操作分配crypto_tfm
代价很高,那么你必须找到一些方法来避免分配/释放对象 - 拥有它们的池并为当前操作分配可用的,以及何时操作完成后,再次将其重新放回可用列表中。