aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2018-10-01 10:41:48 -0400
committerJ. Bruce Fields <bfields@redhat.com>2018-10-29 16:58:04 -0400
commit6d1616b26cd91f2502111d098cd9c288dbafe5c8 (patch)
tree85d9039a2c1288cdbccafa18f387bcfb40ae441e
parent9ceddd9da13434a5906255c0fc528c385aded283 (diff)
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>
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 87c71fb0f0ea..1ece4bc3eb8d 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -76,6 +76,7 @@ struct rsi {
76 struct xdr_netobj in_handle, in_token; 76 struct xdr_netobj in_handle, in_token;
77 struct xdr_netobj out_handle, out_token; 77 struct xdr_netobj out_handle, out_token;
78 int major_status, minor_status; 78 int major_status, minor_status;
79 struct rcu_head rcu_head;
79}; 80};
80 81
81static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old); 82static 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)
89 kfree(rsii->out_token.data); 90 kfree(rsii->out_token.data);
90} 91}
91 92
92static void rsi_put(struct kref *ref) 93static void rsi_free_rcu(struct rcu_head *head)
93{ 94{
94 struct rsi *rsii = container_of(ref, struct rsi, h.ref); 95 struct rsi *rsii = container_of(head, struct rsi, rcu_head);
96
95 rsi_free(rsii); 97 rsi_free(rsii);
96 kfree(rsii); 98 kfree(rsii);
97} 99}
98 100
101static 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
99static inline int rsi_hash(struct rsi *item) 108static inline int rsi_hash(struct rsi *item)
100{ 109{
101 return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS) 110 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)
282 struct cache_head *ch; 291 struct cache_head *ch;
283 int hash = rsi_hash(item); 292 int hash = rsi_hash(item);
284 293
285 ch = sunrpc_cache_lookup(cd, &item->h, hash); 294 ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
286 if (ch) 295 if (ch)
287 return container_of(ch, struct rsi, h); 296 return container_of(ch, struct rsi, h);
288 else 297 else
@@ -330,6 +339,7 @@ struct rsc {
330 struct svc_cred cred; 339 struct svc_cred cred;
331 struct gss_svc_seq_data seqdata; 340 struct gss_svc_seq_data seqdata;
332 struct gss_ctx *mechctx; 341 struct gss_ctx *mechctx;
342 struct rcu_head rcu_head;
333}; 343};
334 344
335static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old); 345static 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)
343 free_svc_cred(&rsci->cred); 353 free_svc_cred(&rsci->cred);
344} 354}
345 355
356static 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
346static void rsc_put(struct kref *ref) 364static void rsc_put(struct kref *ref)
347{ 365{
348 struct rsc *rsci = container_of(ref, struct rsc, h.ref); 366 struct rsc *rsci = container_of(ref, struct rsc, h.ref);
349 367
350 rsc_free(rsci); 368 if (rsci->mechctx)
351 kfree(rsci); 369 gss_delete_sec_context(&rsci->mechctx);
370 free_svc_cred(&rsci->cred);
371 call_rcu(&rsci->rcu_head, rsc_free_rcu);
352} 372}
353 373
354static inline int 374static inline int
@@ -542,7 +562,7 @@ static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
542 struct cache_head *ch; 562 struct cache_head *ch;
543 int hash = rsc_hash(item); 563 int hash = rsc_hash(item);
544 564
545 ch = sunrpc_cache_lookup(cd, &item->h, hash); 565 ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
546 if (ch) 566 if (ch)
547 return container_of(ch, struct rsc, h); 567 return container_of(ch, struct rsc, h);
548 else 568 else