我正在试验linux内核模块中的内存管理,我想知道为什么线程看不到与模块功能相同的内存。我的意思是,
我在全球范围内宣布了int *x
。我使用kmalloc分配空间并为其分配10。现在,当我尝试从一个线程中访问它时,我得到一个完全不同的值。
为什么会这样?我怎么能绕过这个?
修改
我在x86架构中在单个核心(在VM上)运行我的程序。
这是我的代码:http://pastebin.com/94qGc6ZQ
答案 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)
你在运行什么架构?我不相信其他答案说你正在打击内存排序问题或缓存一致性问题,因为
kthread_run()
内部需要很多锁等等,我确信在* x的赋值和线程的开始之间存在相当的内存障碍。因此,即使在更有序的架构上,我也不认为你真的错过了内存障碍。换句话说,我认为你在问题中写的代码看起来很好。我怀疑这是从你的真实代码中剔除的,这样你就摆脱了真正的错误。
当然,如果你有代码修改 kthread_run
之后你的线程中使用的变量,那么你有一个竞争条件可能会导致像你看到的那样的错误这里。