Commit fb9100d0 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[PATCH] Clean up the RPC socket slot allocation code [2/2]

Patch by Chuck Lever. Remove the timeout logic from call_reserve.
This improves the overall RPC call ordering, and ensures that soft
tasks don't time out and give up before they have attempted to send
their message down the socket.
parent 7a72fa16
......@@ -57,8 +57,7 @@ struct rpc_timeout {
unsigned long to_current, /* current timeout */
to_initval, /* initial timeout */
to_maxval, /* max timeout */
to_increment, /* if !exponential */
to_resrvval; /* reserve timeout */
to_increment; /* if !exponential */
short to_retries; /* max # of retries */
unsigned char to_exponential;
};
......@@ -173,7 +172,7 @@ void xprt_default_timeout(struct rpc_timeout *, int);
void xprt_set_timeout(struct rpc_timeout *, unsigned int,
unsigned long);
int xprt_reserve(struct rpc_task *);
void xprt_reserve(struct rpc_task *);
void xprt_transmit(struct rpc_task *);
void xprt_receive(struct rpc_task *);
int xprt_adjust_timeout(struct rpc_timeout *);
......
......@@ -394,8 +394,6 @@ call_start(struct rpc_task *task)
static void
call_reserve(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
dprintk("RPC: %4d call_reserve\n", task->tk_pid);
if (!rpcauth_uptodatecred(task)) {
......@@ -405,7 +403,6 @@ call_reserve(struct rpc_task *task)
task->tk_status = 0;
task->tk_action = call_reserveresult;
task->tk_timeout = clnt->cl_timeout.to_resrvval;
xprt_reserve(task);
}
......@@ -448,17 +445,10 @@ call_reserveresult(struct rpc_task *task)
}
switch (status) {
case -EAGAIN:
case -ENOBUFS:
task->tk_timeout = task->tk_client->cl_timeout.to_resrvval;
case -EAGAIN: /* woken up; retry */
task->tk_action = call_reserve;
return;
case -ETIMEDOUT:
dprintk("RPC: timed out while reserving request slot\n");
task->tk_action = call_timeout;
return;
case -EIO:
/* probably a shutdown */
case -EIO: /* probably a shutdown */
break;
default:
printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
......@@ -560,6 +550,9 @@ call_bind(struct rpc_task *task)
struct rpc_clnt *clnt = task->tk_client;
struct rpc_xprt *xprt = clnt->cl_xprt;
dprintk("RPC: %4d call_bind xprt %p %s connected\n", task->tk_pid,
xprt, (xprt_connected(xprt) ? "is" : "is not"));
task->tk_action = (xprt_connected(xprt)) ? call_transmit : call_reconnect;
if (!clnt->cl_port) {
......@@ -696,20 +689,15 @@ static void
call_timeout(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_rqst *req = task->tk_rqstp;
if (req) {
struct rpc_timeout *to = &req->rq_timeout;
struct rpc_timeout *to = &task->tk_rqstp->rq_timeout;
if (xprt_adjust_timeout(to)) {
dprintk("RPC: %4d call_timeout (minor timeo)\n",
task->tk_pid);
goto minor_timeout;
}
to->to_retries = clnt->cl_timeout.to_retries;
if (xprt_adjust_timeout(to)) {
dprintk("RPC: %4d call_timeout (minor)\n", task->tk_pid);
goto retry;
}
to->to_retries = clnt->cl_timeout.to_retries;
dprintk("RPC: %4d call_timeout (major timeo)\n", task->tk_pid);
dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
if (clnt->cl_softrtry) {
if (clnt->cl_chatty && !task->tk_exit)
printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
......@@ -717,33 +705,18 @@ call_timeout(struct rpc_task *task)
rpc_exit(task, -EIO);
return;
}
if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN) && rpc_ntimeo(&clnt->cl_rtt) > 7) {
task->tk_flags |= RPC_CALL_MAJORSEEN;
if (req)
printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
clnt->cl_protname, clnt->cl_server);
#ifdef RPC_DEBUG
else
printk(KERN_NOTICE "%s: task %d can't get a request slot\n",
clnt->cl_protname, task->tk_pid);
#endif
printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
clnt->cl_protname, clnt->cl_server);
}
if (clnt->cl_autobind)
clnt->cl_port = 0;
minor_timeout:
if (!req)
task->tk_action = call_reserve;
else if (!clnt->cl_port) {
task->tk_action = call_bind;
clnt->cl_stats->rpcretrans++;
} else if (!xprt_connected(clnt->cl_xprt)) {
task->tk_action = call_reconnect;
clnt->cl_stats->rpcretrans++;
} else {
task->tk_action = call_transmit;
clnt->cl_stats->rpcretrans++;
}
retry:
clnt->cl_stats->rpcretrans++;
task->tk_action = call_bind;
task->tk_status = 0;
}
......
......@@ -84,7 +84,7 @@
*/
static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
static void do_xprt_transmit(struct rpc_task *);
static void xprt_reserve_status(struct rpc_task *task);
static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_disconnect(struct rpc_xprt *);
static void xprt_reconn_status(struct rpc_task *task);
static struct socket *xprt_create_socket(int, struct rpc_timeout *);
......@@ -1179,61 +1179,39 @@ do_xprt_transmit(struct rpc_task *task)
/*
* Reserve an RPC call slot.
*/
int
void
xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
/* We already have an initialized request. */
if (task->tk_rqstp)
return 0;
spin_lock(&xprt->xprt_lock);
xprt_reserve_status(task);
if (task->tk_rqstp) {
task->tk_timeout = 0;
} else if (!task->tk_timeout) {
task->tk_status = -ENOBUFS;
} else {
dprintk("RPC: xprt_reserve waiting on backlog\n");
task->tk_status = -EAGAIN;
rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
task->tk_status = -EIO;
if (!xprt->shutdown) {
spin_lock(&xprt->xprt_lock);
do_xprt_reserve(task);
spin_unlock(&xprt->xprt_lock);
}
spin_unlock(&xprt->xprt_lock);
dprintk("RPC: %4d xprt_reserve returns %d\n",
task->tk_pid, task->tk_status);
return task->tk_status;
}
/*
* Reservation callback
*/
static void
xprt_reserve_status(struct rpc_task *task)
static inline void
do_xprt_reserve(struct rpc_task *task)
{
struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_rqst *req;
if (xprt->shutdown) {
task->tk_status = -EIO;
} else if (task->tk_status < 0) {
/* NOP */
} else if (task->tk_rqstp) {
/* We've already been given a request slot: NOP */
} else {
if (!(req = xprt->free))
goto out_nofree;
/* OK: There's room for us. Grab a free slot */
xprt->free = req->rq_next;
req->rq_next = NULL;
task->tk_status = 0;
if (task->tk_rqstp)
return;
if (xprt->free) {
struct rpc_rqst *req = xprt->free;
xprt->free = req->rq_next;
req->rq_next = NULL;
task->tk_rqstp = req;
xprt_request_init(task, xprt);
return;
}
return;
out_nofree:
dprintk("RPC: waiting for request slot\n");
task->tk_status = -EAGAIN;
task->tk_timeout = 0;
rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
}
/*
......@@ -1249,7 +1227,6 @@ xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
xid = CURRENT_TIME << 12;
dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, xid);
task->tk_status = 0;
req->rq_timeout = xprt->timeout;
req->rq_task = task;
req->rq_xprt = xprt;
......@@ -1311,7 +1288,6 @@ xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long incr)
to->to_initval =
to->to_increment = incr;
to->to_maxval = incr * retr;
to->to_resrvval = incr * retr;
to->to_retries = retr;
to->to_exponential = 0;
}
......@@ -1352,7 +1328,6 @@ xprt_setup(struct socket *sock, int proto,
if (to) {
xprt->timeout = *to;
xprt->timeout.to_current = to->to_initval;
xprt->timeout.to_resrvval = to->to_maxval << 1;
} else
xprt_default_timeout(&xprt->timeout, xprt->prot);
......
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