aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2018-01-14 15:28:29 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2018-01-14 23:06:30 -0500
commit0af3442af7c4c5b06e72708d7dd937974d1b4114 (patch)
tree944de880b5c873be536f08557ba5e43ee3c48713
parent3d188805f83250409fc251bfb0a699810086885b (diff)
SUNRPC: Add explicit rescheduling points in the receive path
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>
-rw-r--r--net/sunrpc/xprtsock.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 620be573d78b..18803021f242 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1005,6 +1005,7 @@ static void xs_local_data_receive(struct sock_xprt *transport)
1005 struct sock *sk; 1005 struct sock *sk;
1006 int err; 1006 int err;
1007 1007
1008restart:
1008 mutex_lock(&transport->recv_mutex); 1009 mutex_lock(&transport->recv_mutex);
1009 sk = transport->inet; 1010 sk = transport->inet;
1010 if (sk == NULL) 1011 if (sk == NULL)
@@ -1018,6 +1019,11 @@ static void xs_local_data_receive(struct sock_xprt *transport)
1018 } 1019 }
1019 if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) 1020 if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
1020 break; 1021 break;
1022 if (need_resched()) {
1023 mutex_unlock(&transport->recv_mutex);
1024 cond_resched();
1025 goto restart;
1026 }
1021 } 1027 }
1022out: 1028out:
1023 mutex_unlock(&transport->recv_mutex); 1029 mutex_unlock(&transport->recv_mutex);
@@ -1096,6 +1102,7 @@ static void xs_udp_data_receive(struct sock_xprt *transport)
1096 struct sock *sk; 1102 struct sock *sk;
1097 int err; 1103 int err;
1098 1104
1105restart:
1099 mutex_lock(&transport->recv_mutex); 1106 mutex_lock(&transport->recv_mutex);
1100 sk = transport->inet; 1107 sk = transport->inet;
1101 if (sk == NULL) 1108 if (sk == NULL)
@@ -1109,6 +1116,11 @@ static void xs_udp_data_receive(struct sock_xprt *transport)
1109 } 1116 }
1110 if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) 1117 if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
1111 break; 1118 break;
1119 if (need_resched()) {
1120 mutex_unlock(&transport->recv_mutex);
1121 cond_resched();
1122 goto restart;
1123 }
1112 } 1124 }
1113out: 1125out:
1114 mutex_unlock(&transport->recv_mutex); 1126 mutex_unlock(&transport->recv_mutex);
@@ -1528,16 +1540,16 @@ static void xs_tcp_data_receive(struct sock_xprt *transport)
1528 .arg.data = xprt, 1540 .arg.data = xprt,
1529 }; 1541 };
1530 unsigned long total = 0; 1542 unsigned long total = 0;
1531 int loop;
1532 int read = 0; 1543 int read = 0;
1533 1544
1545restart:
1534 mutex_lock(&transport->recv_mutex); 1546 mutex_lock(&transport->recv_mutex);
1535 sk = transport->inet; 1547 sk = transport->inet;
1536 if (sk == NULL) 1548 if (sk == NULL)
1537 goto out; 1549 goto out;
1538 1550
1539 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ 1551 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
1540 for (loop = 0; loop < 64; loop++) { 1552 for (;;) {
1541 rd_desc.count = RPC_TCP_READ_CHUNK_SZ; 1553 rd_desc.count = RPC_TCP_READ_CHUNK_SZ;
1542 lock_sock(sk); 1554 lock_sock(sk);
1543 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); 1555 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)
1548 } 1560 }
1549 release_sock(sk); 1561 release_sock(sk);
1550 total += read; 1562 total += read;
1563 if (need_resched()) {
1564 mutex_unlock(&transport->recv_mutex);
1565 cond_resched();
1566 goto restart;
1567 }
1551 } 1568 }
1552 if (test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) 1569 if (test_bit(XPRT_SOCK_DATA_READY, &transport->sock_state))
1553 queue_work(xprtiod_workqueue, &transport->recv_worker); 1570 queue_work(xprtiod_workqueue, &transport->recv_worker);