如何获得;“mm信号灯”;在C中?

如何获得;“mm信号灯”;在C中?,c,linux-kernel,C,Linux Kernel,如果您想在实现mmap的自定义内核驱动程序中使用remap\u pfn\u range函数,您知道必须获取“mm信号量”。但从我可以找到的公开例子来看,不清楚如何做到这一点。我认为编辑可用的示例对社区有益,我愿意这样做,但我不知道从哪里开始 根据:只有在调用时保持mm信号量时,这才是安全的。查看实际源[对于重新映射pfn\u范围]。这在mm子目录中,特别是mm/memory.c 在那里你会看到structmm_struct*mm=vma->vm_-mm这就是你想要的mm。请注意,这也是[可能]当

如果您想在实现mmap的自定义内核驱动程序中使用
remap\u pfn\u range
函数,您知道必须获取“mm信号量”。但从我可以找到的公开例子来看,不清楚如何做到这一点。我认为编辑可用的示例对社区有益,我愿意这样做,但我不知道从哪里开始


根据:只有在调用时保持mm信号量时,这才是安全的。

查看实际源[对于
重新映射pfn\u范围
]。这在
mm
子目录中,特别是
mm/memory.c

在那里你会看到
structmm_struct*mm=vma->vm_-mm这就是你想要的
mm
。请注意,这也是[可能]
当前->mm

如果您在那里查看更多的文件[特别是
mm/mmap.c
],您将看到
down\u write(&mm->mmap\u sem)
up\u write(&mm->mmap\u sem)
[这是内核的信号量原语]。请注意,如果您只需要从该区域读取,则有
down\u read
up\u read

所以,把这一切放在一起:

void
myfnc(...)
{
    struct vm_area_struct *vma = ...;
    struct mm_struct *mm = vma->vm_mm;

    ...

    down_write(&mm->mmap_sem);
    remap_pfn_range(vma,...);
    up_write(&mm->mmap_sem);

    ...
}

撇开文档不谈,找到这些东西的最佳方法之一是查看源代码本身。我已经编写linux内核/驱动程序代码20多年了,当我需要查找一些我不知道的东西时,我会这样做。

首先,我对linux一点也不了解:),我不知道为什么我要搜索你:)

以下是我的发现:

1-mm表示15.1.7下的内存映射。进程内存映射标题:

内存管理难题的最后一块是进程内存映射结构,它将所有其他数据结构放在一起。系统中的每个进程(除了几个内核空间助手线程)都有一个struct mm_struct(在中定义),其中包含进程的虚拟内存区域列表、页表和各种其他内存管理内务管理信息,以及一个信号量(mmap_sem)和一个自旋锁(page_table_lock)。指向此结构的指针位于任务结构中;在极少数情况下,驱动程序需要访问它,通常的方法是使用current->mm。注意,内存管理结构可以在进程之间共享;例如,线程的Linux实现就是这样工作的

2.
mm_结构
定义为:

struct mm_struct {
    int count;
    pgd_t * pgd;
    unsigned long context;
    unsigned long start_code, end_code, start_data, end_data;
    unsigned long start_brk, brk, start_stack, start_mmap;
    unsigned long arg_start, arg_end, env_start, env_end;
    unsigned long rss, total_vm, locked_vm;
    unsigned long def_flags;
    struct vm_area_struct * mmap;
    struct vm_area_struct * mmap_avl;
    struct semaphore mmap_sem; /**this what you are looking for**/
};
3-最后,还有一些锁定和解锁(向下写入和向上写入)mmap_sem属性的示例

我不得不再次承认,我真的不明白发生了什么:)不知何故,我想找到一个解决办法

希望有帮助,
戈汗

为了补充Craig的答案,从Linux 5.8开始,VMA锁更改为
mmap\u锁
。您必须执行以下操作:

down_write(&mm->mmap_lock);
remap_pfn_range...
up_write(&mm->mmap_lock);
此外,正在开发一套新的API:

此VMA锁在Linux社区中是一个有争议的问题:

谢谢!我想就是这样。我不知道函数的实际定义在哪里。我去了lxr并点击了标识符搜索,但那带来了无数的文件。谢谢你的提示,见鬼,当别人环顾四周时,它会帮助他们。另外,现在我可以改进现有的开源示例了!:不客气!稍后我会尝试用我的一些技巧更新我的答案。但是,这里有一个简单的。在最上面的内核目录中执行:
ctags-R
[注意:它有很多选项]。这将创建一个文件
标签
。现在您可以执行:
vi-t重新映射pfn\u范围
。一旦你有了
标签
文件,在
vi
中你可以做:
:ta remap\u pfn\u range
[或任何符号]。如果vi的
:help ta
不起作用,请执行
zless/usr/share/vim/vim74/doc/tagsrch.txt.gz
。虽然我自己没有使用过,
cscope
也可能有用: