我正试图在目标设备上创建一个zram设备。如果zram磁盘大小大于100GB,我的目标无法分配内存,但磁盘大小小于等于50GB是可以的。
在Linux上设置zram设备磁盘大小有限制吗?我的目标设备只有2GB的内存。

最佳答案

我想您可以在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
       ...
 }

vzalloc接受无符号long作为参数。在64位平台上,ULONG_MAX应为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。但是无论如何,最大NUMPEPAGE等于UINT64_MAX >> 12,所以要在64位乘法上溢出它,我们就需要sizeof(*zram->table) = 2^PAGE_SIZE = 4096,并且这不应该发生(除非编译器决定将4000字节的填充添加到ZRAM ->表结构中)。所以我们剩下的是UINT64_MAX-4095。
所以我们剩下的,最大的磁盘大小是UINT64_MAX-4095。如果给定的disksize等于UINT64_MAX - x,其中0 <= x < 4095,而不是由于PAGE_ALIGN宏,则disksize将有效地设置为0。可能这应该提交给内核开发人员,他们应该修改PAGE_ALIGN宏来支持这些数字。
6天前,对vzalloc调用添加了对array_size的调用,以防止this commit溢出。

10-04 21:55