linux/net/sunrpc
Jeff Layton b1691bc03d sunrpc: convert to lockless lookup of queued server threads
Testing has shown that the pool->sp_lock can be a bottleneck on a busy
server. Every time data is received on a socket, the server must take
that lock in order to dequeue a thread from the sp_threads list.

Address this problem by eliminating the sp_threads list (which contains
threads that are currently idle) and replacing it with a RQ_BUSY flag in
svc_rqst. This allows us to walk the sp_all_threads list under the
rcu_read_lock and find a suitable thread for the xprt by doing a
test_and_set_bit.

Note that we do still have a potential atomicity problem however with
this approach.  We don't want svc_xprt_do_enqueue to set the
rqst->rq_xprt pointer unless a test_and_set_bit of RQ_BUSY returned
zero (which indicates that the thread was idle). But, by the time we
check that, the bit could be flipped by a waking thread.

To address this, we acquire a new per-rqst spinlock (rq_lock) and take
that before doing the test_and_set_bit. If that returns false, then we
can set rq_xprt and drop the spinlock. Then, when the thread wakes up,
it must set the bit under the same spinlock and can trust that if it was
already set then the rq_xprt is also properly set.

With this scheme, the case where we have an idle thread no longer needs
to take the highly contended pool->sp_lock at all, and that removes the
bottleneck.

That still leaves one issue: What of the case where we walk the whole
sp_all_threads list and don't find an idle thread? Because the search is
lockess, it's possible for the queueing to race with a thread that is
going to sleep. To address that, we queue the xprt and then search again.

If we find an idle thread at that point, we can't attach the xprt to it
directly since that might race with a different thread waking up and
finding it.  All we can do is wake the idle thread back up and let it
attempt to find the now-queued xprt.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Tested-by: Chris Worley <chris.worley@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
2014-12-09 11:22:22 -05:00
..
auth_gss sunrpc: move rq_splice_ok flag into rq_flags 2014-12-09 11:22:21 -05:00
xprtrdma NFS: Client side changes for RDMA 2014-11-26 17:37:13 -05:00
addr.c replace strict_strto calls 2014-07-12 18:45:49 -04:00
auth.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
auth_generic.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
auth_null.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
auth_unix.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
backchannel_rqst.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
bc_svc.c SUNRPC: remove BUG_ON from bc_send 2012-11-04 14:43:41 -05:00
cache.c SUNRPC: Fix printk that is not only for nfsd 2014-05-08 14:59:51 -04:00
clnt.c sunrpc: add debugfs file for displaying client rpc_task queue 2014-11-27 13:14:51 -05:00
debugfs.c sunrpc: add a debugfs rpc_xprt directory with an info file in it 2014-11-27 13:14:52 -05:00
Kconfig sunrpc: add debugfs file for displaying client rpc_task queue 2014-11-27 13:14:51 -05:00
Makefile sunrpc: add debugfs file for displaying client rpc_task queue 2014-11-27 13:14:51 -05:00
netns.h Merge branch 'for-3.14' of git://linux-nfs.org/~bfields/linux 2014-01-30 10:18:43 -08:00
rpc_pipe.c rpc_pipe: Drop memory allocation cast 2014-07-12 18:43:44 -04:00
rpcb_clnt.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
sched.c sunrpc: eliminate RPC_TRACEPOINTS 2014-11-24 17:33:12 -05:00
socklib.c net: Save software checksum complete 2014-06-11 15:46:13 -07:00
stats.c SUNRPC: serialize iostats updates 2014-11-25 16:22:15 -05:00
sunrpc.h SUNRPC: track whether a request is coming from a loop-back interface. 2014-05-22 15:59:18 -04:00
sunrpc_syms.c sunrpc: add debugfs file for displaying client rpc_task queue 2014-11-27 13:14:51 -05:00
svc.c sunrpc: convert to lockless lookup of queued server threads 2014-12-09 11:22:22 -05:00
svc_xprt.c sunrpc: convert to lockless lookup of queued server threads 2014-12-09 11:22:22 -05:00
svcauth.c nfsd4: better reservation of head space for krb5 2014-05-30 17:32:17 -04:00
svcauth_unix.c svcrpc: fix failures to handle -1 uid's 2013-07-08 17:27:23 -04:00
svcsock.c sunrpc: move rq_local field to rq_flags 2014-12-09 11:21:21 -05:00
sysctl.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00
timer.c net: cleanup unsigned to unsigned int 2012-04-15 12:44:40 -04:00
xdr.c rpc: change comments to assertions 2014-10-23 14:05:11 -04:00
xprt.c sunrpc: add a debugfs rpc_xprt directory with an info file in it 2014-11-27 13:14:52 -05:00
xprtsock.c sunrpc: eliminate RPC_DEBUG 2014-11-24 17:31:46 -05:00