btrfs: qgroup: iterate qgroups without memory allocation for qgroup_reserve()
authorQu Wenruo <wqu@suse.com>
Sat, 2 Sep 2023 00:13:52 +0000 (08:13 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jan 2024 12:42:24 +0000 (12:42 +0000)
commit1c9a5c49504c3df282a8490f165ea9dc623deef6
treef2fa16b4f0b6a151c94eddec782d6e8871d10e7f
parente93bcaebda90c237b2ce2b4e0ee7897b83b5cbf0
btrfs: qgroup: iterate qgroups without memory allocation for qgroup_reserve()

[ Upstream commit 686c4a5a42635e0d2889e3eb461c554fd0b616b4 ]

Qgroup heavily relies on ulist to go through all the involved
qgroups, but since we're using ulist inside fs_info->qgroup_lock
spinlock, this means we're doing a lot of GFP_ATOMIC allocations.

This patch reduces the GFP_ATOMIC usage for qgroup_reserve() by
eliminating the memory allocation completely.

This is done by moving the needed memory to btrfs_qgroup::iterator
list_head, so that we can put all the involved qgroup into a on-stack
list, thus eliminating the need to allocate memory while holding
spinlock.

The only cost is the slightly higher memory usage, but considering the
reduce GFP_ATOMIC during a hot path, it should still be acceptable.

Function qgroup_reserve() is the perfect start point for this
conversion.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Stable-dep-of: b321a52cce06 ("btrfs: free qgroup pertrans reserve on transaction abort")
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/btrfs/qgroup.c
fs/btrfs/qgroup.h