0

我目前正在构建一个内核模块,我想以一种非常理想的方式面对 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]);
}

问题是:如何保证

  1. cpu分配和do_some_work_with?之间没有 CPU 切换
  2. do_some_work_with()只会运行cpu吗?

当时,我想到的解决方案是:

  1. 使用自旋锁禁用抢占
  2. 获取 CPUsmp_processor_id
  3. 设置当前任务的处理器亲和性,使其与当前 CPU 保持一致
  4. 再次启用抢占,释放锁
  5. 做好工作do_some_work_with()
  6. 将亲和力重置为之前的状态

对我来说,这是相当野蛮的,我想知道是否有更聪明、更轻松的方法来做到这一点。

提前致谢。


编辑:如评论中所述,我编辑以解释为什么我觉得我需要这些功能。我必须在文件系统级别执行动态加密。
为此,我将使用内核内置的加密支持(struct crypto_tfm和朋友)。这是原始问题...

在多核机器上,可以同时执行多个 R/W 操作。常见的 fs 层可以做到这一点并且做得很好。但是,我来了,把事情搞砸了:

  • struct crypto_tfm对象负责加密操作
  • 不能同时使用相同的变换对象,因为某些参数会被更改(私钥和初始化向量)并破坏所有过程
  • 由于加密中内置的复杂密码分配系统,下面描述的简单解决方案完全不可能。
    1. 分配crypto_tfm转换
    2. 执行加密操作
    3. 释放转换对象
  • 只有一个转换可用的经典方案可防止多个并发 R/W 操作,因为一个任务必须等待另一个任务释放持有的锁以保护转换对象。

由于这些原因,我需要处理多个转换对象。我必须找到一个允许并发 R/W 的有效方案。我觉得我的“Y”在这里是“简单、整洁......但错误的解决方案”。任何建议将不胜感激。

注意:如果我使用类似于我在原始问题中给出的解决方案,我会将其限制在非常短的部分,以避免对 CPU 负载平衡产生重大影响。

4

1 回答 1

2

因此,根据您编辑的问题,我不得不说我认为您的解决方案是错误的。

正确的做法是有一个“每个操作” crypto_tfm,它遵循跨 CPU 的操作。在这里使用“当前 CPU”是不正确的。[如果这是在具有热插拔 CPU 的系统上运行,并且有人断开了您的任务正在运行的 CPU 的连接,并且从未将其放回原位,会发生什么?]

如果分配crypto_tfm每个操作的成本很高,那么您必须找到一些方法来避免分配/释放对象 - 拥有它们的池并为当前操作分配一个可用的对象,当操作完成时,将其放回再次可用列表。

于 2013-02-13T14:17:34.363 回答