aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-31 10:48:37 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit37d1aeee3990385e9bb436c50c2f7e120a668df6 (patch)
tree6fc0e7beba7161e0400e743b31030b8cbbe29885
parent47ac14fa0f5306c6b97203f4f086bf1fa21dfddb (diff)
Btrfs: Throttle tuning
This avoids waiting for transactions with pages locked by breaking out the code to wait for the current transaction to close into a function called by btrfs_throttle. It also lowers the limits for where we start throttling. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c3
-rw-r--r--fs/btrfs/file.c2
-rw-r--r--fs/btrfs/transaction.c38
3 files changed, 31 insertions, 12 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 4765248000fd..b003b4364ddb 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2526,6 +2526,9 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
2526 *level = 0; 2526 *level = 0;
2527 break; 2527 break;
2528 } 2528 }
2529 if (printk_ratelimit())
2530 printk("leaf ref miss for bytenr %llu\n",
2531 (unsigned long long)bytenr);
2529 } 2532 }
2530 next = btrfs_find_tree_block(root, bytenr, blocksize); 2533 next = btrfs_find_tree_block(root, bytenr, blocksize);
2531 if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { 2534 if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 388ac397c2c8..d3f2fe0b7c6c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -253,7 +253,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
253 end_of_last_block = start_pos + num_bytes - 1; 253 end_of_last_block = start_pos + num_bytes - 1;
254 254
255 lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); 255 lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS);
256 trans = btrfs_start_transaction(root, 1); 256 trans = btrfs_join_transaction(root, 1);
257 if (!trans) { 257 if (!trans) {
258 err = -ENOMEM; 258 err = -ENOMEM;
259 goto out_unlock; 259 goto out_unlock;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 52c5524896a3..66af5140c8ce 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -124,17 +124,12 @@ static noinline int record_root_in_trans(struct btrfs_root *root)
124 return 0; 124 return 0;
125} 125}
126 126
127struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 127static void wait_current_trans(struct btrfs_root *root)
128 int num_blocks, int join)
129{ 128{
130 struct btrfs_trans_handle *h =
131 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
132 struct btrfs_transaction *cur_trans; 129 struct btrfs_transaction *cur_trans;
133 int ret;
134 130
135 mutex_lock(&root->fs_info->trans_mutex);
136 cur_trans = root->fs_info->running_transaction; 131 cur_trans = root->fs_info->running_transaction;
137 if (cur_trans && cur_trans->blocked && !join) { 132 if (cur_trans && cur_trans->blocked) {
138 DEFINE_WAIT(wait); 133 DEFINE_WAIT(wait);
139 cur_trans->use_count++; 134 cur_trans->use_count++;
140 while(1) { 135 while(1) {
@@ -154,6 +149,18 @@ struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
154 } 149 }
155 put_transaction(cur_trans); 150 put_transaction(cur_trans);
156 } 151 }
152}
153
154struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
155 int num_blocks, int join)
156{
157 struct btrfs_trans_handle *h =
158 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
159 int ret;
160
161 mutex_lock(&root->fs_info->trans_mutex);
162 if (!join)
163 wait_current_trans(root);
157 ret = join_transaction(root); 164 ret = join_transaction(root);
158 BUG_ON(ret); 165 BUG_ON(ret);
159 166
@@ -200,7 +207,7 @@ static noinline int wait_for_commit(struct btrfs_root *root,
200 return 0; 207 return 0;
201} 208}
202 209
203void btrfs_throttle(struct btrfs_root *root) 210static void throttle_on_drops(struct btrfs_root *root)
204{ 211{
205 struct btrfs_fs_info *info = root->fs_info; 212 struct btrfs_fs_info *info = root->fs_info;
206 213
@@ -223,19 +230,28 @@ harder:
223 } while (thr == atomic_read(&info->throttle_gen)); 230 } while (thr == atomic_read(&info->throttle_gen));
224 231
225 if (harder_count < 5 && 232 if (harder_count < 5 &&
226 info->total_ref_cache_size > 5 * 1024 * 1024) { 233 info->total_ref_cache_size > 1 * 1024 * 1024) {
227 harder_count++; 234 harder_count++;
228 goto harder; 235 goto harder;
229 } 236 }
230 237
231 if (harder_count < 10 && 238 if (harder_count < 10 &&
232 info->total_ref_cache_size > 10 * 1024 * 1024) { 239 info->total_ref_cache_size > 5 * 1024 * 1024) {
233 harder_count++; 240 harder_count++;
234 goto harder; 241 goto harder;
235 } 242 }
236 } 243 }
237} 244}
238 245
246void btrfs_throttle(struct btrfs_root *root)
247{
248 mutex_lock(&root->fs_info->trans_mutex);
249 wait_current_trans(root);
250 mutex_unlock(&root->fs_info->trans_mutex);
251
252 throttle_on_drops(root);
253}
254
239static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, 255static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
240 struct btrfs_root *root, int throttle) 256 struct btrfs_root *root, int throttle)
241{ 257{
@@ -256,7 +272,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
256 kmem_cache_free(btrfs_trans_handle_cachep, trans); 272 kmem_cache_free(btrfs_trans_handle_cachep, trans);
257 273
258 if (throttle) 274 if (throttle)
259 btrfs_throttle(root); 275 throttle_on_drops(root);
260 276
261 return 0; 277 return 0;
262} 278}