mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
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)
|
||||
/*
|
||||
* Note that this should be called with XPRT_LOCKED held (or when we otherwise
|
||||
* know that we have exclusive access to the socket), to guard against
|
||||
* races with xs_reset_transport.
|
||||
* Note that this should be called with XPRT_LOCKED held, or recv_mutex
|
||||
* held, or when we otherwise know that we have exclusive access to the
|
||||
* socket, to guard against races with xs_reset_transport.
|
||||
*/
|
||||
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);
|
||||
|
||||
if (atomic_inc_return(&xprt->swapper) != 1)
|
||||
return 0;
|
||||
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE))
|
||||
return -ERESTARTSYS;
|
||||
if (xs->inet)
|
||||
mutex_lock(&xs->recv_mutex);
|
||||
if (atomic_inc_return(&xprt->swapper) == 1 &&
|
||||
xs->inet)
|
||||
sk_set_memalloc(xs->inet);
|
||||
xprt_release_xprt(xprt, NULL);
|
||||
mutex_unlock(&xs->recv_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1989,13 +1987,11 @@ xs_disable_swap(struct rpc_xprt *xprt)
|
||||
{
|
||||
struct sock_xprt *xs = container_of(xprt, struct sock_xprt, xprt);
|
||||
|
||||
if (!atomic_dec_and_test(&xprt->swapper))
|
||||
return;
|
||||
if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE))
|
||||
return;
|
||||
if (xs->inet)
|
||||
mutex_lock(&xs->recv_mutex);
|
||||
if (atomic_dec_and_test(&xprt->swapper) &&
|
||||
xs->inet)
|
||||
sk_clear_memalloc(xs->inet);
|
||||
xprt_release_xprt(xprt, NULL);
|
||||
mutex_unlock(&xs->recv_mutex);
|
||||
}
|
||||
#else
|
||||
static void xs_set_memalloc(struct rpc_xprt *xprt)
|
||||
|
Loading…
Reference in New Issue
Block a user