【发布时间】:2019-08-24 11:45:18
【问题描述】:
struct page* alloc_pages(gfp_t gfp_mask, unsigned int order) 是内核中用于分配页面的函数。所以这将分配 2^order 连续的物理页面。
所以这意味着页面将以 1、2、4、8、16 等方式分配。
如果只需要 3 页或 5 ,9 等等会怎样。
【问题讨论】:
标签: c memory-management linux-kernel
struct page* alloc_pages(gfp_t gfp_mask, unsigned int order) 是内核中用于分配页面的函数。所以这将分配 2^order 连续的物理页面。
所以这意味着页面将以 1、2、4、8、16 等方式分配。
如果只需要 3 页或 5 ,9 等等会怎样。
【问题讨论】:
标签: c memory-management linux-kernel
来自the link provided by tkausl:
顺序是要分配的两个页数的幂
所以alloc_pages(gfp_mask, 3) 将分配 8 页。 alloc_pages(gfp_mask, 4) 将分配 16 个页面,以此类推。
【讨论】:
alloc_pages 从物理内存中分配continuous page frames。 Linux 内核当然有这个坏名声。
我相信它使用的是buddy allocator。
大多数时候,您甚至不需要连续的页框。这仅在进行 DMA 传输或类似的硬件时才需要。您不太可能需要 9 个连续帧。如果你真的这样做了,你将分配 16 个页面并释放剩余的 7 个页面,例如order=0。
【讨论】:
如果您需要确切的页数,请致电alloc_pages_exact()。它采用所需的字节大小和 GFP 标志,并返回页面对齐的地址。使用传递给alloc_pages_exact() 的相同大小调用free_pages_exact() 以释放内存。
#define MY_BUF_SIZE 20000 /* size in bytes */
...
mydev->buf = alloc_pages_exact(MY_BUF_SIZE, GFP_KERNEL);
...
if (mydev->buf)
free_pages_exact(mydev->buf, MY_BUF_SIZE);
注意alloc_pages_exact()的实现如下:
alloc_page()(通过__get_free_pages())分配已确定页序的单个“复合页”,该页序由两个单页数的幂组成。split_page() 将复合页面拆分为单页。free_page()。free_pages_exact() 的实现使用指定的大小(应该与传递给 alloc_pages_exact() 的大小相匹配)来确定要释放的单个页面的数量,并释放许多连续的页面(通过调用 free_page())从指定的虚拟地址。
【讨论】: