【问题标题】:How can I prevent a task to be moved from a CPU to another?如何防止任务从 CPU 移动到另一个 CPU?
【发布时间】: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]);
}

问题是:如何保证

  1. cpu assignment 和 do_some_work_with 之间没有 CPU 切换?
  2. do_some_work_with() 只会在 cpu 上运行?

当时我想到的解决办法是:

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

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

提前致谢。


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

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

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

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

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

【问题讨论】:

  • 为什么您认为需要进行这种级别的控制?如果没有,你的模块有问题吗?
  • 我非常强烈地认为您的整体方法是错误的。强制内核在特定 CPU 上运行内核线程绝对是不对的。我相信你描述的方法会奏效,但似乎非常错误。
  • @MatsPetersson 我有同样的感觉......但我无法弄清楚如何在我需要运行的任务中保证平滑的 SMP。我可以编辑向您解释导致我考虑这种可怕事情的背景
  • 这可能会有所帮助 - 因为我觉得这是一个典型的 XY 问题 - 你认为正确的解决方案是做 Y 来解决 X,所以你问如何做 Y。
  • @MatsPetersson 我编辑了,你现在应该有“X”

标签: c concurrency linux-kernel


【解决方案1】:

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

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

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

【讨论】:

  • 除了两个明显的对象(分配一个新对象或只是等待现有对象可用)之外,当没有对象可供使用时,还有哪些可用策略?从我目前阅读的内容来看,如果一个任务不能移动到另一个 CPU,则不能热拔出 CPU
  • 我能想到的只有这两个。好吧,我想第三个“混合”是基于if (num_allocated_crypt_tfm < max_allocated_crypt_tfm) allocate_new_crypt_tfm(); else wait_for_available_crypt_tfm(); - 这样,您可以限制crypt_tfm 的数量,但同时不必分配很多开始。
猜你喜欢
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多