如何获得;“mm信号灯”;在C中?
如果您想在实现mmap的自定义内核驱动程序中使用如何获得;“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。请注意,这也是[可能]当
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
也可能有用: