我正在做一些Linux内核开发。
我将分配一些类似于以下内容的内存空间:
ptr = flex_array_alloc(size=136B, num=1<<16, GFP_KERNEL)
每次尝试,ptr
就是NULL
。
此外,当我将大小更改为20B或将num更改为256时,没有任何问题,并且可以获得内存。
所以我想知道在Linux内核模块中请求内存是否有一些限制。以及如何调试它或分配大的内存空间。
谢谢。
在我的环境中,kzalloc
有类似的行为。也就是说,请求136B * (1<<16)
空间失败,而20B
或1<<8
成功。
答案 0 :(得分:1)
用flex_array_allocate
分配的数组的大小有两个限制。首先,对象大小本身不能超过一页,如https://www.kernel.org/doc/Documentation/flexible-arrays.txt所示:
缺点是不能直接为数组建立索引,单个对象的大小不能超过系统页面的大小,并且将数据放入灵活的数组中需要进行复制操作。
第二,数组中的元素数量最多。
这两种限制都是实现技术的结果:
…可以通过将较小部分的数组拼接在一起来消除
vmalloc()
对内存的需求。一个灵活的数组可容纳任意数量(不超过一定数量)的固定大小的对象,这些对象可以通过整数索引进行访问。...仅进行单页分配 ...
通过使用指向各个部分的指针数组将数组“组合”在一起,其中每个部分都是一个系统页面。由于还分配了此数组,并且仅进行了单页分配(如上所述),因此最大部分数比页面中可以容纳的指针数略少(由于包含一些簿记数据,因此略少) 。)实际上,这在具有8字节指针和4kb页面的系统上将灵活数组的总大小限制为大约2MB。 (如果对象大小不是2的幂,则精确限制将根据页面中浪费的空间量而变化。)