aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-ref.h
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2014-01-23 09:21:38 -0500
committerChris Mason <clm@fb.com>2014-01-28 16:20:25 -0500
commitd7df2c796d7eedd72a334dc89c65e1fec8171431 (patch)
tree63e3adda6e56db27b13d0df28840a873ceac5855 /fs/btrfs/delayed-ref.h
parent5039eddc19aee8c894191c24f2dde4e645ca1bbb (diff)
Btrfs: attach delayed ref updates to delayed ref heads
Currently we have two rb-trees, one for delayed ref heads and one for all of the delayed refs, including the delayed ref heads. When we process the delayed refs we have to hold onto the delayed ref lock for all of the selecting and merging and such, which results in quite a bit of lock contention. This was solved by having a waitqueue and only one flusher at a time, however this hurts if we get a lot of delayed refs queued up. So instead just have an rb tree for the delayed ref heads, and then attach the delayed ref updates to an rb tree that is per delayed ref head. Then we only need to take the delayed ref lock when adding new delayed refs and when selecting a delayed ref head to process, all the rest of the time we deal with a per delayed ref head lock which will be much less contentious. The locking rules for this get a little more complicated since we have to lock up to 3 things to properly process delayed refs, but I will address that problem later. For now this passes all of xfstests and my overnight stress tests. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/delayed-ref.h')
-rw-r--r--fs/btrfs/delayed-ref.h23
1 files changed, 7 insertions, 16 deletions
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index a54c9d47918f..4ba9b93022ff 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -81,7 +81,8 @@ struct btrfs_delayed_ref_head {
81 */ 81 */
82 struct mutex mutex; 82 struct mutex mutex;
83 83
84 struct list_head cluster; 84 spinlock_t lock;
85 struct rb_root ref_root;
85 86
86 struct rb_node href_node; 87 struct rb_node href_node;
87 88
@@ -100,6 +101,7 @@ struct btrfs_delayed_ref_head {
100 */ 101 */
101 unsigned int must_insert_reserved:1; 102 unsigned int must_insert_reserved:1;
102 unsigned int is_data:1; 103 unsigned int is_data:1;
104 unsigned int processing:1;
103}; 105};
104 106
105struct btrfs_delayed_tree_ref { 107struct btrfs_delayed_tree_ref {
@@ -118,8 +120,6 @@ struct btrfs_delayed_data_ref {
118}; 120};
119 121
120struct btrfs_delayed_ref_root { 122struct btrfs_delayed_ref_root {
121 struct rb_root root;
122
123 /* head ref rbtree */ 123 /* head ref rbtree */
124 struct rb_root href_root; 124 struct rb_root href_root;
125 125
@@ -129,7 +129,7 @@ struct btrfs_delayed_ref_root {
129 /* how many delayed ref updates we've queued, used by the 129 /* how many delayed ref updates we've queued, used by the
130 * throttling code 130 * throttling code
131 */ 131 */
132 unsigned long num_entries; 132 atomic_t num_entries;
133 133
134 /* total number of head nodes in tree */ 134 /* total number of head nodes in tree */
135 unsigned long num_heads; 135 unsigned long num_heads;
@@ -138,15 +138,6 @@ struct btrfs_delayed_ref_root {
138 unsigned long num_heads_ready; 138 unsigned long num_heads_ready;
139 139
140 /* 140 /*
141 * bumped when someone is making progress on the delayed
142 * refs, so that other procs know they are just adding to
143 * contention intead of helping
144 */
145 atomic_t procs_running_refs;
146 atomic_t ref_seq;
147 wait_queue_head_t wait;
148
149 /*
150 * set when the tree is flushing before a transaction commit, 141 * set when the tree is flushing before a transaction commit,
151 * used by the throttling code to decide if new updates need 142 * used by the throttling code to decide if new updates need
152 * to be run right away 143 * to be run right away
@@ -231,9 +222,9 @@ static inline void btrfs_delayed_ref_unlock(struct btrfs_delayed_ref_head *head)
231 mutex_unlock(&head->mutex); 222 mutex_unlock(&head->mutex);
232} 223}
233 224
234int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, 225
235 struct list_head *cluster, u64 search_start); 226struct btrfs_delayed_ref_head *
236void btrfs_release_ref_cluster(struct list_head *cluster); 227btrfs_select_ref_head(struct btrfs_trans_handle *trans);
237 228
238int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, 229int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
239 struct btrfs_delayed_ref_root *delayed_refs, 230 struct btrfs_delayed_ref_root *delayed_refs,