btrfs: use kvmalloc() for b-tree split_item()
[BUG]
There is a bug report that the kmalloc() call inside split_item() failed
with the following call trace, and triggered a transaction abort:
kworker/u69:8: page allocation failure: order:4, mode:0x40c40(GFP_NOFS|__GFP_COMP), nodemask=(null)
CPU: 3 UID: 0 PID:
1154528 Comm: kworker/u69:8 Not tainted 7.0.2 #1 PREEMPTLAZY
Workqueue: events_unbound btrfs_async_reclaim_metadata_space
Call Trace:
<TASK>
dump_stack_lvl+0x47/0x60
warn_alloc.cold+0x67/0xec
__alloc_pages_slowpath.constprop.0+0x9bf/0xed0
__alloc_frozen_pages_noprof+0x1ac/0x1c0
___kmalloc_large_node+0x9d/0xc0
__kmalloc_noprof+0x17b/0x1f0
split_item+0x9e/0x2e0
btrfs_del_csums+0x285/0x400
__btrfs_free_extent.isra.0+0x6de/0x12b0
__btrfs_run_delayed_refs+0x522/0x10c0
btrfs_run_delayed_refs+0x4d/0x1d0
flush_space+0x34d/0x4e0
do_async_reclaim_metadata_space+0x89/0x1d0
btrfs_async_reclaim_metadata_space+0x44/0x60
process_one_work+0x145/0x230
worker_thread+0x185/0x2e0
kthread+0xca/0x100
ret_from_fork+0x14e/0x200
ret_from_fork_asm+0x11/0x20
</TASK>
BTRFS error (device dm-3 state A): Transaction aborted (error -12)
BTRFS: error (device dm-3 state A) in btrfs_del_csums:1053: errno=-12 Out of memory
BTRFS info (device dm-3 state EA): forced readonly
BTRFS: error (device dm-3 state EA) in do_free_extent_accounting:3168: errno=-12 Out of memory
BTRFS error (device dm-3 state EA): failed to run delayed ref for logical
1202913873920 num_bytes 274432 type 184 action 2 ref_mod 1: -12
BTRFS: error (device dm-3 state EA) in btrfs_run_delayed_refs:2247: errno=-12 Out of memory
[CAUSE]
The kmalloc() call is to allocate a buffer to store the full item.
However as shown in the above call trace, the order can be high (4), and
since we're using GFP_NOFS, it's impossible to reclaim memory by writing
back dirty pages.
When there is no physically contiguous memory left, such high order
allocation can easily fail, and if such kmalloc() happens in a critical
path we can trigger a transaction abort.
[FIX]
Instead of kmalloc(), which requires physically contiguous pages, use
kvmalloc().
There is no special requirement for physically contiguous pages here, we
just want virtually contiguous memory as a buffer.
Reported-by: xavierbachmeyer182 <xavierbachmeyer182@protonmail.com>
Link: https://lore.kernel.org/linux-btrfs/250decb0-d940-4fe6-9b54-d06e1b293a1b@suse.com/
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Daniel Vacek <neelx@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>