summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcauth.c
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2018-10-01 16:41:44 +0200
committerJ. Bruce Fields <bfields@redhat.com>2018-10-03 17:32:59 +0200
commit608a0ab2f54ab0e301ad76a41aad979ea0d02670 (patch)
tree26382fa9fd57a2f549fb991c067c72257a2b2b61 /net/sunrpc/svcauth.c
parentSUNRPC: Remove the server 'authtab_lock' and just use RCU (diff)
downloadlinux-608a0ab2f54ab0e301ad76a41aad979ea0d02670.tar.xz
linux-608a0ab2f54ab0e301ad76a41aad979ea0d02670.zip
SUNRPC: Add lockless lookup of the server's auth domain
Avoid taking the global auth_domain_lock in most lookups of the auth domain by adding an RCU protected lookup. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/svcauth.c')
-rw-r--r--net/sunrpc/svcauth.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index f83443856cd1..775b8c94265b 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -143,10 +143,11 @@ static struct hlist_head auth_domain_table[DN_HASHMAX];
static DEFINE_SPINLOCK(auth_domain_lock);
static void auth_domain_release(struct kref *kref)
+ __releases(&auth_domain_lock)
{
struct auth_domain *dom = container_of(kref, struct auth_domain, ref);
- hlist_del(&dom->hash);
+ hlist_del_rcu(&dom->hash);
dom->flavour->domain_release(dom);
spin_unlock(&auth_domain_lock);
}
@@ -175,7 +176,7 @@ auth_domain_lookup(char *name, struct auth_domain *new)
}
}
if (new)
- hlist_add_head(&new->hash, head);
+ hlist_add_head_rcu(&new->hash, head);
spin_unlock(&auth_domain_lock);
return new;
}
@@ -183,6 +184,21 @@ EXPORT_SYMBOL_GPL(auth_domain_lookup);
struct auth_domain *auth_domain_find(char *name)
{
- return auth_domain_lookup(name, NULL);
+ struct auth_domain *hp;
+ struct hlist_head *head;
+
+ head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(hp, head, hash) {
+ if (strcmp(hp->name, name)==0) {
+ if (!kref_get_unless_zero(&hp->ref))
+ hp = NULL;
+ rcu_read_unlock();
+ return hp;
+ }
+ }
+ rcu_read_unlock();
+ return NULL;
}
EXPORT_SYMBOL_GPL(auth_domain_find);