Skip to content

Commit daf60d6

Browse files
gaomingnamjaejeon
authored andcommitted
exfat: use kvmalloc_array/kvfree instead of kmalloc_array/kfree
The call stack shown below is a scenario in the Linux 4.19 kernel. Allocating memory failed where exfat fs use kmalloc_array due to system memory fragmentation, while the u-disk was inserted without recognition. Devices such as u-disk using the exfat file system are pluggable and may be insert into the system at any time. However, long-term running systems cannot guarantee the continuity of physical memory. Therefore, it's necessary to address this issue. Binder:2632_6: page allocation failure: order:4, mode:0x6040c0(GFP_KERNEL|__GFP_COMP), nodemask=(null) Call trace: [242178.097582] dump_backtrace+0x0/0x4 [242178.097589] dump_stack+0xf4/0x134 [242178.097598] warn_alloc+0xd8/0x144 [242178.097603] __alloc_pages_nodemask+0x1364/0x1384 [242178.097608] kmalloc_order+0x2c/0x510 [242178.097612] kmalloc_order_trace+0x40/0x16c [242178.097618] __kmalloc+0x360/0x408 [242178.097624] load_alloc_bitmap+0x160/0x284 [242178.097628] exfat_fill_super+0xa3c/0xe7c [242178.097635] mount_bdev+0x2e8/0x3a0 [242178.097638] exfat_fs_mount+0x40/0x50 [242178.097643] mount_fs+0x138/0x2e8 [242178.097649] vfs_kern_mount+0x90/0x270 [242178.097655] do_mount+0x798/0x173c [242178.097659] ksys_mount+0x114/0x1ac [242178.097665] __arm64_sys_mount+0x24/0x34 [242178.097671] el0_svc_common+0xb8/0x1b8 [242178.097676] el0_svc_handler+0x74/0x90 [242178.097681] el0_svc+0x8/0x340 By analyzing the exfat code,we found that continuous physical memory is not required here,so kvmalloc_array is used can solve this problem. Cc: [email protected] Signed-off-by: gaoming <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent 06c2afb commit daf60d6

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

fs/exfat/balloc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static int exfat_allocate_bitmap(struct super_block *sb,
6969
}
7070
sbi->map_sectors = ((need_map_size - 1) >>
7171
(sb->s_blocksize_bits)) + 1;
72-
sbi->vol_amap = kmalloc_array(sbi->map_sectors,
72+
sbi->vol_amap = kvmalloc_array(sbi->map_sectors,
7373
sizeof(struct buffer_head *), GFP_KERNEL);
7474
if (!sbi->vol_amap)
7575
return -ENOMEM;
@@ -84,7 +84,7 @@ static int exfat_allocate_bitmap(struct super_block *sb,
8484
while (j < i)
8585
brelse(sbi->vol_amap[j++]);
8686

87-
kfree(sbi->vol_amap);
87+
kvfree(sbi->vol_amap);
8888
sbi->vol_amap = NULL;
8989
return -EIO;
9090
}
@@ -138,7 +138,7 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
138138
for (i = 0; i < sbi->map_sectors; i++)
139139
__brelse(sbi->vol_amap[i]);
140140

141-
kfree(sbi->vol_amap);
141+
kvfree(sbi->vol_amap);
142142
}
143143

144144
int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync)

0 commit comments

Comments
 (0)