xprtrdma: Modernize ops->connect
Adapt and apply changes that were made to the TCP socket connect code. See the following commits for details on the purpose of these changes: Commit7196dbb02e
("SUNRPC: Allow changing of the TCP timeout parameters on the fly") Commit3851f1cdb2
("SUNRPC: Limit the reconnect backoff timer to the max RPC message timeout") Commit02910177ae
("SUNRPC: Fix reconnection timeouts") Some common transport code is moved to xprt.c to satisfy the code duplication police. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
5828cebad1
commit
675dd90ad0
|
@ -334,6 +334,9 @@ struct xprt_class {
|
|||
*/
|
||||
struct rpc_xprt *xprt_create_transport(struct xprt_create *args);
|
||||
void xprt_connect(struct rpc_task *task);
|
||||
unsigned long xprt_reconnect_delay(const struct rpc_xprt *xprt);
|
||||
void xprt_reconnect_backoff(struct rpc_xprt *xprt,
|
||||
unsigned long init_to);
|
||||
void xprt_reserve(struct rpc_task *task);
|
||||
void xprt_retry_reserve(struct rpc_task *task);
|
||||
int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task);
|
||||
|
|
|
@ -375,6 +375,37 @@ DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);
|
|||
DEFINE_RXPRT_EVENT(xprtrdma_op_close);
|
||||
DEFINE_RXPRT_EVENT(xprtrdma_op_connect);
|
||||
|
||||
TRACE_EVENT(xprtrdma_op_set_cto,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_xprt *r_xprt,
|
||||
unsigned long connect,
|
||||
unsigned long reconnect
|
||||
),
|
||||
|
||||
TP_ARGS(r_xprt, connect, reconnect),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const void *, r_xprt)
|
||||
__field(unsigned long, connect)
|
||||
__field(unsigned long, reconnect)
|
||||
__string(addr, rpcrdma_addrstr(r_xprt))
|
||||
__string(port, rpcrdma_portstr(r_xprt))
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->r_xprt = r_xprt;
|
||||
__entry->connect = connect;
|
||||
__entry->reconnect = reconnect;
|
||||
__assign_str(addr, rpcrdma_addrstr(r_xprt));
|
||||
__assign_str(port, rpcrdma_portstr(r_xprt));
|
||||
),
|
||||
|
||||
TP_printk("peer=[%s]:%s r_xprt=%p: connect=%lu reconnect=%lu",
|
||||
__get_str(addr), __get_str(port), __entry->r_xprt,
|
||||
__entry->connect / HZ, __entry->reconnect / HZ
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(xprtrdma_qp_event,
|
||||
TP_PROTO(
|
||||
const struct rpcrdma_xprt *r_xprt,
|
||||
|
|
|
@ -58,6 +58,7 @@ static struct rpc_wait_queue delay_queue;
|
|||
*/
|
||||
struct workqueue_struct *rpciod_workqueue __read_mostly;
|
||||
struct workqueue_struct *xprtiod_workqueue __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(xprtiod_workqueue);
|
||||
|
||||
unsigned long
|
||||
rpc_task_timeout(const struct rpc_task *task)
|
||||
|
|
|
@ -850,6 +850,38 @@ void xprt_connect(struct rpc_task *task)
|
|||
xprt_release_write(xprt, task);
|
||||
}
|
||||
|
||||
/**
|
||||
* xprt_reconnect_delay - compute the wait before scheduling a connect
|
||||
* @xprt: transport instance
|
||||
*
|
||||
*/
|
||||
unsigned long xprt_reconnect_delay(const struct rpc_xprt *xprt)
|
||||
{
|
||||
unsigned long start, now = jiffies;
|
||||
|
||||
start = xprt->stat.connect_start + xprt->reestablish_timeout;
|
||||
if (time_after(start, now))
|
||||
return start - now;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xprt_reconnect_delay);
|
||||
|
||||
/**
|
||||
* xprt_reconnect_backoff - compute the new re-establish timeout
|
||||
* @xprt: transport instance
|
||||
* @init_to: initial reestablish timeout
|
||||
*
|
||||
*/
|
||||
void xprt_reconnect_backoff(struct rpc_xprt *xprt, unsigned long init_to)
|
||||
{
|
||||
xprt->reestablish_timeout <<= 1;
|
||||
if (xprt->reestablish_timeout > xprt->max_reconnect_timeout)
|
||||
xprt->reestablish_timeout = xprt->max_reconnect_timeout;
|
||||
if (xprt->reestablish_timeout < init_to)
|
||||
xprt->reestablish_timeout = init_to;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xprt_reconnect_backoff);
|
||||
|
||||
enum xprt_xid_rb_cmp {
|
||||
XID_RB_EQUAL,
|
||||
XID_RB_LEFT,
|
||||
|
|
|
@ -298,6 +298,7 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
|
|||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
/* 60 second timeout, no retries */
|
||||
static const struct rpc_timeout xprt_rdma_default_timeout = {
|
||||
.to_initval = 60 * HZ,
|
||||
.to_maxval = 60 * HZ,
|
||||
|
@ -323,8 +324,9 @@ xprt_setup_rdma(struct xprt_create *args)
|
|||
if (!xprt)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/* 60 second timeout, no retries */
|
||||
xprt->timeout = &xprt_rdma_default_timeout;
|
||||
xprt->connect_timeout = xprt->timeout->to_initval;
|
||||
xprt->max_reconnect_timeout = xprt->timeout->to_maxval;
|
||||
xprt->bind_timeout = RPCRDMA_BIND_TO;
|
||||
xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
|
||||
xprt->idle_timeout = RPCRDMA_IDLE_DISC_TO;
|
||||
|
@ -487,31 +489,64 @@ xprt_rdma_timer(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||
}
|
||||
|
||||
/**
|
||||
* xprt_rdma_connect - try to establish a transport connection
|
||||
* xprt_rdma_set_connect_timeout - set timeouts for establishing a connection
|
||||
* @xprt: controlling transport instance
|
||||
* @connect_timeout: reconnect timeout after client disconnects
|
||||
* @reconnect_timeout: reconnect timeout after server disconnects
|
||||
*
|
||||
*/
|
||||
static void xprt_rdma_tcp_set_connect_timeout(struct rpc_xprt *xprt,
|
||||
unsigned long connect_timeout,
|
||||
unsigned long reconnect_timeout)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
|
||||
trace_xprtrdma_op_set_cto(r_xprt, connect_timeout, reconnect_timeout);
|
||||
|
||||
spin_lock(&xprt->transport_lock);
|
||||
|
||||
if (connect_timeout < xprt->connect_timeout) {
|
||||
struct rpc_timeout to;
|
||||
unsigned long initval;
|
||||
|
||||
to = *xprt->timeout;
|
||||
initval = connect_timeout;
|
||||
if (initval < RPCRDMA_INIT_REEST_TO << 1)
|
||||
initval = RPCRDMA_INIT_REEST_TO << 1;
|
||||
to.to_initval = initval;
|
||||
to.to_maxval = initval;
|
||||
r_xprt->rx_timeout = to;
|
||||
xprt->timeout = &r_xprt->rx_timeout;
|
||||
xprt->connect_timeout = connect_timeout;
|
||||
}
|
||||
|
||||
if (reconnect_timeout < xprt->max_reconnect_timeout)
|
||||
xprt->max_reconnect_timeout = reconnect_timeout;
|
||||
|
||||
spin_unlock(&xprt->transport_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* xprt_rdma_connect - schedule an attempt to reconnect
|
||||
* @xprt: transport state
|
||||
* @task: RPC scheduler context
|
||||
* @task: RPC scheduler context (unused)
|
||||
*
|
||||
*/
|
||||
static void
|
||||
xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
||||
{
|
||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||
unsigned long delay;
|
||||
|
||||
trace_xprtrdma_op_connect(r_xprt);
|
||||
|
||||
delay = 0;
|
||||
if (r_xprt->rx_ep.rep_connected != 0) {
|
||||
/* Reconnect */
|
||||
schedule_delayed_work(&r_xprt->rx_connect_worker,
|
||||
xprt->reestablish_timeout);
|
||||
xprt->reestablish_timeout <<= 1;
|
||||
if (xprt->reestablish_timeout > RPCRDMA_MAX_REEST_TO)
|
||||
xprt->reestablish_timeout = RPCRDMA_MAX_REEST_TO;
|
||||
else if (xprt->reestablish_timeout < RPCRDMA_INIT_REEST_TO)
|
||||
xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
|
||||
} else {
|
||||
schedule_delayed_work(&r_xprt->rx_connect_worker, 0);
|
||||
if (!RPC_IS_ASYNC(task))
|
||||
flush_delayed_work(&r_xprt->rx_connect_worker);
|
||||
delay = xprt_reconnect_delay(xprt);
|
||||
xprt_reconnect_backoff(xprt, RPCRDMA_INIT_REEST_TO);
|
||||
}
|
||||
queue_delayed_work(xprtiod_workqueue, &r_xprt->rx_connect_worker,
|
||||
delay);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -769,6 +804,7 @@ static const struct rpc_xprt_ops xprt_rdma_procs = {
|
|||
.send_request = xprt_rdma_send_request,
|
||||
.close = xprt_rdma_close,
|
||||
.destroy = xprt_rdma_destroy,
|
||||
.set_connect_timeout = xprt_rdma_tcp_set_connect_timeout,
|
||||
.print_stats = xprt_rdma_print_stats,
|
||||
.enable_swap = xprt_rdma_enable_swap,
|
||||
.disable_swap = xprt_rdma_disable_swap,
|
||||
|
|
|
@ -432,6 +432,7 @@ struct rpcrdma_xprt {
|
|||
struct rpcrdma_ep rx_ep;
|
||||
struct rpcrdma_buffer rx_buf;
|
||||
struct delayed_work rx_connect_worker;
|
||||
struct rpc_timeout rx_timeout;
|
||||
struct rpcrdma_stats rx_stats;
|
||||
};
|
||||
|
||||
|
|
|
@ -2402,25 +2402,6 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|||
xprt_wake_pending_tasks(xprt, status);
|
||||
}
|
||||
|
||||
static unsigned long xs_reconnect_delay(const struct rpc_xprt *xprt)
|
||||
{
|
||||
unsigned long start, now = jiffies;
|
||||
|
||||
start = xprt->stat.connect_start + xprt->reestablish_timeout;
|
||||
if (time_after(start, now))
|
||||
return start - now;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xs_reconnect_backoff(struct rpc_xprt *xprt)
|
||||
{
|
||||
xprt->reestablish_timeout <<= 1;
|
||||
if (xprt->reestablish_timeout > xprt->max_reconnect_timeout)
|
||||
xprt->reestablish_timeout = xprt->max_reconnect_timeout;
|
||||
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
|
||||
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
|
||||
}
|
||||
|
||||
/**
|
||||
* xs_connect - connect a socket to a remote endpoint
|
||||
* @xprt: pointer to transport structure
|
||||
|
@ -2450,8 +2431,8 @@ static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|||
/* Start by resetting any existing state */
|
||||
xs_reset_transport(transport);
|
||||
|
||||
delay = xs_reconnect_delay(xprt);
|
||||
xs_reconnect_backoff(xprt);
|
||||
delay = xprt_reconnect_delay(xprt);
|
||||
xprt_reconnect_backoff(xprt, XS_TCP_INIT_REEST_TO);
|
||||
|
||||
} else
|
||||
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
|
||||
|
|
Loading…
Reference in New Issue