Skip to content

Commit

Permalink
SUNRPC: Treat the task and request as separate in the xprt_ops->send_…
Browse files Browse the repository at this point in the history
…request()

When we shift to using the transmit queue, then the task that holds the
write lock will not necessarily be the same as the one being transmitted.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
  • Loading branch information
Trond Myklebust committed Sep 30, 2018
1 parent 902c588 commit 50f484e
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 21 deletions.
2 changes: 1 addition & 1 deletion include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ struct rpc_xprt_ops {
void (*connect)(struct rpc_xprt *xprt, struct rpc_task *task);
int (*buf_alloc)(struct rpc_task *task);
void (*buf_free)(struct rpc_task *task);
int (*send_request)(struct rpc_task *task);
int (*send_request)(struct rpc_rqst *req, struct rpc_task *task);
void (*set_retrans_timeout)(struct rpc_task *task);
void (*timer)(struct rpc_xprt *xprt, struct rpc_task *task);
void (*release_request)(struct rpc_task *task);
Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,7 +1191,7 @@ void xprt_transmit(struct rpc_task *task)
}

connect_cookie = xprt->connect_cookie;
status = xprt->ops->send_request(task);
status = xprt->ops->send_request(req, task);
trace_xprt_transmit(xprt, req->rq_xid, status);
if (status != 0) {
task->tk_status = status;
Expand Down
3 changes: 1 addition & 2 deletions net/sunrpc/xprtrdma/svc_rdma_backchannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,8 @@ rpcrdma_bc_send_request(struct svcxprt_rdma *rdma, struct rpc_rqst *rqst)
* connection.
*/
static int
xprt_rdma_bc_send_request(struct rpc_task *task)
xprt_rdma_bc_send_request(struct rpc_rqst *rqst, struct rpc_task *task)
{
struct rpc_rqst *rqst = task->tk_rqstp;
struct svc_xprt *sxprt = rqst->rq_xprt->bc_xprt;
struct svcxprt_rdma *rdma;
int ret;
Expand Down
5 changes: 2 additions & 3 deletions net/sunrpc/xprtrdma/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,8 @@ xprt_rdma_free(struct rpc_task *task)
* sent. Do not try to send this message again.
*/
static int
xprt_rdma_send_request(struct rpc_task *task)
xprt_rdma_send_request(struct rpc_rqst *rqst, struct rpc_task *task)
{
struct rpc_rqst *rqst = task->tk_rqstp;
struct rpc_xprt *xprt = rqst->rq_xprt;
struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
Expand Down Expand Up @@ -741,7 +740,7 @@ xprt_rdma_send_request(struct rpc_task *task)
/* An RPC with no reply will throw off credit accounting,
* so drop the connection to reset the credit grant.
*/
if (!rpc_reply_expected(task))
if (!rpc_reply_expected(rqst->rq_task))
goto drop_connection;
return 0;

Expand Down
27 changes: 13 additions & 14 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,12 @@ static void xs_nospace_callback(struct rpc_task *task)

/**
* xs_nospace - place task on wait queue if transmit was incomplete
* @req: pointer to RPC request
* @task: task to put to sleep
*
*/
static int xs_nospace(struct rpc_task *task)
static int xs_nospace(struct rpc_rqst *req, struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
struct sock *sk = transport->inet;
Expand Down Expand Up @@ -513,6 +513,7 @@ static inline void xs_encode_stream_record_marker(struct xdr_buf *buf)

/**
* xs_local_send_request - write an RPC request to an AF_LOCAL socket
* @req: pointer to RPC request
* @task: RPC task that manages the state of an RPC request
*
* Return values:
Expand All @@ -522,9 +523,8 @@ static inline void xs_encode_stream_record_marker(struct xdr_buf *buf)
* ENOTCONN: Caller needs to invoke connect logic then call again
* other: Some other error occured, the request was not sent
*/
static int xs_local_send_request(struct rpc_task *task)
static int xs_local_send_request(struct rpc_rqst *req, struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport =
container_of(xprt, struct sock_xprt, xprt);
Expand Down Expand Up @@ -569,7 +569,7 @@ static int xs_local_send_request(struct rpc_task *task)
case -ENOBUFS:
break;
case -EAGAIN:
status = xs_nospace(task);
status = xs_nospace(req, task);
break;
default:
dprintk("RPC: sendmsg returned unrecognized error %d\n",
Expand All @@ -585,6 +585,7 @@ static int xs_local_send_request(struct rpc_task *task)

/**
* xs_udp_send_request - write an RPC request to a UDP socket
* @req: pointer to RPC request
* @task: address of RPC task that manages the state of an RPC request
*
* Return values:
Expand All @@ -594,9 +595,8 @@ static int xs_local_send_request(struct rpc_task *task)
* ENOTCONN: Caller needs to invoke connect logic then call again
* other: Some other error occurred, the request was not sent
*/
static int xs_udp_send_request(struct rpc_task *task)
static int xs_udp_send_request(struct rpc_rqst *req, struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
struct xdr_buf *xdr = &req->rq_snd_buf;
Expand Down Expand Up @@ -638,7 +638,7 @@ static int xs_udp_send_request(struct rpc_task *task)
/* Should we call xs_close() here? */
break;
case -EAGAIN:
status = xs_nospace(task);
status = xs_nospace(req, task);
break;
case -ENETUNREACH:
case -ENOBUFS:
Expand All @@ -658,6 +658,7 @@ static int xs_udp_send_request(struct rpc_task *task)

/**
* xs_tcp_send_request - write an RPC request to a TCP socket
* @req: pointer to RPC request
* @task: address of RPC task that manages the state of an RPC request
*
* Return values:
Expand All @@ -670,9 +671,8 @@ static int xs_udp_send_request(struct rpc_task *task)
* XXX: In the case of soft timeouts, should we eventually give up
* if sendmsg is not able to make progress?
*/
static int xs_tcp_send_request(struct rpc_task *task)
static int xs_tcp_send_request(struct rpc_rqst *req, struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
struct xdr_buf *xdr = &req->rq_snd_buf;
Expand All @@ -697,7 +697,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
* completes while the socket holds a reference to the pages,
* then we may end up resending corrupted data.
*/
if (task->tk_flags & RPC_TASK_SENT)
if (req->rq_task->tk_flags & RPC_TASK_SENT)
zerocopy = false;

if (test_bit(XPRT_SOCK_UPD_TIMEOUT, &transport->sock_state))
Expand Down Expand Up @@ -761,7 +761,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
/* Should we call xs_close() here? */
break;
case -EAGAIN:
status = xs_nospace(task);
status = xs_nospace(req, task);
break;
case -ECONNRESET:
case -ECONNREFUSED:
Expand Down Expand Up @@ -2706,9 +2706,8 @@ static int bc_sendto(struct rpc_rqst *req)
/*
* The send routine. Borrows from svc_send
*/
static int bc_send_request(struct rpc_task *task)
static int bc_send_request(struct rpc_rqst *req, struct rpc_task *task)
{
struct rpc_rqst *req = task->tk_rqstp;
struct svc_xprt *xprt;
int len;

Expand Down

0 comments on commit 50f484e

Please sign in to comment.