Commit 7b3fef8e authored by Trond Myklebust's avatar Trond Myklebust
Browse files

SUNRPC: Respect RPC call timeouts when retrying transmission



Fix a regression where soft and softconn requests are not timing out
as expected.

Fixes: 89f90fe1 ("SUNRPC: Allow calls to xprt_transmit() to drain...")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 477687e1
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ static int rpc_encode_header(struct rpc_task *task,
static int	rpc_decode_header(struct rpc_task *task,
				  struct xdr_stream *xdr);
static int	rpc_ping(struct rpc_clnt *clnt);
static void	rpc_check_timeout(struct rpc_task *task);

static void rpc_register_client(struct rpc_clnt *clnt)
{
@@ -1962,8 +1963,7 @@ call_connect_status(struct rpc_task *task)
			break;
		if (clnt->cl_autobind) {
			rpc_force_rebind(clnt);
			task->tk_action = call_bind;
			return;
			goto out_retry;
		}
		/* fall through */
	case -ECONNRESET:
@@ -1983,16 +1983,19 @@ call_connect_status(struct rpc_task *task)
		/* fall through */
	case -ENOTCONN:
	case -EAGAIN:
		/* Check for timeouts before looping back to call_bind */
	case -ETIMEDOUT:
		task->tk_action = call_timeout;
		return;
		goto out_retry;
	case 0:
		clnt->cl_stats->netreconn++;
		task->tk_action = call_transmit;
		return;
	}
	rpc_exit(task, status);
	return;
out_retry:
	/* Check for timeouts before looping back to call_bind */
	task->tk_action = call_bind;
	rpc_check_timeout(task);
}

/*
@@ -2069,7 +2072,7 @@ call_transmit_status(struct rpc_task *task)
				trace_xprt_ping(task->tk_xprt,
						task->tk_status);
			rpc_exit(task, task->tk_status);
			break;
			return;
		}
		/* fall through */
	case -ECONNRESET:
@@ -2081,6 +2084,7 @@ call_transmit_status(struct rpc_task *task)
		task->tk_status = 0;
		break;
	}
	rpc_check_timeout(task);
}

#if defined(CONFIG_SUNRPC_BACKCHANNEL)
@@ -2217,7 +2221,7 @@ call_status(struct rpc_task *task)
	case -EPIPE:
	case -ENOTCONN:
	case -EAGAIN:
		task->tk_action = call_encode;
		task->tk_action = call_timeout;
		break;
	case -EIO:
		/* shutdown or soft timeout */
@@ -2231,20 +2235,13 @@ call_status(struct rpc_task *task)
	}
}

/*
 * 6a.	Handle RPC timeout
 * 	We do not release the request slot, so we keep using the
 *	same XID for all retransmits.
 */
static void
call_timeout(struct rpc_task *task)
rpc_check_timeout(struct rpc_task *task)
{
	struct rpc_clnt	*clnt = task->tk_client;

	if (xprt_adjust_timeout(task->tk_rqstp) == 0) {
		dprintk("RPC: %5u call_timeout (minor)\n", task->tk_pid);
		goto retry;
	}
	if (xprt_adjust_timeout(task->tk_rqstp) == 0)
		return;

	dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
	task->tk_timeouts++;
@@ -2280,10 +2277,19 @@ call_timeout(struct rpc_task *task)
	 * event? RFC2203 requires the server to drop all such requests.
	 */
	rpcauth_invalcred(task);
}

retry:
/*
 * 6a.	Handle RPC timeout
 * 	We do not release the request slot, so we keep using the
 *	same XID for all retransmits.
 */
static void
call_timeout(struct rpc_task *task)
{
	task->tk_action = call_encode;
	task->tk_status = 0;
	rpc_check_timeout(task);
}

/*