aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-06-30 14:42:28 -0400
committerChris Mason <chris.mason@oracle.com>2011-07-27 12:46:25 -0400
commitbab39bf998133510f2dad08158006197ec0dabea (patch)
tree0ea50b2b07a9f75988829de6c42b6936e2355545
parentdf98b6e2c52f65665eaf0fc23e647fb64335b289 (diff)
Btrfs: use a worker thread to do caching
A user reported a deadlock when copying a bunch of files. This is because they were low on memory and kthreadd got hung up trying to migrate pages for an allocation when starting the caching kthread. The page was locked by the person starting the caching kthread. To fix this we just need to use the async thread stuff so that the threads are already created and we don't have to worry about deadlocks. Thanks, Reported-by: Roman Mamedov <rm@romanrm.ru> Signed-off-by: Josef Bacik <josef@redhat.com>
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/disk-io.c6
-rw-r--r--fs/btrfs/extent-tree.c46
3 files changed, 27 insertions, 29 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 406c33876605..9f6f342900c9 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -767,7 +767,6 @@ struct btrfs_space_info {
767 struct list_head block_groups[BTRFS_NR_RAID_TYPES]; 767 struct list_head block_groups[BTRFS_NR_RAID_TYPES];
768 spinlock_t lock; 768 spinlock_t lock;
769 struct rw_semaphore groups_sem; 769 struct rw_semaphore groups_sem;
770 atomic_t caching_threads;
771 wait_queue_head_t wait; 770 wait_queue_head_t wait;
772}; 771};
773 772
@@ -828,6 +827,7 @@ struct btrfs_caching_control {
828 struct list_head list; 827 struct list_head list;
829 struct mutex mutex; 828 struct mutex mutex;
830 wait_queue_head_t wait; 829 wait_queue_head_t wait;
830 struct btrfs_work work;
831 struct btrfs_block_group_cache *block_group; 831 struct btrfs_block_group_cache *block_group;
832 u64 progress; 832 u64 progress;
833 atomic_t count; 833 atomic_t count;
@@ -1036,6 +1036,8 @@ struct btrfs_fs_info {
1036 struct btrfs_workers endio_write_workers; 1036 struct btrfs_workers endio_write_workers;
1037 struct btrfs_workers endio_freespace_worker; 1037 struct btrfs_workers endio_freespace_worker;
1038 struct btrfs_workers submit_workers; 1038 struct btrfs_workers submit_workers;
1039 struct btrfs_workers caching_workers;
1040
1039 /* 1041 /*
1040 * fixup workers take dirty pages that didn't properly go through 1042 * fixup workers take dirty pages that didn't properly go through
1041 * the cow mechanism and make them safe to write. It happens 1043 * the cow mechanism and make them safe to write. It happens
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 1ac8db5dc0a3..234a08404fc2 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1807,6 +1807,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1807 fs_info->thread_pool_size), 1807 fs_info->thread_pool_size),
1808 &fs_info->generic_worker); 1808 &fs_info->generic_worker);
1809 1809
1810 btrfs_init_workers(&fs_info->caching_workers, "cache",
1811 2, &fs_info->generic_worker);
1812
1810 /* a higher idle thresh on the submit workers makes it much more 1813 /* a higher idle thresh on the submit workers makes it much more
1811 * likely that bios will be send down in a sane order to the 1814 * likely that bios will be send down in a sane order to the
1812 * devices 1815 * devices
@@ -1860,6 +1863,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1860 btrfs_start_workers(&fs_info->endio_write_workers, 1); 1863 btrfs_start_workers(&fs_info->endio_write_workers, 1);
1861 btrfs_start_workers(&fs_info->endio_freespace_worker, 1); 1864 btrfs_start_workers(&fs_info->endio_freespace_worker, 1);
1862 btrfs_start_workers(&fs_info->delayed_workers, 1); 1865 btrfs_start_workers(&fs_info->delayed_workers, 1);
1866 btrfs_start_workers(&fs_info->caching_workers, 1);
1863 1867
1864 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 1868 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
1865 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 1869 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -2117,6 +2121,7 @@ fail_sb_buffer:
2117 btrfs_stop_workers(&fs_info->endio_freespace_worker); 2121 btrfs_stop_workers(&fs_info->endio_freespace_worker);
2118 btrfs_stop_workers(&fs_info->submit_workers); 2122 btrfs_stop_workers(&fs_info->submit_workers);
2119 btrfs_stop_workers(&fs_info->delayed_workers); 2123 btrfs_stop_workers(&fs_info->delayed_workers);
2124 btrfs_stop_workers(&fs_info->caching_workers);
2120fail_alloc: 2125fail_alloc:
2121 kfree(fs_info->delayed_root); 2126 kfree(fs_info->delayed_root);
2122fail_iput: 2127fail_iput:
@@ -2584,6 +2589,7 @@ int close_ctree(struct btrfs_root *root)
2584 btrfs_stop_workers(&fs_info->endio_freespace_worker); 2589 btrfs_stop_workers(&fs_info->endio_freespace_worker);
2585 btrfs_stop_workers(&fs_info->submit_workers); 2590 btrfs_stop_workers(&fs_info->submit_workers);
2586 btrfs_stop_workers(&fs_info->delayed_workers); 2591 btrfs_stop_workers(&fs_info->delayed_workers);
2592 btrfs_stop_workers(&fs_info->caching_workers);
2587 2593
2588 btrfs_close_devices(fs_info->fs_devices); 2594 btrfs_close_devices(fs_info->fs_devices);
2589 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2595 btrfs_mapping_tree_free(&fs_info->mapping_tree);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 340c14715091..5ab31f70ff5b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -320,12 +320,12 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group,
320 return total_added; 320 return total_added;
321} 321}
322 322
323static int caching_kthread(void *data) 323static noinline void caching_thread(struct btrfs_work *work)
324{ 324{
325 struct btrfs_block_group_cache *block_group = data; 325 struct btrfs_block_group_cache *block_group;
326 struct btrfs_fs_info *fs_info = block_group->fs_info; 326 struct btrfs_fs_info *fs_info;
327 struct btrfs_caching_control *caching_ctl = block_group->caching_ctl; 327 struct btrfs_caching_control *caching_ctl;
328 struct btrfs_root *extent_root = fs_info->extent_root; 328 struct btrfs_root *extent_root;
329 struct btrfs_path *path; 329 struct btrfs_path *path;
330 struct extent_buffer *leaf; 330 struct extent_buffer *leaf;
331 struct btrfs_key key; 331 struct btrfs_key key;
@@ -334,9 +334,14 @@ static int caching_kthread(void *data)
334 u32 nritems; 334 u32 nritems;
335 int ret = 0; 335 int ret = 0;
336 336
337 caching_ctl = container_of(work, struct btrfs_caching_control, work);
338 block_group = caching_ctl->block_group;
339 fs_info = block_group->fs_info;
340 extent_root = fs_info->extent_root;
341
337 path = btrfs_alloc_path(); 342 path = btrfs_alloc_path();
338 if (!path) 343 if (!path)
339 return -ENOMEM; 344 goto out;
340 345
341 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); 346 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
342 347
@@ -433,13 +438,11 @@ err:
433 free_excluded_extents(extent_root, block_group); 438 free_excluded_extents(extent_root, block_group);
434 439
435 mutex_unlock(&caching_ctl->mutex); 440 mutex_unlock(&caching_ctl->mutex);
441out:
436 wake_up(&caching_ctl->wait); 442 wake_up(&caching_ctl->wait);
437 443
438 put_caching_control(caching_ctl); 444 put_caching_control(caching_ctl);
439 atomic_dec(&block_group->space_info->caching_threads);
440 btrfs_put_block_group(block_group); 445 btrfs_put_block_group(block_group);
441
442 return 0;
443} 446}
444 447
445static int cache_block_group(struct btrfs_block_group_cache *cache, 448static int cache_block_group(struct btrfs_block_group_cache *cache,
@@ -449,7 +452,6 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
449{ 452{
450 struct btrfs_fs_info *fs_info = cache->fs_info; 453 struct btrfs_fs_info *fs_info = cache->fs_info;
451 struct btrfs_caching_control *caching_ctl; 454 struct btrfs_caching_control *caching_ctl;
452 struct task_struct *tsk;
453 int ret = 0; 455 int ret = 0;
454 456
455 smp_mb(); 457 smp_mb();
@@ -501,6 +503,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
501 caching_ctl->progress = cache->key.objectid; 503 caching_ctl->progress = cache->key.objectid;
502 /* one for caching kthread, one for caching block group list */ 504 /* one for caching kthread, one for caching block group list */
503 atomic_set(&caching_ctl->count, 2); 505 atomic_set(&caching_ctl->count, 2);
506 caching_ctl->work.func = caching_thread;
504 507
505 spin_lock(&cache->lock); 508 spin_lock(&cache->lock);
506 if (cache->cached != BTRFS_CACHE_NO) { 509 if (cache->cached != BTRFS_CACHE_NO) {
@@ -516,16 +519,9 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
516 list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups); 519 list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups);
517 up_write(&fs_info->extent_commit_sem); 520 up_write(&fs_info->extent_commit_sem);
518 521
519 atomic_inc(&cache->space_info->caching_threads);
520 btrfs_get_block_group(cache); 522 btrfs_get_block_group(cache);
521 523
522 tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", 524 btrfs_queue_worker(&fs_info->caching_workers, &caching_ctl->work);
523 cache->key.objectid);
524 if (IS_ERR(tsk)) {
525 ret = PTR_ERR(tsk);
526 printk(KERN_ERR "error running thread %d\n", ret);
527 BUG();
528 }
529 525
530 return ret; 526 return ret;
531} 527}
@@ -2936,7 +2932,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
2936 init_waitqueue_head(&found->wait); 2932 init_waitqueue_head(&found->wait);
2937 *space_info = found; 2933 *space_info = found;
2938 list_add_rcu(&found->list, &info->space_info); 2934 list_add_rcu(&found->list, &info->space_info);
2939 atomic_set(&found->caching_threads, 0);
2940 return 0; 2935 return 0;
2941} 2936}
2942 2937
@@ -4997,14 +4992,10 @@ have_block_group:
4997 } 4992 }
4998 4993
4999 /* 4994 /*
5000 * We only want to start kthread caching if we are at 4995 * The caching workers are limited to 2 threads, so we
5001 * the point where we will wait for caching to make 4996 * can queue as much work as we care to.
5002 * progress, or if our ideal search is over and we've
5003 * found somebody to start caching.
5004 */ 4997 */
5005 if (loop > LOOP_CACHING_NOWAIT || 4998 if (loop > LOOP_FIND_IDEAL) {
5006 (loop > LOOP_FIND_IDEAL &&
5007 atomic_read(&space_info->caching_threads) < 2)) {
5008 ret = cache_block_group(block_group, trans, 4999 ret = cache_block_group(block_group, trans,
5009 orig_root, 0); 5000 orig_root, 0);
5010 BUG_ON(ret); 5001 BUG_ON(ret);
@@ -5226,8 +5217,7 @@ loop:
5226 if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { 5217 if (loop == LOOP_FIND_IDEAL && found_uncached_bg) {
5227 found_uncached_bg = false; 5218 found_uncached_bg = false;
5228 loop++; 5219 loop++;
5229 if (!ideal_cache_percent && 5220 if (!ideal_cache_percent)
5230 atomic_read(&space_info->caching_threads))
5231 goto search; 5221 goto search;
5232 5222
5233 /* 5223 /*