在Linux内核中请求较大的大小时,无法从“ flex_array_alloc”分配内存

时间:2018-11-20 14:51:55

标签: c linux linux-kernel kernel kernel-module

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

我将分配一些类似于以下内容的内存空间:

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

每次尝试,ptr就是NULL

此外,当我将大小更改为20B或将num更改为256时,没有任何问题,并且可以获得内存。

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

谢谢。


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

1 个答案:

答案 0 :(得分:1)

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

  

缺点是不能直接为数组建立索引,单个对象的大小不能超过系统页面的大小,并且将数据放入灵活的数组中需要进行复制操作。

第二,数组中的元素数量最多。

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

  

…可以通过将较小部分的数组拼接在一起来消除vmalloc()对内存的需求。

     

一个灵活的数组可容纳任意数量(不超过一定数量)的固定大小的对象,这些对象可以通过整数索引进行访问。...仅进行单页分配 ...

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