在 linux 内核中请求相对较大的大小时,无法从 `flex_array_alloc` 分配内存

标签 c linux linux-kernel kernel kernel-module

我正在做一些 linux 内核开发。

我要分配一些内存空间,比如:

ptr = flex_array_alloc(size=136B, num=1<<16, GFP_KERNEL)

ptr结果是NULL每次我尝试。

另外,当我把size改成20B或者num改成256,都没有问题,可以拿到内存了。

所以我想知道在 linux 内核模块中请求内存是否有一些限制。以及如何调试它或分配大内存空间。

谢谢。


kzalloc在我的环境中有类似的行为。也就是说,请求 136B * (1<<16)空间失败,而20B1<<8成功。

最佳答案

使用 flex_array_allocate 分配的数组大小有两个限制。首先,对象大小本身不得超过一页,如 https://www.kernel.org/doc/Documentation/flexible-arrays.txt 中所示。 :

The down sides are that the arrays cannot be indexed directly, individual object size cannot exceed the system page size, and putting data into a flexible array requires a copy operation.

其次,数组中的元素个数是有上限的。

这两个限制都是实现技术的结果:

…the need for memory from vmalloc() can be eliminated by piecing together an array from smaller parts…

A flexible array holds an arbitrary (within limits) number of fixed-sized objects, accessed via an integer index.… Only single-page allocations are made

该数组通过使用指向各个部分的指针数组“拼凑”在一起,其中每个部分是一个系统页面。由于这个数组也被分配,并且只进行单页分配(如上所述),因此最大部分数略小于页面中可以容纳的指针数(略少,因为还有一些簿记数据.) 实际上,在具有 8 字节指针和 4kb 页的系统上,这将灵活数组的总大小限制为大约 2MB。 (如果对象大小不是 2 的幂,则精确限制将根据页面中浪费的空间量而有所不同。)

关于在 linux 内核中请求相对较大的大小时,无法从 `flex_array_alloc` 分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53395633/

相关文章:

c - 关于 stdio.h

c - 为什么我的缓冲区溢出尝试会出现段错误?

c - 如何找出用于构建二进制文件的 *.c 和 *.h 文件?

linux-kernel - vmware 工作站中的自定义 Linux 内核构建失败

linux-kernel - 等待队列和竞争条件

linux - 设备驱动程序 IOCTL 传递 int

c - 编译 .i 或 .ii 文件时忽略 gcc 标志 -include

c - 错误: expected expression before ‘=’ token

c - 使用 gtk c++ 更新多个进度条

linux - GNU/Debian Linux 和 LD