diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2017-02-21 17:19:10 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2017-04-03 09:14:41 -0400 |
commit | 0a52aba7c2168636fc71635cf3ccb92a79a96c38 (patch) | |
tree | a6d611d27d4c2a91e894165e71f31488e442ccd8 | |
parent | c369898759e0e143a513d022121290370f001d01 (diff) |
gfs2: Switch to rhashtable_lookup_get_insert_fast
Switch from rhashtable_lookup_insert_fast + rhashtable_lookup_fast to
rhashtable_lookup_get_insert_fast, which is cleaner and avoids an extra
rhashtable lookup.
At the same time, turn the retry loop in gfs2_glock_get into an infinite
loop. The lookup or insert will eventually succeed, usually very fast,
but there is no reason to give up trying at a fixed number of
iterations.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
-rw-r--r-- | fs/gfs2/glock.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 35f3b0a1d81b..9e81219692c4 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -655,10 +655,10 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
655 | struct lm_lockname name = { .ln_number = number, | 655 | struct lm_lockname name = { .ln_number = number, |
656 | .ln_type = glops->go_type, | 656 | .ln_type = glops->go_type, |
657 | .ln_sbd = sdp }; | 657 | .ln_sbd = sdp }; |
658 | struct gfs2_glock *gl, *tmp = NULL; | 658 | struct gfs2_glock *gl, *tmp; |
659 | struct address_space *mapping; | 659 | struct address_space *mapping; |
660 | struct kmem_cache *cachep; | 660 | struct kmem_cache *cachep; |
661 | int ret, tries = 0; | 661 | int ret = 0; |
662 | 662 | ||
663 | rcu_read_lock(); | 663 | rcu_read_lock(); |
664 | gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); | 664 | gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); |
@@ -723,35 +723,32 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
723 | } | 723 | } |
724 | 724 | ||
725 | again: | 725 | again: |
726 | ret = rhashtable_lookup_insert_fast(&gl_hash_table, &gl->gl_node, | 726 | rcu_read_lock(); |
727 | ht_parms); | 727 | tmp = rhashtable_lookup_get_insert_fast(&gl_hash_table, &gl->gl_node, |
728 | if (ret == 0) { | 728 | ht_parms); |
729 | if (!tmp) { | ||
729 | *glp = gl; | 730 | *glp = gl; |
730 | return 0; | 731 | goto out; |
731 | } | 732 | } |
732 | 733 | if (IS_ERR(tmp)) { | |
733 | if (ret == -EEXIST) { | 734 | ret = PTR_ERR(tmp); |
734 | ret = 0; | 735 | goto out_free; |
735 | rcu_read_lock(); | 736 | } |
736 | tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); | 737 | if (lockref_get_not_dead(&tmp->gl_lockref)) { |
737 | if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) { | 738 | *glp = tmp; |
738 | if (++tries < 100) { | 739 | goto out_free; |
739 | rcu_read_unlock(); | ||
740 | cond_resched(); | ||
741 | goto again; | ||
742 | } | ||
743 | tmp = NULL; | ||
744 | ret = -ENOMEM; | ||
745 | } | ||
746 | rcu_read_unlock(); | ||
747 | } else { | ||
748 | WARN_ON_ONCE(ret); | ||
749 | } | 740 | } |
741 | rcu_read_unlock(); | ||
742 | cond_resched(); | ||
743 | goto again; | ||
744 | |||
745 | out_free: | ||
750 | kfree(gl->gl_lksb.sb_lvbptr); | 746 | kfree(gl->gl_lksb.sb_lvbptr); |
751 | kmem_cache_free(cachep, gl); | 747 | kmem_cache_free(cachep, gl); |
752 | atomic_dec(&sdp->sd_glock_disposal); | 748 | atomic_dec(&sdp->sd_glock_disposal); |
753 | *glp = tmp; | ||
754 | 749 | ||
750 | out: | ||
751 | rcu_read_unlock(); | ||
755 | return ret; | 752 | return ret; |
756 | } | 753 | } |
757 | 754 | ||