【问题标题】:Allocating large amount of memory to Kernel Module using vmalloc使用vmalloc为内核模块分配大量内存
【发布时间】:2017-05-30 10:29:28
【问题描述】:

我正在尝试使用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 分配的内存大小是否有限制?还有其他方法可以为内核模块分配大量内存吗?

【问题讨论】:

  • 理论上,限制应该是 32TB 或物理上可用的 ram,无论哪个先出现;) 在尝试分配它时,您是否从内核收到一些消息?
  • 告诉我们你是如何使用vmalloc()的。
  • 在内核模块中分配 2GiB RAM 听起来是个非常糟糕的主意。看起来像 XY 问题。
  • @Olaf Mind 详细说明为什么这是一个坏主意?我倾向于认为,这取决于应用程序并且找不到论据,为什么不应该有正当理由。
  • @Ctx:因为数据量必须以某种方式传递给应用程序。那么为什么不根据需要在用户空间动态分配内存并传递给内核呢?使用如此大的单个块的一个原因是在一个大而臃肿的内核模块中处理所有事情——这通常是混合不同功能的糟糕概念。只是要明确一点:我并没有说这总是一个坏主意。但从提出的问题来看,我几乎可以肯定它适用于任何 OP 的意图。

标签: c linux-kernel kernel-module


【解决方案1】:

您在这里参考代码:cmets 中的Simple Block Driver,这是回答您的问题所必需的。

原因是,您正在尝试分配 16 艾字节 的数据。 sbd_init()中的这个计算是原因:

Device.size = nsectors * logical_block_size;

Device.size 是unsigned long,而模块参数nsectorslogical_block_size 是整数。

现在,当您将 locgical_block_size 设置为 1024 并将 nsectors 设置为 2097152(总计 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;

然后它应该按预期工作。

【讨论】:

    【解决方案2】:

    在旧版本的 Linux 内核中,vmalloc() 可以分配的内存有 64 MB 的限制,但在版本 3.10.* 中,理论上它应该受到物理内存的限制。

    【讨论】:

    • 这应该是一个注释,因为它并不能真正帮助解决 OPs 问题
    • @Ctx:这回答关于提问者的一个问题 - Is there a limitation to the size of memory that can be allocated via vmalloc? 所以可以是一个回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2016-02-13
    • 2019-08-10
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多