linux内核模块内存管理

时间:2011-10-02 21:51:34

标签: memory-management linux-kernel kernel-module

我正在试验linux内核模块中的内存管理,我想知道为什么线程看不到与模块功能相同的内存。我的意思是,

我在全球范围内宣布了int *x。我使用kmalloc分配空间并为其分配10。现在,当我尝试从一个线程中访问它时,我得到一个完全不同的值。

为什么会这样?我怎么能绕过这个?

修改

我在x86架构中在单个核心(在VM上)运行我的程序。

这是我的代码:http://pastebin.com/94qGc6ZQ

3 个答案:

答案 0 :(得分:2)

在SMP体系结构上,缓存的值不会在所有核心上更新,因此另一个核心上的线程可能使用陈旧值。

你可以拥有的另一个问题是线程之间的并发访问,这意味着线程1在线程2能够写入x之前读取x但线程2继续并且表示x = 10但是当x未初始化时,线程1仍然使用旧值。 / p>

解决第二个问题(似乎更有可能)的方法是使用锁来控制对该变量的访问,这样一次只有1个线程可以修改/读取它,以避免出现过时值。

(不是硬件内核模块所以不要使用volatile; P)使用下面的smp_wb和smp_rb建议。

编辑:看起来我的第一个建议是正确的。因此,要解决此问题,您可以在执行kmalloc和赋值之前在x上使用smp_wb。然后在尝试打印x的值之前在x上读取屏障。这有效地告诉CPU读取新值,因为它可能是坏的或者可能在访问中被重新排序。您可以在另一个线程上使用读屏障,但是为了安全使用可以访问的障碍。

答案 1 :(得分:2)

您需要某种锁(以及使缓存无效的内存屏障。)

在SMP内核上,有一些锁定机制(针对内核)负责处理:

阅读http://www.mjmwired.net/kernel/Documentation/memory-barriers.txt 尤其是“CPU间锁定屏障效应”

答案 2 :(得分:1)

你在运行什么架构?我不相信其他答案说你正在打击内存排序问题或缓存一致性问题,因为

  • x86的排序非常强,kthread_run()内部需要很多锁等等,我确信在* x的赋值和线程的开始之间存在相当的内存障碍。因此,即使在更有序的架构上,我也不认为你真的错过了内存障碍。
  • 我不相信有任何架构,其中Linux运行在CPU之间是高速缓存不连贯的。您必须小心将DMA作为内存的外部设备,但这与此处的问题完全不同。

换句话说,我认为你在问题中写的代码看起来很好。我怀疑这是从你的真实代码中剔除的,这样你就摆脱了真正的错误。

当然,如果你有代码修改 kthread_run之后你的线程中使用的变量,那么你有一个竞争条件可能会导致像你看到的那样的错误这里。