Skip to content

Commit f2b112c

Browse files
trondmyJ. Bruce Fields
authored andcommitted
SUNRPC: Lockless server RPCSEC_GSS context lookup
Use RCU protection for looking up the RPCSEC_GSS context. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 2936bb6 commit f2b112c

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ struct rsi {
7676
struct xdr_netobj in_handle, in_token;
7777
struct xdr_netobj out_handle, out_token;
7878
int major_status, minor_status;
79+
struct rcu_head rcu_head;
7980
};
8081

8182
static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
@@ -89,13 +90,21 @@ static void rsi_free(struct rsi *rsii)
8990
kfree(rsii->out_token.data);
9091
}
9192

92-
static void rsi_put(struct kref *ref)
93+
static void rsi_free_rcu(struct rcu_head *head)
9394
{
94-
struct rsi *rsii = container_of(ref, struct rsi, h.ref);
95+
struct rsi *rsii = container_of(head, struct rsi, rcu_head);
96+
9597
rsi_free(rsii);
9698
kfree(rsii);
9799
}
98100

101+
static void rsi_put(struct kref *ref)
102+
{
103+
struct rsi *rsii = container_of(ref, struct rsi, h.ref);
104+
105+
call_rcu(&rsii->rcu_head, rsi_free_rcu);
106+
}
107+
99108
static inline int rsi_hash(struct rsi *item)
100109
{
101110
return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
@@ -282,7 +291,7 @@ static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
282291
struct cache_head *ch;
283292
int hash = rsi_hash(item);
284293

285-
ch = sunrpc_cache_lookup(cd, &item->h, hash);
294+
ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
286295
if (ch)
287296
return container_of(ch, struct rsi, h);
288297
else
@@ -330,6 +339,7 @@ struct rsc {
330339
struct svc_cred cred;
331340
struct gss_svc_seq_data seqdata;
332341
struct gss_ctx *mechctx;
342+
struct rcu_head rcu_head;
333343
};
334344

335345
static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
@@ -343,12 +353,22 @@ static void rsc_free(struct rsc *rsci)
343353
free_svc_cred(&rsci->cred);
344354
}
345355

356+
static void rsc_free_rcu(struct rcu_head *head)
357+
{
358+
struct rsc *rsci = container_of(head, struct rsc, rcu_head);
359+
360+
kfree(rsci->handle.data);
361+
kfree(rsci);
362+
}
363+
346364
static void rsc_put(struct kref *ref)
347365
{
348366
struct rsc *rsci = container_of(ref, struct rsc, h.ref);
349367

350-
rsc_free(rsci);
351-
kfree(rsci);
368+
if (rsci->mechctx)
369+
gss_delete_sec_context(&rsci->mechctx);
370+
free_svc_cred(&rsci->cred);
371+
call_rcu(&rsci->rcu_head, rsc_free_rcu);
352372
}
353373

354374
static inline int
@@ -542,7 +562,7 @@ static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
542562
struct cache_head *ch;
543563
int hash = rsc_hash(item);
544564

545-
ch = sunrpc_cache_lookup(cd, &item->h, hash);
565+
ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
546566
if (ch)
547567
return container_of(ch, struct rsc, h);
548568
else

0 commit comments

Comments
 (0)