btrfs: Switch memory allocations in async csum calculation path to kvmalloc
authorNikolay Borisov <nborisov@suse.com>
Mon, 1 Apr 2019 08:29:58 +0000 (11:29 +0300)
committerDavid Sterba <dsterba@suse.com>
Thu, 25 Apr 2019 12:17:38 +0000 (14:17 +0200)
commita3d46aea46f99d134b4e0726e4826b824c3e5980
tree17e3d7820b40192b8e45c7a302c449894fe9b107
parent272e5326c7837697882ce3162029ba893059b616
btrfs: Switch memory allocations in async csum calculation path to kvmalloc

Recent multi-page biovec rework allowed creation of bios that can span
large regions - up to 128 megabytes in the case of btrfs. OTOH btrfs'
submission path currently allocates a contiguous array to store the
checksums for every bio submitted. This means we can request up to
(128mb / BTRFS_SECTOR_SIZE) * 4 bytes + 32bytes of memory from kmalloc.
On busy systems with possibly fragmented memory said kmalloc can fail
which will trigger BUG_ON due to improper error handling IO submission
context in btrfs.

Until error handling is improved or bios in btrfs limited to a more
manageable size (e.g. 1m) let's use kvmalloc to fallback to vmalloc for
such large allocations. There is no hard requirement that the memory
allocated for checksums during IO submission has to be contiguous, but
this is a simple fix that does not require several non-contiguous
allocations.

For small writes this is unlikely to have any visible effect since
kmalloc will still satisfy allocation requests as usual. For larger
requests the code will just fallback to vmalloc.

We've performed evaluation on several workload types and there was no
significant difference kmalloc vs kvmalloc.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/file-item.c
fs/btrfs/ordered-data.c