使用 vmalloc 为内核模块分配大量内存
Allocating large amount of memory to Kernel Module using vmalloc
我正在尝试使用 vmalloc()
为内核模块分配大内存。
我无法在具有 64GB 内存的 64 位 Linux (3.10.0-514.2.2.el7.x86_64) 上分配超过 2GB 的内存。
这些是相关的代码部分:
...
static int logical_block_size = 512;
module_param(logical_block_size, int, 0);
static int nsectors = 1024; /* How big the drive is */
module_param(nsectors, int, 0);
...
/*
* The internal representation of our device.
*/
static struct sbd_device {
unsigned long size;
spinlock_t lock;
u8 *data;
struct gendisk *gd;
} Device;
...
static int __init sbd_init(void) {
/*
* Set up our internal device.
*/
Device.size = nsectors * logical_block_size;
spin_lock_init(&Device.lock);
Device.data = vmalloc(Device.size);
...
可通过vmalloc
分配的内存大小是否有限制?有没有其他方法可以为内核模块分配大量内存?
在旧版本的 Linux 内核中,vmalloc()
可以分配的内存有 64 MB 的限制,但在版本 3.10.*
中,理论上它应该受到物理内存的限制。
您参考这里的代码:Simple Block Driver 在评论中,这是回答您的问题所必需的。
原因是,您正在尝试分配 16 艾字节 的数据。
sbd_init()
中的这个计算是因为:
Device.size = nsectors * logical_block_size;
Device.size 是 unsigned long
而模块参数 nsectors
和 logical_block_size
是整数。
现在,当您将 locgical_block_size 设置为 1024
并将 nsectors 设置为 2097152
(总计 space 的 2GB)时,计算结果为 有符号整数,因此结果为:
1024 * 2097152 = -2147483648
当它隐式转换为 unsigned long
(通过赋值给 Device.size)时,结果为 18446744071562067968
,然后传递给 vmalloc()
,(可能) 稍微超过了物理内存和vmalloc保留区,在linux x86_64.
上是32TB
解决方案是按unsigned long
:
进行计算
Device.size = (unsigned long) nsectors * logical_block_size;
然后它应该按预期工作。
我正在尝试使用 vmalloc()
为内核模块分配大内存。
我无法在具有 64GB 内存的 64 位 Linux (3.10.0-514.2.2.el7.x86_64) 上分配超过 2GB 的内存。
这些是相关的代码部分:
...
static int logical_block_size = 512;
module_param(logical_block_size, int, 0);
static int nsectors = 1024; /* How big the drive is */
module_param(nsectors, int, 0);
...
/*
* The internal representation of our device.
*/
static struct sbd_device {
unsigned long size;
spinlock_t lock;
u8 *data;
struct gendisk *gd;
} Device;
...
static int __init sbd_init(void) {
/*
* Set up our internal device.
*/
Device.size = nsectors * logical_block_size;
spin_lock_init(&Device.lock);
Device.data = vmalloc(Device.size);
...
可通过vmalloc
分配的内存大小是否有限制?有没有其他方法可以为内核模块分配大量内存?
在旧版本的 Linux 内核中,vmalloc()
可以分配的内存有 64 MB 的限制,但在版本 3.10.*
中,理论上它应该受到物理内存的限制。
您参考这里的代码:Simple Block Driver 在评论中,这是回答您的问题所必需的。
原因是,您正在尝试分配 16 艾字节 的数据。
sbd_init()
中的这个计算是因为:
Device.size = nsectors * logical_block_size;
Device.size 是 unsigned long
而模块参数 nsectors
和 logical_block_size
是整数。
现在,当您将 locgical_block_size 设置为 1024
并将 nsectors 设置为 2097152
(总计 space 的 2GB)时,计算结果为 有符号整数,因此结果为:
1024 * 2097152 = -2147483648
当它隐式转换为 unsigned long
(通过赋值给 Device.size)时,结果为 18446744071562067968
,然后传递给 vmalloc()
,(可能) 稍微超过了物理内存和vmalloc保留区,在linux x86_64.
解决方案是按unsigned long
:
Device.size = (unsigned long) nsectors * logical_block_size;
然后它应该按预期工作。