diff options
author | Josef Bacik <jbacik@fusionio.com> | 2012-08-01 15:36:24 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-08-28 16:53:33 -0400 |
commit | 66657b318e0e443ada229fccd40c8be86cfebdbf (patch) | |
tree | bf1334fff93556fbc8d82b26a6d5431fd9e74b5c /fs/btrfs/disk-io.c | |
parent | 1fa11e265fa2562fb713171b6a58e72bb7afd276 (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/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 7 |
1 files changed, 4 insertions, 3 deletions
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 | ||