SUNRPC: Add explicit rescheduling points in the receive path
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 14 Jan 2018 20:28:29 +0000 (15:28 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Mon, 15 Jan 2018 04:06:30 +0000 (23:06 -0500)
When reading the reply from the server, insert an explicit
cond_resched() to avoid starving higher priority tasks.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
net/sunrpc/xprtsock.c

index 620be573d78b49e4730b3cffb0e3d31788971096..18803021f242ebecb5cde14ae892009e65edabf2 100644 (file)
@@ -1005,6 +1005,7 @@ static void xs_local_data_receive(struct sock_xprt *transport)
        struct sock *sk;
        int err;
 
+restart:
        mutex_lock(&transport->recv_mutex);
        sk = transport->inet;
        if (sk == NULL)
@@ -1018,6 +1019,11 @@ static void xs_local_data_receive(struct sock_xprt *transport)
                }
                if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
                        break;
+               if (need_resched()) {
+                       mutex_unlock(&transport->recv_mutex);
+                       cond_resched();
+                       goto restart;
+               }
        }
 out:
        mutex_unlock(&transport->recv_mutex);
@@ -1096,6 +1102,7 @@ static void xs_udp_data_receive(struct sock_xprt *transport)
        struct sock *sk;
        int err;
 
+restart:
        mutex_lock(&transport->recv_mutex);
        sk = transport->inet;
        if (sk == NULL)
@@ -1109,6 +1116,11 @@ static void xs_udp_data_receive(struct sock_xprt *transport)
                }
                if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
                        break;
+               if (need_resched()) {
+                       mutex_unlock(&transport->recv_mutex);
+                       cond_resched();
+                       goto restart;
+               }
        }
 out:
        mutex_unlock(&transport->recv_mutex);
@@ -1528,16 +1540,16 @@ static void xs_tcp_data_receive(struct sock_xprt *transport)
                .arg.data = xprt,
        };
        unsigned long total = 0;
-       int loop;
        int read = 0;
 
+restart:
        mutex_lock(&transport->recv_mutex);
        sk = transport->inet;
        if (sk == NULL)
                goto out;
 
        /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
-       for (loop = 0; loop < 64; loop++) {
+       for (;;) {
                rd_desc.count = RPC_TCP_READ_CHUNK_SZ;
                lock_sock(sk);
                read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
@@ -1548,6 +1560,11 @@ static void xs_tcp_data_receive(struct sock_xprt *transport)
                }
                release_sock(sk);
                total += read;
+               if (need_resched()) {
+                       mutex_unlock(&transport->recv_mutex);
+                       cond_resched();
+                       goto restart;
+               }
        }
        if (test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
                queue_work(xprtiod_workqueue, &transport->recv_worker);