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>
This commit is contained in:
Andreas Gruenbacher 2017-02-21 23:19:10 +01:00 committed by Bob Peterson
parent c369898759
commit 0a52aba7c2
1 changed files with 21 additions and 24 deletions

View File

@ -655,10 +655,10 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
struct lm_lockname name = { .ln_number = number,
.ln_type = glops->go_type,
.ln_sbd = sdp };
struct gfs2_glock *gl, *tmp = NULL;
struct gfs2_glock *gl, *tmp;
struct address_space *mapping;
struct kmem_cache *cachep;
int ret, tries = 0;
int ret = 0;
rcu_read_lock();
gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
@ -723,35 +723,32 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
}
again:
ret = rhashtable_lookup_insert_fast(&gl_hash_table, &gl->gl_node,
ht_parms);
if (ret == 0) {
rcu_read_lock();
tmp = rhashtable_lookup_get_insert_fast(&gl_hash_table, &gl->gl_node,
ht_parms);
if (!tmp) {
*glp = gl;
return 0;
goto out;
}
if (IS_ERR(tmp)) {
ret = PTR_ERR(tmp);
goto out_free;
}
if (lockref_get_not_dead(&tmp->gl_lockref)) {
*glp = tmp;
goto out_free;
}
rcu_read_unlock();
cond_resched();
goto again;
if (ret == -EEXIST) {
ret = 0;
rcu_read_lock();
tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) {
if (++tries < 100) {
rcu_read_unlock();
cond_resched();
goto again;
}
tmp = NULL;
ret = -ENOMEM;
}
rcu_read_unlock();
} else {
WARN_ON_ONCE(ret);
}
out_free:
kfree(gl->gl_lksb.sb_lvbptr);
kmem_cache_free(cachep, gl);
atomic_dec(&sdp->sd_glock_disposal);
*glp = tmp;
out:
rcu_read_unlock();
return ret;
}