在Linux内核中的指定地址分配内存块

时间:2021-05-13 16:55:26

Is there a way in the Linux kernel to allocate a chunk of memory and specify that it needs to be at a specified virtual address?

Linux内核中是否有一种方法可以分配一块内存并指定它需要位于指定的虚拟地址?

I realize this may not always be possible, as that chunk of memory may not be available. But if that chunk happens to be available, is there a way for me to claim it?

我意识到这可能并不总是可能的,因为那块内存可能无法使用。但是,如果那个大块好可用,有没有办法让我声称它?

I am asking this because I want to allocate a small chunk of memory at first, and if needed, increase its size without having to allocate another larger chunk of memory and copy everything over.

我问这个是因为我想首先分配一小块内存,如果需要,增加它的大小,而不必分配另一个更大的内存块并复制一切。

Edit:

编辑:

As someone pointed one, at the user space, realloc() does exactly what I need. But is there an equivalent in kernel space?

正如有人指出的那样,在用户空间,realloc()正是我所需要的。但内核空间是否有相同的内容?

1 个解决方案

#1


1  

See man mremap() for the mechanism that realloc() uses. The mechanisms to implement this are in the kernel. See mremap.c. mremap() attempts to setup adjacent memory for user space so that a range maybe grown. It may not apply well to kernel space.

有关realloc()使用的机制,请参阅man mremap()。实现它的机制在内核中。见mremap.c。 mremap()尝试为用户空间设置相邻内存,以便可以增加范围。它可能不适用于内核空间。

You can request a region of virtual address space and also request it at a specific address. See vmap() at LWN. All that remains is to assign some physical pages to this virtual addresses.

您可以请求虚拟地址空间区域,也可以在特定地址请求它。请参阅LWN的vmap()。剩下的就是为这个虚拟地址分配一些物理页面。

kmalloc() works at the page level and then provides binning within pages (via SLAB, SLUB, etc). See kmalloc size allocation‌​. In your case, you can not share the page so others can use it. If you grow the region and someone else uses it, then you have to move the memory.

kmalloc()在页面级别工作,然后在页面内提供分箱(通过SLAB,SLUB等)。请参阅kmalloc大小分配。在您的情况下,您无法共享该页面,以便其他人可以使用它。如果你在该地区发展并且其他人使用它,那么你必须移动内存。

See do_krealloc() for the moving. If your total size is small, then you can use krealloc(). If they are large (>16k), then you should be using vmap() or use the alternate interface of vfs_writev() instead of vfs_write(). Note that even sizes of 16k may fail as system memory gets fragmented. This is why people generally use only a page as it can never get fragmented.

请参阅do_krealloc()以了解移动情况。如果您的总大小很小,那么您可以使用krealloc()。如果它们很大(> 16k),那么您应该使用vmap()或使用vfs_writev()的备用接口而不是vfs_write()。请注意,即使16k的大小也可能因系统内存碎片而失败。这就是为什么人们通常只使用一个页面,因为它永远不会碎片化。

#1


1  

See man mremap() for the mechanism that realloc() uses. The mechanisms to implement this are in the kernel. See mremap.c. mremap() attempts to setup adjacent memory for user space so that a range maybe grown. It may not apply well to kernel space.

有关realloc()使用的机制,请参阅man mremap()。实现它的机制在内核中。见mremap.c。 mremap()尝试为用户空间设置相邻内存,以便可以增加范围。它可能不适用于内核空间。

You can request a region of virtual address space and also request it at a specific address. See vmap() at LWN. All that remains is to assign some physical pages to this virtual addresses.

您可以请求虚拟地址空间区域,也可以在特定地址请求它。请参阅LWN的vmap()。剩下的就是为这个虚拟地址分配一些物理页面。

kmalloc() works at the page level and then provides binning within pages (via SLAB, SLUB, etc). See kmalloc size allocation‌​. In your case, you can not share the page so others can use it. If you grow the region and someone else uses it, then you have to move the memory.

kmalloc()在页面级别工作,然后在页面内提供分箱(通过SLAB,SLUB等)。请参阅kmalloc大小分配。在您的情况下,您无法共享该页面,以便其他人可以使用它。如果你在该地区发展并且其他人使用它,那么你必须移动内存。

See do_krealloc() for the moving. If your total size is small, then you can use krealloc(). If they are large (>16k), then you should be using vmap() or use the alternate interface of vfs_writev() instead of vfs_write(). Note that even sizes of 16k may fail as system memory gets fragmented. This is why people generally use only a page as it can never get fragmented.

请参阅do_krealloc()以了解移动情况。如果您的总大小很小,那么您可以使用krealloc()。如果它们很大(> 16k),那么您应该使用vmap()或使用vfs_writev()的备用接口而不是vfs_write()。请注意,即使16k的大小也可能因系统内存碎片而失败。这就是为什么人们通常只使用一个页面,因为它永远不会碎片化。