* [PATCH 0/6] Extent buffer locking cleanups, part 1 @ 2019-01-23 17:37 David Sterba 2019-01-23 17:38 ` [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers David Sterba ` (5 more replies) 0 siblings, 6 replies; 13+ messages in thread From: David Sterba @ 2019-01-23 17:37 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba This series cleans up a few locking helpers, removes conditional switches by read/write type where not necessary and updates the callers. No changes expected, other than tiny speedups resulting from smaller code. David Sterba (6): btrfs: split btrfs_set_lock_blocking_rw to read and write helpers btrfs: split btrfs_clear_lock_blocking_rw to read and write helpers btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers btrfs: open code now trivial btrfs_set_lock_blocking btrfs: simplify waiting loop in btrfs_tree_lock btrfs: merge btrfs_set_lock_blocking_rw with it's caller fs/btrfs/backref.c | 4 +- fs/btrfs/ctree.c | 39 +++++++++------ fs/btrfs/disk-io.c | 4 +- fs/btrfs/extent-tree.c | 14 +++--- fs/btrfs/locking.c | 108 ++++++++++++++++++++--------------------- fs/btrfs/locking.h | 15 ++---- fs/btrfs/qgroup.c | 6 +-- fs/btrfs/ref-verify.c | 4 +- fs/btrfs/relocation.c | 8 +-- fs/btrfs/transaction.c | 2 +- fs/btrfs/tree-defrag.c | 2 +- fs/btrfs/tree-log.c | 6 +-- 12 files changed, 105 insertions(+), 107 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:05 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw " David Sterba ` (4 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba There are many callers that hardcode the desired lock type so we can avoid the switch and call them directly. Split the current function to two but leave a helper that still takes the variable lock type to make current code compile. The call sites will be converted in followup patches. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/locking.c | 50 ++++++++++++++++++++++++---------------------- fs/btrfs/locking.h | 15 +++++++++++++- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 1da768e5ef75..7201d000f61d 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -14,35 +14,37 @@ static void btrfs_assert_tree_read_locked(struct extent_buffer *eb); -/* - * if we currently have a spinning reader or writer lock - * (indicated by the rw flag) this will bump the count - * of blocking holders and drop the spinlock. - */ -void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) +void btrfs_set_lock_blocking_read(struct extent_buffer *eb) { /* - * no lock is required. The lock owner may change if - * we have a read lock, but it won't change to or away - * from us. If we have the write lock, we are the owner - * and it'll never change. + * No lock is required. The lock owner may change if we have a read + * lock, but it won't change to or away from us. If we have the write + * lock, we are the owner and it'll never change. */ if (eb->lock_nested && current->pid == eb->lock_owner) return; - if (rw == BTRFS_WRITE_LOCK) { - if (atomic_read(&eb->blocking_writers) == 0) { - WARN_ON(atomic_read(&eb->spinning_writers) != 1); - atomic_dec(&eb->spinning_writers); - btrfs_assert_tree_locked(eb); - atomic_inc(&eb->blocking_writers); - write_unlock(&eb->lock); - } - } else if (rw == BTRFS_READ_LOCK) { - btrfs_assert_tree_read_locked(eb); - atomic_inc(&eb->blocking_readers); - WARN_ON(atomic_read(&eb->spinning_readers) == 0); - atomic_dec(&eb->spinning_readers); - read_unlock(&eb->lock); + btrfs_assert_tree_read_locked(eb); + atomic_inc(&eb->blocking_readers); + WARN_ON(atomic_read(&eb->spinning_readers) == 0); + atomic_dec(&eb->spinning_readers); + read_unlock(&eb->lock); +} + +void btrfs_set_lock_blocking_write(struct extent_buffer *eb) +{ + /* + * No lock is required. The lock owner may change if we have a read + * lock, but it won't change to or away from us. If we have the write + * lock, we are the owner and it'll never change. + */ + if (eb->lock_nested && current->pid == eb->lock_owner) + return; + if (atomic_read(&eb->blocking_writers) == 0) { + WARN_ON(atomic_read(&eb->spinning_writers) != 1); + atomic_dec(&eb->spinning_writers); + btrfs_assert_tree_locked(eb); + atomic_inc(&eb->blocking_writers); + write_unlock(&eb->lock); } } diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 29135def468e..0453a4797693 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -17,7 +17,8 @@ void btrfs_tree_unlock(struct extent_buffer *eb); void btrfs_tree_read_lock(struct extent_buffer *eb); void btrfs_tree_read_unlock(struct extent_buffer *eb); void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb); -void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw); +void btrfs_set_lock_blocking_read(struct extent_buffer *eb); +void btrfs_set_lock_blocking_write(struct extent_buffer *eb); void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw); void btrfs_assert_tree_locked(struct extent_buffer *eb); int btrfs_try_tree_read_lock(struct extent_buffer *eb); @@ -37,6 +38,18 @@ static inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw) BUG(); } +/* + * If we currently have a spinning reader or writer lock (indicated by the rw + * flag) this will bump the count of blocking holders and drop the spinlock. + */ +static inline void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) +{ + if (rw == BTRFS_WRITE_LOCK) + btrfs_set_lock_blocking_write(eb); + else if (rw == BTRFS_READ_LOCK) + btrfs_set_lock_blocking_read(eb); +} + static inline void btrfs_set_lock_blocking(struct extent_buffer *eb) { btrfs_set_lock_blocking_rw(eb, BTRFS_WRITE_LOCK); -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers 2019-01-23 17:38 ` [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers David Sterba @ 2019-01-24 9:05 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:05 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw to read and write helpers 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba 2019-01-23 17:38 ` [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:06 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers David Sterba ` (3 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba There are many callers that hardcode the desired lock type so we can avoid the switch and call them directly. Split the current function to two. There are no remaining users of btrfs_clear_lock_blocking_rw so it's removed. The call sites will be converted in followup patches. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/locking.c | 47 ++++++++++++++++++++++++---------------------- fs/btrfs/locking.h | 7 ++----- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 7201d000f61d..7f89ca6f1fbc 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -48,11 +48,24 @@ void btrfs_set_lock_blocking_write(struct extent_buffer *eb) } } -/* - * if we currently have a blocking lock, take the spinlock - * and drop our blocking count - */ -void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) +void btrfs_clear_lock_blocking_read(struct extent_buffer *eb) +{ + /* + * No lock is required. The lock owner may change if we have a read + * lock, but it won't change to or away from us. If we have the write + * lock, we are the owner and it'll never change. + */ + if (eb->lock_nested && current->pid == eb->lock_owner) + return; + BUG_ON(atomic_read(&eb->blocking_readers) == 0); + read_lock(&eb->lock); + atomic_inc(&eb->spinning_readers); + /* atomic_dec_and_test implies a barrier */ + if (atomic_dec_and_test(&eb->blocking_readers)) + cond_wake_up_nomb(&eb->read_lock_wq); +} + +void btrfs_clear_lock_blocking_write(struct extent_buffer *eb) { /* * no lock is required. The lock owner may change if @@ -62,23 +75,13 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) */ if (eb->lock_nested && current->pid == eb->lock_owner) return; - - if (rw == BTRFS_WRITE_LOCK_BLOCKING) { - BUG_ON(atomic_read(&eb->blocking_writers) != 1); - write_lock(&eb->lock); - WARN_ON(atomic_read(&eb->spinning_writers)); - atomic_inc(&eb->spinning_writers); - /* atomic_dec_and_test implies a barrier */ - if (atomic_dec_and_test(&eb->blocking_writers)) - cond_wake_up_nomb(&eb->write_lock_wq); - } else if (rw == BTRFS_READ_LOCK_BLOCKING) { - BUG_ON(atomic_read(&eb->blocking_readers) == 0); - read_lock(&eb->lock); - atomic_inc(&eb->spinning_readers); - /* atomic_dec_and_test implies a barrier */ - if (atomic_dec_and_test(&eb->blocking_readers)) - cond_wake_up_nomb(&eb->read_lock_wq); - } + BUG_ON(atomic_read(&eb->blocking_writers) != 1); + write_lock(&eb->lock); + WARN_ON(atomic_read(&eb->spinning_writers)); + atomic_inc(&eb->spinning_writers); + /* atomic_dec_and_test implies a barrier */ + if (atomic_dec_and_test(&eb->blocking_writers)) + cond_wake_up_nomb(&eb->write_lock_wq); } /* diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 0453a4797693..3f81d6900c71 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -19,7 +19,8 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb); void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb); void btrfs_set_lock_blocking_read(struct extent_buffer *eb); void btrfs_set_lock_blocking_write(struct extent_buffer *eb); -void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw); +void btrfs_clear_lock_blocking_read(struct extent_buffer *eb); +void btrfs_clear_lock_blocking_write(struct extent_buffer *eb); void btrfs_assert_tree_locked(struct extent_buffer *eb); int btrfs_try_tree_read_lock(struct extent_buffer *eb); int btrfs_try_tree_write_lock(struct extent_buffer *eb); @@ -55,8 +56,4 @@ static inline void btrfs_set_lock_blocking(struct extent_buffer *eb) btrfs_set_lock_blocking_rw(eb, BTRFS_WRITE_LOCK); } -static inline void btrfs_clear_lock_blocking(struct extent_buffer *eb) -{ - btrfs_clear_lock_blocking_rw(eb, BTRFS_WRITE_LOCK_BLOCKING); -} #endif -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw to read and write helpers 2019-01-23 17:38 ` [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw " David Sterba @ 2019-01-24 9:06 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:06 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba 2019-01-23 17:38 ` [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers David Sterba 2019-01-23 17:38 ` [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw " David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:06 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking David Sterba ` (2 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba We can use the right helper where the lock type is a fixed parameter. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/backref.c | 4 ++-- fs/btrfs/ctree.c | 4 ++-- fs/btrfs/disk-io.c | 2 +- fs/btrfs/locking.h | 2 +- fs/btrfs/qgroup.c | 6 +++--- fs/btrfs/ref-verify.c | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 78556447e1d5..136454dbb4af 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1289,7 +1289,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, goto out; } btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); ret = find_extent_in_eb(eb, bytenr, *extent_item_pos, &eie, ignore_offset); btrfs_tree_read_unlock_blocking(eb); @@ -1650,7 +1650,7 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, /* make sure we can use eb after releasing the path */ if (eb != eb_in) { if (!path->skip_locking) - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); path->nodes[0] = NULL; path->locks[0] = 0; } diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index f64aad613727..a9c957c1e2b9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1266,7 +1266,7 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct btrfs_path *path, return eb; btrfs_set_path_blocking(path); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) { BUG_ON(tm->slot != 0); @@ -1356,7 +1356,7 @@ get_old_root(struct btrfs_root *root, u64 time_seq) free_extent_buffer(eb_root); eb = alloc_dummy_extent_buffer(fs_info, logical); } else { - btrfs_set_lock_blocking_rw(eb_root, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb_root); eb = btrfs_clone_extent_buffer(eb_root); btrfs_tree_read_unlock_blocking(eb_root); free_extent_buffer(eb_root); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6a2a2a951705..ba369b502f4e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -341,7 +341,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, if (need_lock) { btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); } lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 3f81d6900c71..9d9f649e35cc 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -53,7 +53,7 @@ static inline void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) static inline void btrfs_set_lock_blocking(struct extent_buffer *eb) { - btrfs_set_lock_blocking_rw(eb, BTRFS_WRITE_LOCK); + btrfs_set_lock_blocking_write(eb); } #endif diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 4e473a998219..fa9e07e79516 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1832,7 +1832,7 @@ static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans, src_path->nodes[cur_level] = eb; btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); src_path->locks[cur_level] = BTRFS_READ_LOCK_BLOCKING; } @@ -1973,7 +1973,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans, dst_path->slots[cur_level] = 0; btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); dst_path->locks[cur_level] = BTRFS_READ_LOCK_BLOCKING; need_cleanup = true; } @@ -2207,7 +2207,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans, path->slots[level] = 0; btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); path->locks[level] = BTRFS_READ_LOCK_BLOCKING; ret = btrfs_qgroup_trace_extent(trans, child_bytenr, diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c index c3557c12656b..d09b6cdb785a 100644 --- a/fs/btrfs/ref-verify.c +++ b/fs/btrfs/ref-verify.c @@ -583,7 +583,7 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path, return -EIO; } btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); path->nodes[level-1] = eb; path->slots[level-1] = 0; path->locks[level-1] = BTRFS_READ_LOCK_BLOCKING; @@ -987,7 +987,7 @@ int btrfs_build_ref_tree(struct btrfs_fs_info *fs_info) return -ENOMEM; eb = btrfs_read_lock_root_node(fs_info->extent_root); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); + btrfs_set_lock_blocking_read(eb); level = btrfs_header_level(eb); path->nodes[level] = eb; path->slots[level] = 0; -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers 2019-01-23 17:38 ` [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers David Sterba @ 2019-01-24 9:06 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:06 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba ` (2 preceding siblings ...) 2019-01-23 17:38 ` [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:07 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock David Sterba 2019-01-23 17:38 ` [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller David Sterba 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba btrfs_set_lock_blocking is now only a simple wrapper around btrfs_set_lock_blocking_write. The name does not bring any semantic value that could not be inferred from the new function so there's no point keeping it. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/ctree.c | 22 +++++++++++----------- fs/btrfs/disk-io.c | 2 +- fs/btrfs/extent-tree.c | 14 +++++++------- fs/btrfs/locking.h | 5 ----- fs/btrfs/relocation.c | 8 ++++---- fs/btrfs/transaction.c | 2 +- fs/btrfs/tree-defrag.c | 2 +- fs/btrfs/tree-log.c | 6 +++--- 8 files changed, 28 insertions(+), 33 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index a9c957c1e2b9..a482171fd710 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1464,8 +1464,8 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, search_start = buf->start & ~((u64)SZ_1G - 1); if (parent) - btrfs_set_lock_blocking(parent); - btrfs_set_lock_blocking(buf); + btrfs_set_lock_blocking_write(parent); + btrfs_set_lock_blocking_write(buf); ret = __btrfs_cow_block(trans, root, buf, parent, parent_slot, cow_ret, search_start, 0); @@ -1560,7 +1560,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, if (parent_nritems <= 1) return 0; - btrfs_set_lock_blocking(parent); + btrfs_set_lock_blocking_write(parent); for (i = start_slot; i <= end_slot; i++) { struct btrfs_key first_key; @@ -1619,7 +1619,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, search_start = last_block; btrfs_tree_lock(cur); - btrfs_set_lock_blocking(cur); + btrfs_set_lock_blocking_write(cur); err = __btrfs_cow_block(trans, root, cur, parent, i, &cur, search_start, min(16 * blocksize, @@ -1834,7 +1834,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, } btrfs_tree_lock(child); - btrfs_set_lock_blocking(child); + btrfs_set_lock_blocking_write(child); ret = btrfs_cow_block(trans, root, child, mid, 0, &child); if (ret) { btrfs_tree_unlock(child); @@ -1872,7 +1872,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (left) { btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); + btrfs_set_lock_blocking_write(left); wret = btrfs_cow_block(trans, root, left, parent, pslot - 1, &left); if (wret) { @@ -1887,7 +1887,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (right) { btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); + btrfs_set_lock_blocking_write(right); wret = btrfs_cow_block(trans, root, right, parent, pslot + 1, &right); if (wret) { @@ -2050,7 +2050,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, u32 left_nr; btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); + btrfs_set_lock_blocking_write(left); left_nr = btrfs_header_nritems(left); if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) { @@ -2105,7 +2105,7 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, u32 right_nr; btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); + btrfs_set_lock_blocking_write(right); right_nr = btrfs_header_nritems(right); if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) { @@ -3749,7 +3749,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root return 1; btrfs_tree_lock(right); - btrfs_set_lock_blocking(right); + btrfs_set_lock_blocking_write(right); free_space = btrfs_leaf_free_space(fs_info, right); if (free_space < data_size) @@ -3983,7 +3983,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root return 1; btrfs_tree_lock(left); - btrfs_set_lock_blocking(left); + btrfs_set_lock_blocking_write(left); free_space = btrfs_leaf_free_space(fs_info, left); if (free_space < data_size) { diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ba369b502f4e..e64afc78ed27 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1120,7 +1120,7 @@ void clean_tree_block(struct btrfs_fs_info *fs_info, -buf->len, fs_info->dirty_metadata_batch); /* ugh, clear_extent_buffer_dirty needs to lock the page */ - btrfs_set_lock_blocking(buf); + btrfs_set_lock_blocking_write(buf); clear_extent_buffer_dirty(buf); } } diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d81035b7ea7d..39f10f1099a0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -8492,7 +8492,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, clean_tree_block(fs_info, buf); clear_bit(EXTENT_BUFFER_STALE, &buf->bflags); - btrfs_set_lock_blocking(buf); + btrfs_set_lock_blocking_write(buf); set_extent_buffer_uptodate(buf); memzero_extent_buffer(buf, 0, sizeof(struct btrfs_header)); @@ -8917,7 +8917,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, reada = 1; } btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); + btrfs_set_lock_blocking_write(next); ret = btrfs_lookup_extent_info(trans, fs_info, bytenr, level - 1, 1, &wc->refs[level - 1], @@ -8977,7 +8977,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, return -EIO; } btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); + btrfs_set_lock_blocking_write(next); } level--; @@ -9089,7 +9089,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, if (!path->locks[level]) { BUG_ON(level == 0); btrfs_tree_lock(eb); - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; ret = btrfs_lookup_extent_info(trans, fs_info, @@ -9131,7 +9131,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, if (!path->locks[level] && btrfs_header_generation(eb) == trans->transid) { btrfs_tree_lock(eb); - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; } clean_tree_block(fs_info, eb); @@ -9298,7 +9298,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { level = btrfs_header_level(root->node); path->nodes[level] = btrfs_lock_root_node(root); - btrfs_set_lock_blocking(path->nodes[level]); + btrfs_set_lock_blocking_write(path->nodes[level]); path->slots[level] = 0; path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; memset(&wc->update_progress, 0, @@ -9328,7 +9328,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, level = btrfs_header_level(root->node); while (1) { btrfs_tree_lock(path->nodes[level]); - btrfs_set_lock_blocking(path->nodes[level]); + btrfs_set_lock_blocking_write(path->nodes[level]); path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; ret = btrfs_lookup_extent_info(trans, fs_info, diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 9d9f649e35cc..84ea6ed60047 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -51,9 +51,4 @@ static inline void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) btrfs_set_lock_blocking_read(eb); } -static inline void btrfs_set_lock_blocking(struct extent_buffer *eb) -{ - btrfs_set_lock_blocking_write(eb); -} - #endif diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 272b287f8cf0..5a2096f76a35 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -1773,7 +1773,7 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, btrfs_node_key_to_cpu(path->nodes[lowest_level], &key, slot); eb = btrfs_lock_root_node(dest); - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); level = btrfs_header_level(eb); if (level < lowest_level) { @@ -1786,7 +1786,7 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, ret = btrfs_cow_block(trans, dest, eb, NULL, 0, &eb); BUG_ON(ret); } - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); if (next_key) { next_key->objectid = (u64)-1; @@ -1852,7 +1852,7 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, slot, &eb); BUG_ON(ret); } - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); btrfs_tree_unlock(parent); free_extent_buffer(parent); @@ -2752,7 +2752,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, goto next; } btrfs_tree_lock(eb); - btrfs_set_lock_blocking(eb); + btrfs_set_lock_blocking_write(eb); if (!node->eb) { ret = btrfs_cow_block(trans, root, eb, upper->eb, diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 127fa1535f58..3e96e2bd3136 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1540,7 +1540,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, goto fail; } - btrfs_set_lock_blocking(old); + btrfs_set_lock_blocking_write(old); ret = btrfs_copy_root(trans, root, old, &tmp, objectid); /* clean up in any case */ diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index 3c0987ab587d..5f9e2dd413af 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c @@ -52,7 +52,7 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, u32 nritems; root_node = btrfs_lock_root_node(root); - btrfs_set_lock_blocking(root_node); + btrfs_set_lock_blocking_write(root_node); nritems = btrfs_header_nritems(root_node); root->defrag_max.objectid = 0; /* from above we know this is not a leaf */ diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index ac232b3d6d7e..1a69a45ae926 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2663,7 +2663,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, if (trans) { btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); + btrfs_set_lock_blocking_write(next); clean_tree_block(fs_info, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -2747,7 +2747,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, if (trans) { btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); + btrfs_set_lock_blocking_write(next); clean_tree_block(fs_info, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); @@ -2829,7 +2829,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, if (trans) { btrfs_tree_lock(next); - btrfs_set_lock_blocking(next); + btrfs_set_lock_blocking_write(next); clean_tree_block(fs_info, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking 2019-01-23 17:38 ` [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking David Sterba @ 2019-01-24 9:07 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:07 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba ` (3 preceding siblings ...) 2019-01-23 17:38 ` [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:08 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller David Sterba 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Currently, the number of readers and writers is checked and in case there are any, wait and redo the locks. There's some duplication before the branches go back to again label, eg. calling wait_event on blocking_readers twice. The sequence is transformed loop: * wait for readers * wait for writers * write_lock * check readers, unlock and wait for readers, loop * check writers, unlock and wait for writers, loop The new sequence is not exactly the same due to the simplification, for readers it's slightly faster. For the writers, original code does * wait for writers * (loop) wait for readers * wait for writers -- again while the new goes directly to the reader check. This should behave the same on a contended lock with multiple writers and readers, but can reduce number of times we're waiting on something. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/locking.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 7f89ca6f1fbc..82b84e4daad1 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -237,16 +237,9 @@ void btrfs_tree_lock(struct extent_buffer *eb) wait_event(eb->read_lock_wq, atomic_read(&eb->blocking_readers) == 0); wait_event(eb->write_lock_wq, atomic_read(&eb->blocking_writers) == 0); write_lock(&eb->lock); - if (atomic_read(&eb->blocking_readers)) { + if (atomic_read(&eb->blocking_readers) || + atomic_read(&eb->blocking_writers)) { write_unlock(&eb->lock); - wait_event(eb->read_lock_wq, - atomic_read(&eb->blocking_readers) == 0); - goto again; - } - if (atomic_read(&eb->blocking_writers)) { - write_unlock(&eb->lock); - wait_event(eb->write_lock_wq, - atomic_read(&eb->blocking_writers) == 0); goto again; } WARN_ON(atomic_read(&eb->spinning_writers)); -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock 2019-01-23 17:38 ` [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock David Sterba @ 2019-01-24 9:08 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:08 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba ` (4 preceding siblings ...) 2019-01-23 17:38 ` [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock David Sterba @ 2019-01-23 17:38 ` David Sterba 2019-01-24 9:08 ` Johannes Thumshirn 5 siblings, 1 reply; 13+ messages in thread From: David Sterba @ 2019-01-23 17:38 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba The last caller that does not have a fixed value of lock is btrfs_set_path_blocking, that actually does the same conditional swtich by the lock type so we can merge the branches together and remove the helper. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/ctree.c | 13 ++++++++++--- fs/btrfs/locking.h | 12 ------------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index a482171fd710..1f2917da89ef 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -45,11 +45,18 @@ noinline void btrfs_set_path_blocking(struct btrfs_path *p) for (i = 0; i < BTRFS_MAX_LEVEL; i++) { if (!p->nodes[i] || !p->locks[i]) continue; - btrfs_set_lock_blocking_rw(p->nodes[i], p->locks[i]); - if (p->locks[i] == BTRFS_READ_LOCK) + /* + * If we currently have a spinning reader or writer lock this + * will bump the count of blocking holders and drop the + * spinlock. + */ + if (p->locks[i] == BTRFS_READ_LOCK) { + btrfs_set_lock_blocking_read(p->nodes[i]); p->locks[i] = BTRFS_READ_LOCK_BLOCKING; - else if (p->locks[i] == BTRFS_WRITE_LOCK) + } else if (p->locks[i] == BTRFS_WRITE_LOCK) { + btrfs_set_lock_blocking_write(p->nodes[i]); p->locks[i] = BTRFS_WRITE_LOCK_BLOCKING; + } } } diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 84ea6ed60047..595014f64830 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h @@ -39,16 +39,4 @@ static inline void btrfs_tree_unlock_rw(struct extent_buffer *eb, int rw) BUG(); } -/* - * If we currently have a spinning reader or writer lock (indicated by the rw - * flag) this will bump the count of blocking holders and drop the spinlock. - */ -static inline void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) -{ - if (rw == BTRFS_WRITE_LOCK) - btrfs_set_lock_blocking_write(eb); - else if (rw == BTRFS_READ_LOCK) - btrfs_set_lock_blocking_read(eb); -} - #endif -- 2.20.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller 2019-01-23 17:38 ` [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller David Sterba @ 2019-01-24 9:08 ` Johannes Thumshirn 0 siblings, 0 replies; 13+ messages in thread From: Johannes Thumshirn @ 2019-01-24 9:08 UTC (permalink / raw) To: David Sterba, linux-btrfs Looks good, Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> -- Johannes Thumshirn SUSE Labs Filesystems jthumshirn@suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2019-01-24 9:09 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-01-23 17:37 [PATCH 0/6] Extent buffer locking cleanups, part 1 David Sterba 2019-01-23 17:38 ` [PATCH 1/6] btrfs: split btrfs_set_lock_blocking_rw to read and write helpers David Sterba 2019-01-24 9:05 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 2/6] btrfs: split btrfs_clear_lock_blocking_rw " David Sterba 2019-01-24 9:06 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 3/6] btrfs: replace btrfs_set_lock_blocking_rw with appropriate helpers David Sterba 2019-01-24 9:06 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 4/6] btrfs: open code now trivial btrfs_set_lock_blocking David Sterba 2019-01-24 9:07 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 5/6] btrfs: simplify waiting loop in btrfs_tree_lock David Sterba 2019-01-24 9:08 ` Johannes Thumshirn 2019-01-23 17:38 ` [PATCH 6/6] btrfs: merge btrfs_set_lock_blocking_rw with it's caller David Sterba 2019-01-24 9:08 ` Johannes Thumshirn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).