aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2017-02-21 17:19:10 -0500
committerBob Peterson <rpeterso@redhat.com>2017-04-03 09:14:41 -0400
commit0a52aba7c2168636fc71635cf3ccb92a79a96c38 (patch)
treea6d611d27d4c2a91e894165e71f31488e442ccd8
parentc369898759e0e143a513d022121290370f001d01 (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.c45
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
725again: 725again:
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
745out_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
750out:
751 rcu_read_unlock();
755 return ret; 752 return ret;
756} 753}
757 754