diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2017-08-12 15:11:49 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2017-08-16 15:10:16 -0400 |
commit | 8d6f97d698b2b9e71124ba95688a6bf1adad5055 (patch) | |
tree | be327d7f519f65e32e7d4472a33942d9553fb83a /net | |
parent | c89091c88db768e3d28992023ca2cff6636c402b (diff) | |
download | linux-stable-8d6f97d698b2b9e71124ba95688a6bf1adad5055.tar.gz linux-stable-8d6f97d698b2b9e71124ba95688a6bf1adad5055.tar.bz2 linux-stable-8d6f97d698b2b9e71124ba95688a6bf1adad5055.zip |
SUNRPC: Don't loop forever in xs_tcp_data_receive()
Ensure that we don't hog the workqueue thread by requeuing the job
every 64 loops.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xprtsock.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index a2312f14beb4..e8f44fc76754 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1526,6 +1526,7 @@ static void xs_tcp_data_receive(struct sock_xprt *transport) .arg.data = xprt, }; unsigned long total = 0; + int loop; int read = 0; mutex_lock(&transport->recv_mutex); @@ -1534,20 +1535,20 @@ static void xs_tcp_data_receive(struct sock_xprt *transport) goto out; /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ - for (;;) { + for (loop = 0; loop < 64; loop++) { lock_sock(sk); read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); if (read <= 0) { clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state); release_sock(sk); - if (!test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) - break; - } else { - release_sock(sk); - total += read; + break; } + release_sock(sk); + total += read; rd_desc.count = 65536; } + if (test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) + queue_work(xprtiod_workqueue, &transport->recv_worker); out: mutex_unlock(&transport->recv_mutex); trace_xs_tcp_data_ready(xprt, read, total); |