aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-22 17:14:36 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-24 10:46:15 -0400
commitf878b657ce8e7d3673afe48110ec208a29e38c4a (patch)
treece2f01c75268473a8d4e8879f5f55b73a16caa7d /net
parent4bc1e68ed6a8b59be8a79eb719be515a55c7bc68 (diff)
SUNRPC: Get rid of the xs_error_report socket callback
Chris Perl reports that we're seeing races between the wakeup call in xs_error_report and the connect attempts. Basically, Chris has shown that in certain circumstances, the call to xs_error_report causes the rpc_task that is responsible for reconnecting to wake up early, thus triggering a disconnect and retry. Since the sk->sk_error_report() calls in the socket layer are always followed by a tcp_done() in the cases where we care about waking up the rpc_tasks, just let the state_change callbacks take responsibility for those wake ups. Reported-by: Chris Perl <chris.perl@gmail.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Cc: stable@vger.kernel.org Tested-by: Chris Perl <chris.perl@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtsock.c25
1 files changed, 0 insertions, 25 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 1f105c2d2e15..75853cabf4c9 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -254,7 +254,6 @@ struct sock_xprt {
254 void (*old_data_ready)(struct sock *, int); 254 void (*old_data_ready)(struct sock *, int);
255 void (*old_state_change)(struct sock *); 255 void (*old_state_change)(struct sock *);
256 void (*old_write_space)(struct sock *); 256 void (*old_write_space)(struct sock *);
257 void (*old_error_report)(struct sock *);
258}; 257};
259 258
260/* 259/*
@@ -781,7 +780,6 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk)
781 transport->old_data_ready = sk->sk_data_ready; 780 transport->old_data_ready = sk->sk_data_ready;
782 transport->old_state_change = sk->sk_state_change; 781 transport->old_state_change = sk->sk_state_change;
783 transport->old_write_space = sk->sk_write_space; 782 transport->old_write_space = sk->sk_write_space;
784 transport->old_error_report = sk->sk_error_report;
785} 783}
786 784
787static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) 785static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk)
@@ -789,7 +787,6 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s
789 sk->sk_data_ready = transport->old_data_ready; 787 sk->sk_data_ready = transport->old_data_ready;
790 sk->sk_state_change = transport->old_state_change; 788 sk->sk_state_change = transport->old_state_change;
791 sk->sk_write_space = transport->old_write_space; 789 sk->sk_write_space = transport->old_write_space;
792 sk->sk_error_report = transport->old_error_report;
793} 790}
794 791
795static void xs_reset_transport(struct sock_xprt *transport) 792static void xs_reset_transport(struct sock_xprt *transport)
@@ -1546,25 +1543,6 @@ static void xs_tcp_state_change(struct sock *sk)
1546 read_unlock_bh(&sk->sk_callback_lock); 1543 read_unlock_bh(&sk->sk_callback_lock);
1547} 1544}
1548 1545
1549/**
1550 * xs_error_report - callback mainly for catching socket errors
1551 * @sk: socket
1552 */
1553static void xs_error_report(struct sock *sk)
1554{
1555 struct rpc_xprt *xprt;
1556
1557 read_lock_bh(&sk->sk_callback_lock);
1558 if (!(xprt = xprt_from_sock(sk)))
1559 goto out;
1560 dprintk("RPC: %s client %p...\n"
1561 "RPC: error %d\n",
1562 __func__, xprt, sk->sk_err);
1563 xprt_wake_pending_tasks(xprt, -EAGAIN);
1564out:
1565 read_unlock_bh(&sk->sk_callback_lock);
1566}
1567
1568static void xs_write_space(struct sock *sk) 1546static void xs_write_space(struct sock *sk)
1569{ 1547{
1570 struct socket *sock; 1548 struct socket *sock;
@@ -1864,7 +1842,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt,
1864 sk->sk_user_data = xprt; 1842 sk->sk_user_data = xprt;
1865 sk->sk_data_ready = xs_local_data_ready; 1843 sk->sk_data_ready = xs_local_data_ready;
1866 sk->sk_write_space = xs_udp_write_space; 1844 sk->sk_write_space = xs_udp_write_space;
1867 sk->sk_error_report = xs_error_report;
1868 sk->sk_allocation = GFP_ATOMIC; 1845 sk->sk_allocation = GFP_ATOMIC;
1869 1846
1870 xprt_clear_connected(xprt); 1847 xprt_clear_connected(xprt);
@@ -1989,7 +1966,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
1989 sk->sk_user_data = xprt; 1966 sk->sk_user_data = xprt;
1990 sk->sk_data_ready = xs_udp_data_ready; 1967 sk->sk_data_ready = xs_udp_data_ready;
1991 sk->sk_write_space = xs_udp_write_space; 1968 sk->sk_write_space = xs_udp_write_space;
1992 sk->sk_error_report = xs_error_report;
1993 sk->sk_no_check = UDP_CSUM_NORCV; 1969 sk->sk_no_check = UDP_CSUM_NORCV;
1994 sk->sk_allocation = GFP_ATOMIC; 1970 sk->sk_allocation = GFP_ATOMIC;
1995 1971
@@ -2102,7 +2078,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
2102 sk->sk_data_ready = xs_tcp_data_ready; 2078 sk->sk_data_ready = xs_tcp_data_ready;
2103 sk->sk_state_change = xs_tcp_state_change; 2079 sk->sk_state_change = xs_tcp_state_change;
2104 sk->sk_write_space = xs_tcp_write_space; 2080 sk->sk_write_space = xs_tcp_write_space;
2105 sk->sk_error_report = xs_error_report;
2106 sk->sk_allocation = GFP_ATOMIC; 2081 sk->sk_allocation = GFP_ATOMIC;
2107 2082
2108 /* socket options */ 2083 /* socket options */