SUNRPC: Refactor the transport request pinning

We are going to need to pin for both send and receive.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
Trond Myklebust 2018-08-06 12:55:34 -04:00
Родитель 4cd34e7c2e
Коммит cf9946cd61
3 изменённых файлов: 25 добавлений и 22 удалений

Просмотреть файл

@ -142,8 +142,7 @@ struct rpc_task_setup {
#define RPC_TASK_ACTIVE 2 #define RPC_TASK_ACTIVE 2
#define RPC_TASK_NEED_XMIT 3 #define RPC_TASK_NEED_XMIT 3
#define RPC_TASK_NEED_RECV 4 #define RPC_TASK_NEED_RECV 4
#define RPC_TASK_MSG_RECV 5 #define RPC_TASK_MSG_PIN_WAIT 5
#define RPC_TASK_MSG_RECV_WAIT 6
#define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) #define RPC_IS_RUNNING(t) test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)
#define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate) #define rpc_set_running(t) set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)

Просмотреть файл

@ -103,6 +103,7 @@ struct rpc_rqst {
/* A cookie used to track the /* A cookie used to track the
state of the transport state of the transport
connection */ connection */
atomic_t rq_pin;
/* /*
* Partial send handling * Partial send handling

Просмотреть файл

@ -847,16 +847,22 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
} }
EXPORT_SYMBOL_GPL(xprt_lookup_rqst); EXPORT_SYMBOL_GPL(xprt_lookup_rqst);
static bool
xprt_is_pinned_rqst(struct rpc_rqst *req)
{
return atomic_read(&req->rq_pin) != 0;
}
/** /**
* xprt_pin_rqst - Pin a request on the transport receive list * xprt_pin_rqst - Pin a request on the transport receive list
* @req: Request to pin * @req: Request to pin
* *
* Caller must ensure this is atomic with the call to xprt_lookup_rqst() * Caller must ensure this is atomic with the call to xprt_lookup_rqst()
* so should be holding the xprt transport lock. * so should be holding the xprt receive lock.
*/ */
void xprt_pin_rqst(struct rpc_rqst *req) void xprt_pin_rqst(struct rpc_rqst *req)
{ {
set_bit(RPC_TASK_MSG_RECV, &req->rq_task->tk_runstate); atomic_inc(&req->rq_pin);
} }
EXPORT_SYMBOL_GPL(xprt_pin_rqst); EXPORT_SYMBOL_GPL(xprt_pin_rqst);
@ -864,31 +870,22 @@ EXPORT_SYMBOL_GPL(xprt_pin_rqst);
* xprt_unpin_rqst - Unpin a request on the transport receive list * xprt_unpin_rqst - Unpin a request on the transport receive list
* @req: Request to pin * @req: Request to pin
* *
* Caller should be holding the xprt transport lock. * Caller should be holding the xprt receive lock.
*/ */
void xprt_unpin_rqst(struct rpc_rqst *req) void xprt_unpin_rqst(struct rpc_rqst *req)
{ {
struct rpc_task *task = req->rq_task; if (!test_bit(RPC_TASK_MSG_PIN_WAIT, &req->rq_task->tk_runstate)) {
atomic_dec(&req->rq_pin);
clear_bit(RPC_TASK_MSG_RECV, &task->tk_runstate); return;
if (test_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate)) }
wake_up_bit(&task->tk_runstate, RPC_TASK_MSG_RECV); if (atomic_dec_and_test(&req->rq_pin))
wake_up_var(&req->rq_pin);
} }
EXPORT_SYMBOL_GPL(xprt_unpin_rqst); EXPORT_SYMBOL_GPL(xprt_unpin_rqst);
static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req) static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req)
__must_hold(&req->rq_xprt->recv_lock)
{ {
struct rpc_task *task = req->rq_task; wait_var_event(&req->rq_pin, !xprt_is_pinned_rqst(req));
if (task && test_bit(RPC_TASK_MSG_RECV, &task->tk_runstate)) {
spin_unlock(&req->rq_xprt->recv_lock);
set_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate);
wait_on_bit(&task->tk_runstate, RPC_TASK_MSG_RECV,
TASK_UNINTERRUPTIBLE);
clear_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate);
spin_lock(&req->rq_xprt->recv_lock);
}
} }
/** /**
@ -1388,7 +1385,13 @@ void xprt_release(struct rpc_task *task)
spin_lock(&xprt->recv_lock); spin_lock(&xprt->recv_lock);
if (!list_empty(&req->rq_list)) { if (!list_empty(&req->rq_list)) {
list_del_init(&req->rq_list); list_del_init(&req->rq_list);
xprt_wait_on_pinned_rqst(req); if (xprt_is_pinned_rqst(req)) {
set_bit(RPC_TASK_MSG_PIN_WAIT, &req->rq_task->tk_runstate);
spin_unlock(&xprt->recv_lock);
xprt_wait_on_pinned_rqst(req);
spin_lock(&xprt->recv_lock);
clear_bit(RPC_TASK_MSG_PIN_WAIT, &req->rq_task->tk_runstate);
}
} }
spin_unlock(&xprt->recv_lock); spin_unlock(&xprt->recv_lock);
spin_lock_bh(&xprt->transport_lock); spin_lock_bh(&xprt->transport_lock);