简体   繁体   English

从内核线程为用户空间分配内存

[英]Allocating memory for user space from kernel thread

My question is about passing data from kernel to a user space program.我的问题是关于将数据从内核传递到用户空间程序。 I want to implement a system call "get_data(size, char *buff, char **meta_buf)".我想实现一个系统调用“get_data(size, char *buff, char **meta_buf)”。 In this call, buff is allocated by user space program and its length is passed in the size argument.在这个调用中, buff 由用户空间程序分配,其长度在 size 参数中传递。 However, meta_buf is a variable length buffer that is allocated (in the user space program's vm pages) and filled by kernel.然而,meta_buf 是一个可变长度的缓冲区,由内核分配(在用户空间程序的 vm 页中)并填充。 User space program will free this region.用户空间程序将释放该区域。

(I cant allocate data in user space as user space program does not know size of the meta_buff. Also, user space program cannot allocate a fixed amount of memory and call the system call again and again to read the entire meta data. meta_data has to be returned in one single system call) (我不能在用户空间分配数据,因为用户空间程序不知道 meta_buff 的大小。另外,用户空间程序不能分配固定数量的内存并一遍又一遍地调用系统调用来读取整个元数据。meta_data 必须在一个系统调用中返回)

  1. How do I allocate memory for a user space program from kernel thread?如何从内核线程为用户空间程序分配内存? (I would even appreciate if you can point me to any other system call that does a similar operation - allocating in kernel and freeing in user space) (如果您能指出任何其他执行类似操作的系统调用 - 在内核中分配并在用户空间中释放,我什至会很感激)
  2. Is this interface right or is there a better way to do it?这个界面是正确的还是有更好的方法来做到这一点?

Don't attempt to allocate memory for userspace from the kernel - this is a huge violation of the kernel's abstraction layering. 不要试图从内核为用户空间分配内存 - 这严重违反了内核的抽象分层。 Instead, consider a few other options: 相反,请考虑其他一些选项:

  • Have userspace ask how much space it needs. 让用户空间询问它需要多少空间。 Userspace allocates, then grabs the memory from the kernel. 用户空间分配,然后从内核中获取内存。
  • Have userspace mmap pages owned by your driver directly into its address space. 将驱动程序拥有的用户空间mmap页面直接放入其地址空间。
  • Set an upper bound on the amount of data needed. 设置所需数据量的上限。 Just allocate that much. 只需分配那么多。

It's hard to say more without knowing why this has to be atomic. 如果不知道为什么这必须是原子的,就很难说更多。 Actually allocating memory's going to need to be interruptible anyway (or you're unlikely to succeed), so it's unlikely that going out of and back into the kernel is going to hurt much. 实际上,分配内存无论如何都需要中断(或者你不太可能成功),因此不太可能走出内核并重新受到伤害。 In fact, any write to userspace memory must be interruptible, as there's the potential for page faults requiring IO. 事实上, 任何对用户空间内存的写入都必须是可中断的,因为存在需要IO的页面错误的可能性。

  1. Call vm_mmap() to get a address in user space.调用 vm_mmap() 以获取用户空间中的地址。
  2. Call find_vma() to find the vma corresponding to this address.调用 find_vma() 找到这个地址对应的 vma。
  3. Call virt_to_phys() to get the physical address of kernel memory.调用 virt_to_phys() 获取内核内存的物理地址。
  4. Call remap_pfn_range() map the physical address to the vma.调用 remap_pfn_range() 将物理地址映射到 vma。

There is a point to take care, that is, the mapped address should be aligned to one page size.有一点需要注意,就是映射的地址应该与一个页面大小对齐。 If not, you should ajust it, and add the offset after you get the user space address.如果不是,你应该调整它,并在获得用户空间地址后添加偏移量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM