如何防止将任务从CPU移动到另一个?

时间:2013-02-13 13:26:42

标签: c concurrency linux-kernel

我目前正在构建内核模块,我想以一种非常优化的方式面对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
  3. 上投放

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

    1. 使用spinlock禁用抢占
    2. 使用smp_processor_id
    3. 获取CPU
    4. 设置当前任务的处理器关联,使其与当前CPU保持一致
    5. 再次启用抢占,释放锁定
    6. 完成工作do_some_work_with()
    7. 将亲和力重置为之前的状态
    8. 对我而言,这是非常野蛮的,我想知道是否有更聪明,更轻松的方式。

      提前致谢。


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

      在多核计算机上,可以同时执行多个R / W操作。常见的fs层可以做到并做得很好。但是,我来这里搞砸了:

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

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

      注意:如果我使用的解决方案与我在原始问题中提供的解决方案类似,我会将其限制为非常短的部分,以避免对CPU负载平衡造成严重影响。

1 个答案:

答案 0 :(得分:2)

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

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

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