summaryrefslogtreecommitdiff
path: root/fs/btrfs/qgroup.h
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2023-09-02 03:13:52 +0300
committerDavid Sterba <dsterba@suse.com>2023-10-12 17:44:03 +0300
commit686c4a5a42635e0d2889e3eb461c554fd0b616b4 (patch)
tree5235f3aa787d51bc5ec38d1b81d549ca215e31a6 /fs/btrfs/qgroup.h
parent2a3a1dd99e043b64c0f61cb3960040fd697d87bf (diff)
downloadlinux-686c4a5a42635e0d2889e3eb461c554fd0b616b4.tar.xz
btrfs: qgroup: iterate qgroups without memory allocation for qgroup_reserve()
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>
Diffstat (limited to 'fs/btrfs/qgroup.h')
-rw-r--r--fs/btrfs/qgroup.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 7bffa10589d6..6a43618580b6 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -220,6 +220,15 @@ struct btrfs_qgroup {
struct list_head groups; /* groups this group is member of */
struct list_head members; /* groups that are members of this group */
struct list_head dirty; /* dirty groups */
+
+ /*
+ * For qgroup iteration usage.
+ *
+ * The iteration list should always be empty until qgroup_iterator_add()
+ * is called. And should be reset to empty after the iteration is
+ * finished.
+ */
+ struct list_head iterator;
struct rb_node node; /* tree of qgroups */
/*