在Linux上设置zram设备磁盘大小是否有任何限制?

时间:2018-06-19 06:56:03

标签: linux testing memory linux-kernel

我正在尝试在目标设备上创建zram设备。如果zram disksize超过100GB,我的目标无法分配内存,但是对于50GB或更小的磁盘大小,它是可以的。

在Linux上设置zram设备磁盘大小是否有限制?我的目标设备只有2GB的RAM内存。

2 个答案:

答案 0 :(得分:0)

我想你可以在64位平台上给出UINT64_MAX - 4095 = 18446744073709547520的数字。

https://github.com/torvalds/linux/blob/master/drivers/block/zram/zram_drv.h#L101 https://github.com/torvalds/linux/blob/master/drivers/block/zram/zram_drv.c#L1506 https://github.com/torvalds/linux/blob/master/drivers/block/zram/zram_drv.c#L901

所以我们拥有:

... disksize_store(...) {
    u64 disksize;
    ...
    // ok, we can give at least UINT64_MAX here.
    disksize = unsigned long long memparse(...);
    // PAGE_ALIGN, PAGE_SIZE = 1<<12
    disksize = PAGE_ALIGN(disksize) 
             = (((disksize)+((PAGE_SIZE)-1))&(~((typeof(disksize))(PAGE_SIZE)-1))) 
             = (disksize + ((1<<12)-1))&(~((1<<12)-1)) 
             = (disksize + 4095) & 0xfffffffffffff000
             // ^^^^^^^^^^^^^^^ this can overflow
    // so max number is UINT64_MAX - 4095 so it doesn't overflow
    // otherwise this macro will return 0
    ...
    if (!zram_meta_alloc(..., disksize) {
        ...
        return ...;
    }
    ...
    zram->disksize = disksize;
    ...
}

所以让我们看看zram_meta_alloc:

 ... zram_meta_alloc(..., disksize) {
       ...
       num_pages = disksize >> PAGE_SHIFT; 
       // max num_pages = 0xfffffffffffff = UINT64_MAX >> PAGE_SHIFT
       ... = vzalloc(num_pages * sizeof(*zram->table));
       //                ^^^^^^^^^^^^^^^ this can overflow
       ...
 }

vzallloc将unsigned long作为参数。 ULONG_MAX应该是64位平台上的UINT64_MAX。 sizeof(*zram->table)等于sizeof(unsigned long) + sizeof(unsigned long) + [optional: + sizeof(ktime_t)] + padding(请参阅here)。如果没有填充,假设64位平台sizeof(unsigned long) = 8应该等于8+8[+8] = 16 or 24。但无论如何,最大num_pages等于UINT64_MAX >> 12,所以要在64位乘法上溢出它,我们需要sizeof(*zram->table) = 2^PAGE_SIZE = 4096,这不应该发生(除非编译器决定提供超过4000字节的填充进入zram-&gt;表结构)。所以我们留下了UINT64_MAX - 4095 所以我们离开了,磁盘大小的最大数量为UINT64_MAX-4095。如果你给的磁盘大小等于UINT64_MAX - x,那么0 <= x < 4095,而不是因为PAGE_ALIGN宏,磁盘大小将被有效地设置为0.可能这应该由内核开发人员提供,他们应该修改PAGE_ALIGN宏来支持这些数字。
6天前,为了防止this commit出现溢出,vzalloc调用了array_size

答案 1 :(得分:0)

没有限制,但有开销。

“请注意,当不使用zram时,其占用的磁盘大小约为磁盘大小的0.1%,因此,巨大的zram是浪费的。” https://www.kernel.org/doc/Documentation/blockdev/zram.txt

disk_size也是一个虚拟大小,它完全取决于输入和通过选择的算法接收的压缩率。磁盘大小是最大未压缩大小和常规磁盘参数。 唯一的“实际”控制是通过mem_limit进行的,即压缩大小+磁盘和zram开销。

压缩比完全取决于从/ proc / crypto中选择的comp alg,因为zlib和zstd的效果要好得多,但要慢得多。它也非常依赖于输入,因为文本zlib和zstd可能是lzo和lz4所能达到的两倍。 如果输入已经被压缩,那么任何算法都可能几乎没有压缩到零压缩,而没有mem_limit可能会从系统中抢占很多宝贵的内存。

Mem_limit是zram准备从系统中获取的最大值,并且磁盘大小超过预期应用于mem_limit的压缩比可能会浪费。 它永远不会被使用,而只是0.1%的空白创建开销的一部分。

也许尝试https://github.com/StuartIanNaylor/zram-config