diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2018-01-14 15:28:29 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2018-01-14 23:06:30 -0500 |
commit | 0af3442af7c4c5b06e72708d7dd937974d1b4114 (patch) | |
tree | 944de880b5c873be536f08557ba5e43ee3c48713 | |
parent | 3d188805f83250409fc251bfb0a699810086885b (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.c | 21 |
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 | ||
1008 | restart: | ||
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 | } |
1022 | out: | 1028 | out: |
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 | ||
1105 | restart: | ||
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 | } |
1113 | out: | 1125 | out: |
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 | ||
1545 | restart: | ||
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); |