diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2017-02-08 17:00:51 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2017-02-10 14:02:37 -0500 |
commit | b977b644ccf821ab1269582f7efe1d0d85faa1f6 (patch) | |
tree | 9c2f0a3512ea55bfacf9f1ef6926c1f964a16444 | |
parent | 9a5c63e9c4056de8a73555131e6f698ddb0b9e0d (diff) |
sunrpc: Allow xprt->ops->timer method to sleep
The transport lock is needed to protect the xprt_adjust_cwnd() call
in xs_udp_timer, but it is not necessary for accessing the
rq_reply_bytes_recvd or tk_status fields. It is correct to sublimate
the lock into UDP's xs_udp_timer method, where it is required.
The ->timer method has to take the transport lock if needed, but it
can now sleep safely, or even call back into the RPC scheduler.
This is more a clean-up than a fix, but the "issue" was introduced
by my transport switch patches back in 2005.
Fixes: 46c0ee8bc4ad ("RPC: separate xprt_timer implementations")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r-- | net/sunrpc/xprt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
2 files changed, 2 insertions, 2 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 9a6be030ca7d..b530a2852ba8 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -897,13 +897,11 @@ static void xprt_timer(struct rpc_task *task) | |||
897 | return; | 897 | return; |
898 | dprintk("RPC: %5u xprt_timer\n", task->tk_pid); | 898 | dprintk("RPC: %5u xprt_timer\n", task->tk_pid); |
899 | 899 | ||
900 | spin_lock_bh(&xprt->transport_lock); | ||
901 | if (!req->rq_reply_bytes_recvd) { | 900 | if (!req->rq_reply_bytes_recvd) { |
902 | if (xprt->ops->timer) | 901 | if (xprt->ops->timer) |
903 | xprt->ops->timer(xprt, task); | 902 | xprt->ops->timer(xprt, task); |
904 | } else | 903 | } else |
905 | task->tk_status = 0; | 904 | task->tk_status = 0; |
906 | spin_unlock_bh(&xprt->transport_lock); | ||
907 | } | 905 | } |
908 | 906 | ||
909 | /** | 907 | /** |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 810e9b59be16..18b4e7ff8879 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1739,7 +1739,9 @@ static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t | |||
1739 | */ | 1739 | */ |
1740 | static void xs_udp_timer(struct rpc_xprt *xprt, struct rpc_task *task) | 1740 | static void xs_udp_timer(struct rpc_xprt *xprt, struct rpc_task *task) |
1741 | { | 1741 | { |
1742 | spin_lock_bh(&xprt->transport_lock); | ||
1742 | xprt_adjust_cwnd(xprt, task, -ETIMEDOUT); | 1743 | xprt_adjust_cwnd(xprt, task, -ETIMEDOUT); |
1744 | spin_unlock_bh(&xprt->transport_lock); | ||
1743 | } | 1745 | } |
1744 | 1746 | ||
1745 | static unsigned short xs_get_random_port(void) | 1747 | static unsigned short xs_get_random_port(void) |