aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-08-01 15:36:24 -0400
committerChris Mason <chris.mason@oracle.com>2012-08-28 16:53:33 -0400
commit66657b318e0e443ada229fccd40c8be86cfebdbf (patch)
treebf1334fff93556fbc8d82b26a6d5431fd9e74b5c /fs
parent1fa11e265fa2562fb713171b6a58e72bb7afd276 (diff)
Btrfs: barrier before waitqueue_active
We need a barrir before calling waitqueue_active otherwise we will miss wakeups. So in places that do atomic_dec(); then atomic_read() use atomic_dec_return() which imply a memory barrier (see memory-barriers.txt) and then add an explicit memory barrier everywhere else that need them. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/compression.c1
-rw-r--r--fs/btrfs/delayed-inode.c7
-rw-r--r--fs/btrfs/disk-io.c7
-rw-r--r--fs/btrfs/inode.c4
-rw-r--r--fs/btrfs/volumes.c3
5 files changed, 10 insertions, 12 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 86eff48dab78..43d1c5a3a030 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -818,6 +818,7 @@ static void free_workspace(int type, struct list_head *workspace)
818 btrfs_compress_op[idx]->free_workspace(workspace); 818 btrfs_compress_op[idx]->free_workspace(workspace);
819 atomic_dec(alloc_workspace); 819 atomic_dec(alloc_workspace);
820wake: 820wake:
821 smp_mb();
821 if (waitqueue_active(workspace_wait)) 822 if (waitqueue_active(workspace_wait))
822 wake_up(workspace_wait); 823 wake_up(workspace_wait);
823} 824}
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 00deed4ef3ed..07d5eeb1e6f1 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -512,8 +512,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
512 512
513 rb_erase(&delayed_item->rb_node, root); 513 rb_erase(&delayed_item->rb_node, root);
514 delayed_item->delayed_node->count--; 514 delayed_item->delayed_node->count--;
515 atomic_dec(&delayed_root->items); 515 if (atomic_dec_return(&delayed_root->items) <
516 if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND && 516 BTRFS_DELAYED_BACKGROUND &&
517 waitqueue_active(&delayed_root->wait)) 517 waitqueue_active(&delayed_root->wait))
518 wake_up(&delayed_root->wait); 518 wake_up(&delayed_root->wait);
519} 519}
@@ -1056,8 +1056,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
1056 delayed_node->count--; 1056 delayed_node->count--;
1057 1057
1058 delayed_root = delayed_node->root->fs_info->delayed_root; 1058 delayed_root = delayed_node->root->fs_info->delayed_root;
1059 atomic_dec(&delayed_root->items); 1059 if (atomic_dec_return(&delayed_root->items) <
1060 if (atomic_read(&delayed_root->items) <
1061 BTRFS_DELAYED_BACKGROUND && 1060 BTRFS_DELAYED_BACKGROUND &&
1062 waitqueue_active(&delayed_root->wait)) 1061 waitqueue_active(&delayed_root->wait))
1063 wake_up(&delayed_root->wait); 1062 wake_up(&delayed_root->wait);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a7ad8fc8dc53..dd86a5d88428 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -754,9 +754,7 @@ static void run_one_async_done(struct btrfs_work *work)
754 limit = btrfs_async_submit_limit(fs_info); 754 limit = btrfs_async_submit_limit(fs_info);
755 limit = limit * 2 / 3; 755 limit = limit * 2 / 3;
756 756
757 atomic_dec(&fs_info->nr_async_submits); 757 if (atomic_dec_return(&fs_info->nr_async_submits) < limit &&
758
759 if (atomic_read(&fs_info->nr_async_submits) < limit &&
760 waitqueue_active(&fs_info->async_submit_wait)) 758 waitqueue_active(&fs_info->async_submit_wait))
761 wake_up(&fs_info->async_submit_wait); 759 wake_up(&fs_info->async_submit_wait);
762 760
@@ -3783,14 +3781,17 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
3783 /* FIXME: cleanup wait for commit */ 3781 /* FIXME: cleanup wait for commit */
3784 t->in_commit = 1; 3782 t->in_commit = 1;
3785 t->blocked = 1; 3783 t->blocked = 1;
3784 smp_mb();
3786 if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) 3785 if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
3787 wake_up(&root->fs_info->transaction_blocked_wait); 3786 wake_up(&root->fs_info->transaction_blocked_wait);
3788 3787
3789 t->blocked = 0; 3788 t->blocked = 0;
3789 smp_mb();
3790 if (waitqueue_active(&root->fs_info->transaction_wait)) 3790 if (waitqueue_active(&root->fs_info->transaction_wait))
3791 wake_up(&root->fs_info->transaction_wait); 3791 wake_up(&root->fs_info->transaction_wait);
3792 3792
3793 t->commit_done = 1; 3793 t->commit_done = 1;
3794 smp_mb();
3794 if (waitqueue_active(&t->commit_wait)) 3795 if (waitqueue_active(&t->commit_wait))
3795 wake_up(&t->commit_wait); 3796 wake_up(&t->commit_wait);
3796 3797
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2d65c52b0944..97baf00b40d1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1007,9 +1007,7 @@ static noinline void async_cow_submit(struct btrfs_work *work)
1007 nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >> 1007 nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >>
1008 PAGE_CACHE_SHIFT; 1008 PAGE_CACHE_SHIFT;
1009 1009
1010 atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages); 1010 if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) <
1011
1012 if (atomic_read(&root->fs_info->async_delalloc_pages) <
1013 5 * 1024 * 1024 && 1011 5 * 1024 * 1024 &&
1014 waitqueue_active(&root->fs_info->async_submit_wait)) 1012 waitqueue_active(&root->fs_info->async_submit_wait))
1015 wake_up(&root->fs_info->async_submit_wait); 1013 wake_up(&root->fs_info->async_submit_wait);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3b394503bd4e..0b1e69d380dd 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -227,9 +227,8 @@ loop_lock:
227 cur = pending; 227 cur = pending;
228 pending = pending->bi_next; 228 pending = pending->bi_next;
229 cur->bi_next = NULL; 229 cur->bi_next = NULL;
230 atomic_dec(&fs_info->nr_async_bios);
231 230
232 if (atomic_read(&fs_info->nr_async_bios) < limit && 231 if (atomic_dec_return(&fs_info->nr_async_bios) < limit &&
233 waitqueue_active(&fs_info->async_submit_wait)) 232 waitqueue_active(&fs_info->async_submit_wait))
234 wake_up(&fs_info->async_submit_wait); 233 wake_up(&fs_info->async_submit_wait);
235 234