diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2015-04-16 20:16:45 -0700 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:33:54 -0800 |
commit | b5fa319dcc355fddfbee35773af1d0d5d7bbb676 (patch) | |
tree | 775fa31abf34bbcf88040cc82a34eab20238afce | |
parent | d97ba2d11e9d0eafd4e23c81eb320fc044793fea (diff) |
bcache: uninline slowpath in btree_iter_traverse()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | drivers/md/bcache/btree.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 1c69d9457d69..a8e1aa5c1732 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -1301,6 +1301,42 @@ err: goto out_unlock; } +/* Slowpath, don't want it inlined into btree_iter_traverse() */ +static noinline struct btree *bch_btree_node_fill(struct btree_iter *iter, + const struct bkey_i *k, + int level) +{ + struct btree *b = mca_alloc(iter->c, k, level, iter->btree_id, + &iter->cl); + + if (IS_ERR_OR_NULL(b)) + return b; + + /* + * If the btree node wasn't cached, we can't drop our lock on + * the parent until after it's added to the cache - because + * otherwise we could race with a btree_split() freeing the node + * we're trying to lock. + * + * But the deadlock described below doesn't exist in this case, + * so it's safe to not drop the parent lock until here: + */ + if (btree_node_read_locked(iter, level + 1)) + btree_node_unlock(iter, level + 1); + + bch_btree_node_read(b); + six_unlock_write(&b->lock); + + if (btree_want_intent(iter, level)) { + mark_btree_node_intent_locked(iter, level); + } else { + mark_btree_node_read_locked(iter, level); + BUG_ON(!six_trylock_convert(&b->lock, intent, read)); + } + + return b; +} + /** * bch_btree_node_get - find a btree node in the cache and lock it, reading it * in from disk if necessary. @@ -1323,7 +1359,7 @@ retry: rcu_read_unlock(); if (unlikely(!b)) { - b = mca_alloc(iter->c, k, level, iter->btree_id, &iter->cl); + b = bch_btree_node_fill(iter, k, level); /* We raced and found the btree node in the cache */ if (!b) @@ -1333,28 +1369,6 @@ retry: BUG_ON(PTR_ERR(b) != -EAGAIN); return b; } - - /* - * If the btree node wasn't cached, we can't drop our lock on - * the parent until after it's added to the cache - because - * otherwise we could race with a btree_split() freeing the node - * we're trying to lock. - * - * But the deadlock described below doesn't exist in this case, - * so it's safe to not drop the parent lock until here: - */ - if (btree_node_read_locked(iter, level + 1)) - btree_node_unlock(iter, level + 1); - - bch_btree_node_read(b); - six_unlock_write(&b->lock); - - if (btree_want_intent(iter, level)) { - mark_btree_node_intent_locked(iter, level); - } else { - mark_btree_node_read_locked(iter, level); - BUG_ON(!six_trylock_convert(&b->lock, intent, read)); - } } else { /* * There's a potential deadlock with splits and insertions into |