Commit 8593e010 authored by Chuck Lever's avatar Chuck Lever Committed by Anna Schumaker

SUNRPC: Fix congestion window race with disconnect

If the congestion window closes just as the transport disconnects,
a reconnect is never driven because:

1. The XPRT_CONG_WAIT flag prevents tasks from taking the write lock
2. There's no wake-up of the first task on the xprt->sending queue

To address this, clear the congestion wait flag as part of
completing a disconnect.

Fixes: 75891f50 ("SUNRPC: Support for congestion control ... ")
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 9ba82886
...@@ -456,6 +456,12 @@ void xprt_release_rqst_cong(struct rpc_task *task) ...@@ -456,6 +456,12 @@ void xprt_release_rqst_cong(struct rpc_task *task)
} }
EXPORT_SYMBOL_GPL(xprt_release_rqst_cong); EXPORT_SYMBOL_GPL(xprt_release_rqst_cong);
static void xprt_clear_congestion_window_wait_locked(struct rpc_xprt *xprt)
{
if (test_and_clear_bit(XPRT_CWND_WAIT, &xprt->state))
__xprt_lock_write_next_cong(xprt);
}
/* /*
* Clear the congestion window wait flag and wake up the next * Clear the congestion window wait flag and wake up the next
* entry on xprt->sending * entry on xprt->sending
...@@ -671,6 +677,7 @@ void xprt_disconnect_done(struct rpc_xprt *xprt) ...@@ -671,6 +677,7 @@ void xprt_disconnect_done(struct rpc_xprt *xprt)
spin_lock(&xprt->transport_lock); spin_lock(&xprt->transport_lock);
xprt_clear_connected(xprt); xprt_clear_connected(xprt);
xprt_clear_write_space_locked(xprt); xprt_clear_write_space_locked(xprt);
xprt_clear_congestion_window_wait_locked(xprt);
xprt_wake_pending_tasks(xprt, -ENOTCONN); xprt_wake_pending_tasks(xprt, -ENOTCONN);
spin_unlock(&xprt->transport_lock); spin_unlock(&xprt->transport_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment