SUNRPC: change locking for xs_swap_enable/disable
It is not in general safe to wait for XPRT_LOCKED to clear. A wakeup is only sent when - connection completes - sock close completes so during normal operations, this can wait indefinitely. The event we need to protect against is ->inet being set to NULL, and that happens under the recv_mutex lock. So drop the handlign of XPRT_LOCKED and use recv_mutex instead. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
c265de257f
commit
693486d5f8
@ -1936,9 +1936,9 @@ static void xs_local_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||||||
|
|
||||||
#if IS_ENABLED(CONFIG_SUNRPC_SWAP)
|
#if IS_ENABLED(CONFIG_SUNRPC_SWAP)
|
||||||
/*
|
/*
|
||||||
* Note that this should be called with XPRT_LOCKED held (or when we otherwise
|
* Note that this should be called with XPRT_LOCKED held, or recv_mutex
|
||||||
* know that we have exclusive access to the socket), to guard against
|
* held, or when we otherwise know that we have exclusive access to the
|
||||||
* races with xs_reset_transport.
|
* socket, to guard against races with xs_reset_transport.
|
||||||
*/
|
*/
|
||||||
static void xs_set_memalloc(struct rpc_xprt *xprt)
|
static void xs_set_memalloc(struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
@ -1967,13 +1967,11 @@ xs_enable_swap(struct rpc_xprt *xprt)
|
|||||||
{
|
{
|
||||||
struct sock_xprt *xs = container_of(xprt, struct sock_xprt, xprt);
|
struct sock_xprt *xs = container_of(xprt, struct sock_xprt, xprt);
|
||||||
|
|
||||||
if (atomic_inc_return(&xprt->swapper) != 1)
|
mutex_lock(&xs->recv_mutex);
|
||||||
return 0;
|
if (atomic_inc_return(&xprt->swapper) == 1 &&
|
||||||
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE))
|
xs->inet)
|
||||||
return -ERESTARTSYS;
|
|
||||||
if (xs->inet)
|
|
||||||
sk_set_memalloc(xs->inet);
|
sk_set_memalloc(xs->inet);
|
||||||
xprt_release_xprt(xprt, NULL);
|
mutex_unlock(&xs->recv_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1989,13 +1987,11 @@ xs_disable_swap(struct rpc_xprt *xprt)
|
|||||||
{
|
{
|
||||||
struct sock_xprt *xs = container_of(xprt, struct sock_xprt, xprt);
|
struct sock_xprt *xs = container_of(xprt, struct sock_xprt, xprt);
|
||||||
|
|
||||||
if (!atomic_dec_and_test(&xprt->swapper))
|
mutex_lock(&xs->recv_mutex);
|
||||||
return;
|
if (atomic_dec_and_test(&xprt->swapper) &&
|
||||||
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE))
|
xs->inet)
|
||||||
return;
|
|
||||||
if (xs->inet)
|
|
||||||
sk_clear_memalloc(xs->inet);
|
sk_clear_memalloc(xs->inet);
|
||||||
xprt_release_xprt(xprt, NULL);
|
mutex_unlock(&xs->recv_mutex);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void xs_set_memalloc(struct rpc_xprt *xprt)
|
static void xs_set_memalloc(struct rpc_xprt *xprt)
|
||||||
|
Loading…
Reference in New Issue
Block a user