【发布时间】:2013-02-13 13:26:42
【问题描述】:
我目前正在构建一个内核模块,我想以一种非常理想的方式来解决 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]);
}
问题是:如何保证
-
cpuassignment 和do_some_work_with之间没有 CPU 切换? -
do_some_work_with()只会在cpu上运行?
当时我想到的解决办法是:
- 使用自旋锁禁用抢占
- 用
smp_processor_id获取CPU - 设置当前任务的处理器亲和性,使其与当前 CPU 保持一致
- 再次启用抢占,释放锁
- 做好工作
do_some_work_with() - 将关联重置为之前的状态
对我来说,这是相当野蛮的,我想知道是否有更聪明、更轻松的方法来做到这一点。
提前致谢。
编辑:
正如 cmets 中所述,我编辑以解释为什么我觉得我需要这些功能。
我必须在 文件系统 级别上执行动态加密。
为此,我将使用内核内置的加密支持(struct crypto_tfm 和朋友)。这是原始问题...
在多核机器上,可以同时执行多个 R/W 操作。常见的 fs 层可以做到这一点并且做得很好。但是,我来把事情搞砸了:
- 类似
struct crypto_tfm的对象负责加密操作 - 不能同时使用相同的变换对象,因为某些参数会被更改(私钥和初始化向量)并破坏所有过程
- 由于加密中内置的复杂密码分配系统,下面描述的简单解决方案完全不可能。
- 分配
crypto_tfm转换 - 执行加密操作
- 释放转换对象
- 分配
- 只有一个转换可用的经典方案可防止多个并发 R/W 操作,因为一个任务必须等待另一个任务释放持有的锁以保护转换对象。
由于这些原因,我需要处理多个转换对象。我必须找到一个允许并发 R/W 的有效方案。我觉得我的“Y”在这里是“简单、整洁......但错误的解决方案”。 任何建议将不胜感激。
注意:如果我使用我在原始问题中给出的解决方案,我会将其限制在非常短的部分,以避免对 CPU 负载平衡产生重大影响。
【问题讨论】:
-
为什么您认为需要进行这种级别的控制?如果没有,你的模块有问题吗?
-
我非常强烈地认为您的整体方法是错误的。强制内核在特定 CPU 上运行内核线程绝对是不对的。我相信你描述的方法会奏效,但似乎非常错误。
-
@MatsPetersson 我有同样的感觉......但我无法弄清楚如何在我需要运行的任务中保证平滑的 SMP。我可以编辑向您解释导致我考虑这种可怕事情的背景
-
这可能会有所帮助 - 因为我觉得这是一个典型的 XY 问题 - 你认为正确的解决方案是做 Y 来解决 X,所以你问如何做 Y。
-
@MatsPetersson 我编辑了,你现在应该有“X”
标签: c concurrency linux-kernel