SUNRPC: Don't loop forever in xs_tcp_data_receive()
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 12 Aug 2017 19:11:49 +0000 (15:11 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 16 Aug 2017 19:10:16 +0000 (15:10 -0400)
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>
net/sunrpc/xprtsock.c

index a2312f14beb43b778ef78ad4ca26f750ede54873..e8f44fc76754e1708f83f1be908ddf0c51c10d0b 100644 (file)
@@ -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);