Skip to content

Commit 30382d6

Browse files
trondmyJ. Bruce Fields
authored andcommitted
SUNRPC: Remove the server 'authtab_lock' and just use RCU
Module removal is RCU safe by design, so we really have no need to lock the 'authtab[]' array. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 7d20b6a commit 30382d6

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

net/sunrpc/svcauth.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,32 @@
2727
extern struct auth_ops svcauth_null;
2828
extern struct auth_ops svcauth_unix;
2929

30-
static DEFINE_SPINLOCK(authtab_lock);
31-
static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
32-
[0] = &svcauth_null,
33-
[1] = &svcauth_unix,
30+
static struct auth_ops __rcu *authtab[RPC_AUTH_MAXFLAVOR] = {
31+
[RPC_AUTH_NULL] = (struct auth_ops __force __rcu *)&svcauth_null,
32+
[RPC_AUTH_UNIX] = (struct auth_ops __force __rcu *)&svcauth_unix,
3433
};
3534

35+
static struct auth_ops *
36+
svc_get_auth_ops(rpc_authflavor_t flavor)
37+
{
38+
struct auth_ops *aops;
39+
40+
if (flavor >= RPC_AUTH_MAXFLAVOR)
41+
return NULL;
42+
rcu_read_lock();
43+
aops = rcu_dereference(authtab[flavor]);
44+
if (aops != NULL && !try_module_get(aops->owner))
45+
aops = NULL;
46+
rcu_read_unlock();
47+
return aops;
48+
}
49+
50+
static void
51+
svc_put_auth_ops(struct auth_ops *aops)
52+
{
53+
module_put(aops->owner);
54+
}
55+
3656
int
3757
svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
3858
{
@@ -45,14 +65,11 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
4565

4666
dprintk("svc: svc_authenticate (%d)\n", flavor);
4767

48-
spin_lock(&authtab_lock);
49-
if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor]) ||
50-
!try_module_get(aops->owner)) {
51-
spin_unlock(&authtab_lock);
68+
aops = svc_get_auth_ops(flavor);
69+
if (aops == NULL) {
5270
*authp = rpc_autherr_badcred;
5371
return SVC_DENIED;
5472
}
55-
spin_unlock(&authtab_lock);
5673

5774
rqstp->rq_auth_slack = 0;
5875
init_svc_cred(&rqstp->rq_cred);
@@ -82,32 +99,31 @@ int svc_authorise(struct svc_rqst *rqstp)
8299

83100
if (aops) {
84101
rv = aops->release(rqstp);
85-
module_put(aops->owner);
102+
svc_put_auth_ops(aops);
86103
}
87104
return rv;
88105
}
89106

90107
int
91108
svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
92109
{
110+
struct auth_ops *old;
93111
int rv = -EINVAL;
94-
spin_lock(&authtab_lock);
95-
if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
96-
authtab[flavor] = aops;
97-
rv = 0;
112+
113+
if (flavor < RPC_AUTH_MAXFLAVOR) {
114+
old = cmpxchg((struct auth_ops ** __force)&authtab[flavor], NULL, aops);
115+
if (old == NULL || old == aops)
116+
rv = 0;
98117
}
99-
spin_unlock(&authtab_lock);
100118
return rv;
101119
}
102120
EXPORT_SYMBOL_GPL(svc_auth_register);
103121

104122
void
105123
svc_auth_unregister(rpc_authflavor_t flavor)
106124
{
107-
spin_lock(&authtab_lock);
108125
if (flavor < RPC_AUTH_MAXFLAVOR)
109-
authtab[flavor] = NULL;
110-
spin_unlock(&authtab_lock);
126+
rcu_assign_pointer(authtab[flavor], NULL);
111127
}
112128
EXPORT_SYMBOL_GPL(svc_auth_unregister);
113129

0 commit comments

Comments
 (0)