aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2015-10-12 19:24:40 -0400
committerChris Mason <clm@fb.com>2015-10-12 19:24:40 -0400
commit6db4a7335dd701a0e20275440ee057d3db2a7ae3 (patch)
treec0734d7411806ef91bfeb615bf528ffb349938fe
parent62fb50ab7c903357c92cef2f7677235b92ac575f (diff)
parentee86395458072760d62e66aad10a5e9e8902b8cf (diff)
Merge branch 'fix/waitqueue-barriers' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4
-rw-r--r--fs/btrfs/compression.c3
-rw-r--r--fs/btrfs/delayed-inode.c4
-rw-r--r--fs/btrfs/dev-replace.c3
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/extent-tree.c3
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/locking.c12
-rw-r--r--fs/btrfs/ordered-data.c6
-rw-r--r--fs/btrfs/raid56.c6
-rw-r--r--fs/btrfs/transaction.c9
-rw-r--r--fs/btrfs/tree-log.c14
-rw-r--r--fs/btrfs/volumes.c3
12 files changed, 62 insertions, 7 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 57ee8ca29b06..3a9317ce67f8 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -839,6 +839,9 @@ static void free_workspace(int type, struct list_head *workspace)
839 btrfs_compress_op[idx]->free_workspace(workspace); 839 btrfs_compress_op[idx]->free_workspace(workspace);
840 atomic_dec(alloc_workspace); 840 atomic_dec(alloc_workspace);
841wake: 841wake:
842 /*
843 * Make sure counter is updated before we wake up waiters.
844 */
842 smp_mb(); 845 smp_mb();
843 if (waitqueue_active(workspace_wait)) 846 if (waitqueue_active(workspace_wait))
844 wake_up(workspace_wait); 847 wake_up(workspace_wait);
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index a2ae42720a6a..e0941fbb913c 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -463,6 +463,10 @@ static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node,
463static void finish_one_item(struct btrfs_delayed_root *delayed_root) 463static void finish_one_item(struct btrfs_delayed_root *delayed_root)
464{ 464{
465 int seq = atomic_inc_return(&delayed_root->items_seq); 465 int seq = atomic_inc_return(&delayed_root->items_seq);
466
467 /*
468 * atomic_dec_return implies a barrier for waitqueue_active
469 */
466 if ((atomic_dec_return(&delayed_root->items) < 470 if ((atomic_dec_return(&delayed_root->items) <
467 BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0) && 471 BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0) &&
468 waitqueue_active(&delayed_root->wait)) 472 waitqueue_active(&delayed_root->wait))
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index a64ca942b63f..1e668fb7dd4c 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -454,8 +454,7 @@ static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info)
454static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info) 454static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info)
455{ 455{
456 clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state); 456 clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state);
457 if (waitqueue_active(&fs_info->replace_wait)) 457 wake_up(&fs_info->replace_wait);
458 wake_up(&fs_info->replace_wait);
459} 458}
460 459
461static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, 460static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 7f934cccc98d..a42c1f575ef7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -801,6 +801,9 @@ static void run_one_async_done(struct btrfs_work *work)
801 limit = btrfs_async_submit_limit(fs_info); 801 limit = btrfs_async_submit_limit(fs_info);
802 limit = limit * 2 / 3; 802 limit = limit * 2 / 3;
803 803
804 /*
805 * atomic_dec_return implies a barrier for waitqueue_active
806 */
804 if (atomic_dec_return(&fs_info->nr_async_submits) < limit && 807 if (atomic_dec_return(&fs_info->nr_async_submits) < limit &&
805 waitqueue_active(&fs_info->async_submit_wait)) 808 waitqueue_active(&fs_info->async_submit_wait))
806 wake_up(&fs_info->async_submit_wait); 809 wake_up(&fs_info->async_submit_wait);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 92a5b4cad2ab..522fb45d472a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10372,8 +10372,7 @@ void btrfs_end_write_no_snapshoting(struct btrfs_root *root)
10372{ 10372{
10373 percpu_counter_dec(&root->subv_writers->counter); 10373 percpu_counter_dec(&root->subv_writers->counter);
10374 /* 10374 /*
10375 * Make sure counter is updated before we wake up 10375 * Make sure counter is updated before we wake up waiters.
10376 * waiters.
10377 */ 10376 */
10378 smp_mb(); 10377 smp_mb();
10379 if (waitqueue_active(&root->subv_writers->wait)) 10378 if (waitqueue_active(&root->subv_writers->wait))
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 25eb814c302f..208db4e835f0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1096,6 +1096,9 @@ static noinline void async_cow_submit(struct btrfs_work *work)
1096 nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >> 1096 nr_pages = (async_cow->end - async_cow->start + PAGE_CACHE_SIZE) >>
1097 PAGE_CACHE_SHIFT; 1097 PAGE_CACHE_SHIFT;
1098 1098
1099 /*
1100 * atomic_sub_return implies a barrier for waitqueue_active
1101 */
1099 if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) < 1102 if (atomic_sub_return(nr_pages, &root->fs_info->async_delalloc_pages) <
1100 5 * 1024 * 1024 && 1103 5 * 1024 * 1024 &&
1101 waitqueue_active(&root->fs_info->async_submit_wait)) 1104 waitqueue_active(&root->fs_info->async_submit_wait))
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index d7e6baf1b205..8077461fc56a 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -79,6 +79,9 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)
79 write_lock(&eb->lock); 79 write_lock(&eb->lock);
80 WARN_ON(atomic_read(&eb->spinning_writers)); 80 WARN_ON(atomic_read(&eb->spinning_writers));
81 atomic_inc(&eb->spinning_writers); 81 atomic_inc(&eb->spinning_writers);
82 /*
83 * atomic_dec_and_test implies a barrier for waitqueue_active
84 */
82 if (atomic_dec_and_test(&eb->blocking_writers) && 85 if (atomic_dec_and_test(&eb->blocking_writers) &&
83 waitqueue_active(&eb->write_lock_wq)) 86 waitqueue_active(&eb->write_lock_wq))
84 wake_up(&eb->write_lock_wq); 87 wake_up(&eb->write_lock_wq);
@@ -86,6 +89,9 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)
86 BUG_ON(atomic_read(&eb->blocking_readers) == 0); 89 BUG_ON(atomic_read(&eb->blocking_readers) == 0);
87 read_lock(&eb->lock); 90 read_lock(&eb->lock);
88 atomic_inc(&eb->spinning_readers); 91 atomic_inc(&eb->spinning_readers);
92 /*
93 * atomic_dec_and_test implies a barrier for waitqueue_active
94 */
89 if (atomic_dec_and_test(&eb->blocking_readers) && 95 if (atomic_dec_and_test(&eb->blocking_readers) &&
90 waitqueue_active(&eb->read_lock_wq)) 96 waitqueue_active(&eb->read_lock_wq))
91 wake_up(&eb->read_lock_wq); 97 wake_up(&eb->read_lock_wq);
@@ -229,6 +235,9 @@ void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
229 } 235 }
230 btrfs_assert_tree_read_locked(eb); 236 btrfs_assert_tree_read_locked(eb);
231 WARN_ON(atomic_read(&eb->blocking_readers) == 0); 237 WARN_ON(atomic_read(&eb->blocking_readers) == 0);
238 /*
239 * atomic_dec_and_test implies a barrier for waitqueue_active
240 */
232 if (atomic_dec_and_test(&eb->blocking_readers) && 241 if (atomic_dec_and_test(&eb->blocking_readers) &&
233 waitqueue_active(&eb->read_lock_wq)) 242 waitqueue_active(&eb->read_lock_wq))
234 wake_up(&eb->read_lock_wq); 243 wake_up(&eb->read_lock_wq);
@@ -280,6 +289,9 @@ void btrfs_tree_unlock(struct extent_buffer *eb)
280 if (blockers) { 289 if (blockers) {
281 WARN_ON(atomic_read(&eb->spinning_writers)); 290 WARN_ON(atomic_read(&eb->spinning_writers));
282 atomic_dec(&eb->blocking_writers); 291 atomic_dec(&eb->blocking_writers);
292 /*
293 * Make sure counter is updated before we wake up waiters.
294 */
283 smp_mb(); 295 smp_mb();
284 if (waitqueue_active(&eb->write_lock_wq)) 296 if (waitqueue_active(&eb->write_lock_wq))
285 wake_up(&eb->write_lock_wq); 297 wake_up(&eb->write_lock_wq);
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 52170cf1757e..071005f008c1 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -345,6 +345,9 @@ int btrfs_dec_test_first_ordered_pending(struct inode *inode,
345 345
346 if (entry->bytes_left == 0) { 346 if (entry->bytes_left == 0) {
347 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); 347 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
348 /*
349 * Implicit memory barrier after test_and_set_bit
350 */
348 if (waitqueue_active(&entry->wait)) 351 if (waitqueue_active(&entry->wait))
349 wake_up(&entry->wait); 352 wake_up(&entry->wait);
350 } else { 353 } else {
@@ -409,6 +412,9 @@ have_entry:
409 412
410 if (entry->bytes_left == 0) { 413 if (entry->bytes_left == 0) {
411 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); 414 ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
415 /*
416 * Implicit memory barrier after test_and_set_bit
417 */
412 if (waitqueue_active(&entry->wait)) 418 if (waitqueue_active(&entry->wait))
413 wake_up(&entry->wait); 419 wake_up(&entry->wait);
414 } else { 420 } else {
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index fcf7265ca46f..1a33d3eb36de 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -810,7 +810,11 @@ static noinline void unlock_stripe(struct btrfs_raid_bio *rbio)
810 } 810 }
811 811
812 goto done_nolock; 812 goto done_nolock;
813 } else if (waitqueue_active(&h->wait)) { 813 /*
814 * The barrier for this waitqueue_active is not needed,
815 * we're protected by h->lock and can't miss a wakeup.
816 */
817 } else if (waitqueue_active(&h->wait)) {
814 spin_unlock(&rbio->bio_list_lock); 818 spin_unlock(&rbio->bio_list_lock);
815 spin_unlock_irqrestore(&h->lock, flags); 819 spin_unlock_irqrestore(&h->lock, flags);
816 wake_up(&h->wait); 820 wake_up(&h->wait);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 76354bb1312c..47fd27031a20 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -82,6 +82,12 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction)
82static void clear_btree_io_tree(struct extent_io_tree *tree) 82static void clear_btree_io_tree(struct extent_io_tree *tree)
83{ 83{
84 spin_lock(&tree->lock); 84 spin_lock(&tree->lock);
85 /*
86 * Do a single barrier for the waitqueue_active check here, the state
87 * of the waitqueue should not change once clear_btree_io_tree is
88 * called.
89 */
90 smp_mb();
85 while (!RB_EMPTY_ROOT(&tree->state)) { 91 while (!RB_EMPTY_ROOT(&tree->state)) {
86 struct rb_node *node; 92 struct rb_node *node;
87 struct extent_state *state; 93 struct extent_state *state;
@@ -856,6 +862,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
856 atomic_dec(&cur_trans->num_writers); 862 atomic_dec(&cur_trans->num_writers);
857 extwriter_counter_dec(cur_trans, trans->type); 863 extwriter_counter_dec(cur_trans, trans->type);
858 864
865 /*
866 * Make sure counter is updated before we wake up waiters.
867 */
859 smp_mb(); 868 smp_mb();
860 if (waitqueue_active(&cur_trans->writer_wait)) 869 if (waitqueue_active(&cur_trans->writer_wait))
861 wake_up(&cur_trans->writer_wait); 870 wake_up(&cur_trans->writer_wait);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c3f9a9c71f28..1fffe8845c09 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -229,7 +229,9 @@ int btrfs_pin_log_trans(struct btrfs_root *root)
229void btrfs_end_log_trans(struct btrfs_root *root) 229void btrfs_end_log_trans(struct btrfs_root *root)
230{ 230{
231 if (atomic_dec_and_test(&root->log_writers)) { 231 if (atomic_dec_and_test(&root->log_writers)) {
232 smp_mb(); 232 /*
233 * Implicit memory barrier after atomic_dec_and_test
234 */
233 if (waitqueue_active(&root->log_writer_wait)) 235 if (waitqueue_active(&root->log_writer_wait))
234 wake_up(&root->log_writer_wait); 236 wake_up(&root->log_writer_wait);
235 } 237 }
@@ -2820,7 +2822,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2820 2822
2821 mutex_lock(&log_root_tree->log_mutex); 2823 mutex_lock(&log_root_tree->log_mutex);
2822 if (atomic_dec_and_test(&log_root_tree->log_writers)) { 2824 if (atomic_dec_and_test(&log_root_tree->log_writers)) {
2823 smp_mb(); 2825 /*
2826 * Implicit memory barrier after atomic_dec_and_test
2827 */
2824 if (waitqueue_active(&log_root_tree->log_writer_wait)) 2828 if (waitqueue_active(&log_root_tree->log_writer_wait))
2825 wake_up(&log_root_tree->log_writer_wait); 2829 wake_up(&log_root_tree->log_writer_wait);
2826 } 2830 }
@@ -2950,6 +2954,9 @@ out_wake_log_root:
2950 atomic_set(&log_root_tree->log_commit[index2], 0); 2954 atomic_set(&log_root_tree->log_commit[index2], 0);
2951 mutex_unlock(&log_root_tree->log_mutex); 2955 mutex_unlock(&log_root_tree->log_mutex);
2952 2956
2957 /*
2958 * The barrier before waitqueue_active is implied by mutex_unlock
2959 */
2953 if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) 2960 if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
2954 wake_up(&log_root_tree->log_commit_wait[index2]); 2961 wake_up(&log_root_tree->log_commit_wait[index2]);
2955out: 2962out:
@@ -2961,6 +2968,9 @@ out:
2961 atomic_set(&root->log_commit[index1], 0); 2968 atomic_set(&root->log_commit[index1], 0);
2962 mutex_unlock(&root->log_mutex); 2969 mutex_unlock(&root->log_mutex);
2963 2970
2971 /*
2972 * The barrier before waitqueue_active is implied by mutex_unlock
2973 */
2964 if (waitqueue_active(&root->log_commit_wait[index1])) 2974 if (waitqueue_active(&root->log_commit_wait[index1]))
2965 wake_up(&root->log_commit_wait[index1]); 2975 wake_up(&root->log_commit_wait[index1]);
2966 return ret; 2976 return ret;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dd644d767782..cc1cc3559045 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -344,6 +344,9 @@ loop_lock:
344 pending = pending->bi_next; 344 pending = pending->bi_next;
345 cur->bi_next = NULL; 345 cur->bi_next = NULL;
346 346
347 /*
348 * atomic_dec_return implies a barrier for waitqueue_active
349 */
347 if (atomic_dec_return(&fs_info->nr_async_bios) < limit && 350 if (atomic_dec_return(&fs_info->nr_async_bios) < limit &&
348 waitqueue_active(&fs_info->async_submit_wait)) 351 waitqueue_active(&fs_info->async_submit_wait))
349 wake_up(&fs_info->async_submit_wait); 352 wake_up(&fs_info->async_submit_wait);