Commit 66657b318e0e443ada229fccd40c8be86cfebdbf
Committed by
Chris Mason
1 parent
1fa11e265f
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 5 changed files with 10 additions and 12 deletions Side-by-side Diff
fs/btrfs/compression.c
fs/btrfs/delayed-inode.c
... | ... | @@ -512,8 +512,8 @@ |
512 | 512 | |
513 | 513 | rb_erase(&delayed_item->rb_node, root); |
514 | 514 | delayed_item->delayed_node->count--; |
515 | - atomic_dec(&delayed_root->items); | |
516 | - if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND && | |
515 | + if (atomic_dec_return(&delayed_root->items) < | |
516 | + BTRFS_DELAYED_BACKGROUND && | |
517 | 517 | waitqueue_active(&delayed_root->wait)) |
518 | 518 | wake_up(&delayed_root->wait); |
519 | 519 | } |
... | ... | @@ -1056,8 +1056,7 @@ |
1056 | 1056 | delayed_node->count--; |
1057 | 1057 | |
1058 | 1058 | delayed_root = delayed_node->root->fs_info->delayed_root; |
1059 | - atomic_dec(&delayed_root->items); | |
1060 | - if (atomic_read(&delayed_root->items) < | |
1059 | + if (atomic_dec_return(&delayed_root->items) < | |
1061 | 1060 | BTRFS_DELAYED_BACKGROUND && |
1062 | 1061 | waitqueue_active(&delayed_root->wait)) |
1063 | 1062 | wake_up(&delayed_root->wait); |
fs/btrfs/disk-io.c
... | ... | @@ -754,9 +754,7 @@ |
754 | 754 | limit = btrfs_async_submit_limit(fs_info); |
755 | 755 | limit = limit * 2 / 3; |
756 | 756 | |
757 | - atomic_dec(&fs_info->nr_async_submits); | |
758 | - | |
759 | - if (atomic_read(&fs_info->nr_async_submits) < limit && | |
757 | + if (atomic_dec_return(&fs_info->nr_async_submits) < limit && | |
760 | 758 | waitqueue_active(&fs_info->async_submit_wait)) |
761 | 759 | wake_up(&fs_info->async_submit_wait); |
762 | 760 | |
763 | 761 | |
764 | 762 | |
... | ... | @@ -3783,14 +3781,17 @@ |
3783 | 3781 | /* FIXME: cleanup wait for commit */ |
3784 | 3782 | t->in_commit = 1; |
3785 | 3783 | t->blocked = 1; |
3784 | + smp_mb(); | |
3786 | 3785 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) |
3787 | 3786 | wake_up(&root->fs_info->transaction_blocked_wait); |
3788 | 3787 | |
3789 | 3788 | t->blocked = 0; |
3789 | + smp_mb(); | |
3790 | 3790 | if (waitqueue_active(&root->fs_info->transaction_wait)) |
3791 | 3791 | wake_up(&root->fs_info->transaction_wait); |
3792 | 3792 | |
3793 | 3793 | t->commit_done = 1; |
3794 | + smp_mb(); | |
3794 | 3795 | if (waitqueue_active(&t->commit_wait)) |
3795 | 3796 | wake_up(&t->commit_wait); |
3796 | 3797 |
fs/btrfs/inode.c
... | ... | @@ -1007,9 +1007,7 @@ |
1007 | 1007 | nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >> |
1008 | 1008 | PAGE_CACHE_SHIFT; |
1009 | 1009 | |
1010 | - atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages); | |
1011 | - | |
1012 | - if (atomic_read(&root->fs_info->async_delalloc_pages) < | |
1010 | + if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) < | |
1013 | 1011 | 5 * 1024 * 1024 && |
1014 | 1012 | waitqueue_active(&root->fs_info->async_submit_wait)) |
1015 | 1013 | wake_up(&root->fs_info->async_submit_wait); |
fs/btrfs/volumes.c
... | ... | @@ -227,9 +227,8 @@ |
227 | 227 | cur = pending; |
228 | 228 | pending = pending->bi_next; |
229 | 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 | 232 | waitqueue_active(&fs_info->async_submit_wait)) |
234 | 233 | wake_up(&fs_info->async_submit_wait); |
235 | 234 |