0

我需要get_user_pages_fast()从内核线程调用。但是在内部get_user_pages_fast()使用current->mm,它设置为NULL用于内核线程。有没有办法解决这个问题?有问题的内核线程正在代表另一个进程工作,比如说x,设置并调用是否x->mm可以?current->mmget_user_pages_fast()

[编辑 1]:我验证了这一点,它似乎正在工作。我仍然担心它是否会在某些情况下破裂。欢迎任何见解。谢谢。

4

2 回答 2

2

您的“hack”确实会起作用,但让我们退后一步,了解它的想法是什么:

当您在内核线程中时,(我说的是纯内核线程(kthreadd 的子线程),而不是在内核模式下执行的用户线程,就像服务系统调用的情况一样),没有用户内存可以谈到。这就是 current->mm 为空的原因:没有“当前”用户空间内存。

当您将 current->mm 分配给 x->mm 时,您通过将无辜 x 的进程内存空间合并为您自己的来“作弊”。因此,您执行的任何分配都将计入 x,并且对 x 可见(毕竟,它是其内存空间的一部分)。此外,可能存在对 current->mm 的内部内核检查,这可能会被欺骗,导致内核将内核模式线程视为用户模式线程(尽管可以说其他检查依赖于 KERNEL_DS/USER_DS,这你没有修改)。仍然,一个担忧。如果 x 死了,这将中断(嘿-没有人是不朽的),并且可能会导致 oops,如果不是完全恐慌的话。

您还没有说为什么需要获取用户页面-如果情况是您知道 x 还活着并且您正在这样做作为 IPC/shmem 的一部分,我可以看到其中的原因。如果是这种情况,您可能希望为相关进程提供一些 API 以向内核线程“注册”。否则,您的解决方案可以工作,但是......好吧,没有它可能的那么整洁。

于 2013-04-23T14:34:53.437 回答
1

我不相信这是完全安全的。_fast部分get_user_pages_fast意味着不需要获取,mm->mmap_sem部分原因是因为假设我们在进程本身内运行(例如,current->mm不能完全消失)。由于您在另一个线程中运行,因此如果真正的进程曾经做过一些改变其映射的事情,那么您很容易受到竞争的影响。

I guess the question is why can't you just use get_user_pages instead?

于 2013-04-23T17:15:43.700 回答