diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2009-06-04 14:13:06 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2009-06-04 14:13:06 +0000 |
commit | 4df6c5e1fcc8804ec08f4f04c8dd9d0ef83466e1 (patch) | |
tree | cc0d48c0c71f2161d578f4ba91009671a5e3a128 /sys/rpc/svc.c | |
parent | 88c056a07bd7f41543280f44bc1556d6294a3fa9 (diff) | |
download | FreeBSD-src-4df6c5e1fcc8804ec08f4f04c8dd9d0ef83466e1.zip FreeBSD-src-4df6c5e1fcc8804ec08f4f04c8dd9d0ef83466e1.tar.gz |
Fix two races in the server side krpc w.r.t upcalls:
Add a flag so that soupcall_clear() is only called once to cancel
an upcall.
Move the test for xprt_registered in the upcall down to after the
mtx_lock() of the pool mutex, to catch the case where it is
unregistered while the upcall is waiting for the mutex.
Also, move the mtx_destroy() of the pool mutex to after SVC_RELEASE(),
so that it isn't destroyed before the upcalls are disabled.
Reviewed by: dfr, jhb
Tested by: pho
Approved by: kib (mentor)
Diffstat (limited to 'sys/rpc/svc.c')
-rw-r--r-- | sys/rpc/svc.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c index 8af9e80..fbddafb 100644 --- a/sys/rpc/svc.c +++ b/sys/rpc/svc.c @@ -175,12 +175,12 @@ svcpool_destroy(SVCPOOL *pool) mtx_lock(&pool->sp_lock); } - mtx_destroy(&pool->sp_lock); - TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) { SVC_RELEASE(xprt); } + mtx_destroy(&pool->sp_lock); + if (pool->sp_rcache) replay_freecache(pool->sp_rcache); @@ -353,15 +353,16 @@ xprt_active(SVCXPRT *xprt) { SVCPOOL *pool = xprt->xp_pool; + mtx_lock(&pool->sp_lock); + if (!xprt->xp_registered) { /* * Race with xprt_unregister - we lose. */ + mtx_unlock(&pool->sp_lock); return; } - mtx_lock(&pool->sp_lock); - if (!xprt->xp_active) { TAILQ_INSERT_TAIL(&pool->sp_active, xprt, xp_alink); xprt->xp_active = TRUE; |