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);
|
struct rpc_xprt *xprt_create_transport(struct xprt_create *args);
|
||||||
void xprt_connect(struct rpc_task *task);
|
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_reserve(struct rpc_task *task);
|
||||||
void xprt_retry_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);
|
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_close);
|
||||||
DEFINE_RXPRT_EVENT(xprtrdma_op_connect);
|
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,
|
TRACE_EVENT(xprtrdma_qp_event,
|
||||||
TP_PROTO(
|
TP_PROTO(
|
||||||
const struct rpcrdma_xprt *r_xprt,
|
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 *rpciod_workqueue __read_mostly;
|
||||||
struct workqueue_struct *xprtiod_workqueue __read_mostly;
|
struct workqueue_struct *xprtiod_workqueue __read_mostly;
|
||||||
|
EXPORT_SYMBOL_GPL(xprtiod_workqueue);
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
rpc_task_timeout(const struct rpc_task *task)
|
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_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 {
|
enum xprt_xid_rb_cmp {
|
||||||
XID_RB_EQUAL,
|
XID_RB_EQUAL,
|
||||||
XID_RB_LEFT,
|
XID_RB_LEFT,
|
||||||
|
@ -298,6 +298,7 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
|
|||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 60 second timeout, no retries */
|
||||||
static const struct rpc_timeout xprt_rdma_default_timeout = {
|
static const struct rpc_timeout xprt_rdma_default_timeout = {
|
||||||
.to_initval = 60 * HZ,
|
.to_initval = 60 * HZ,
|
||||||
.to_maxval = 60 * HZ,
|
.to_maxval = 60 * HZ,
|
||||||
@ -323,8 +324,9 @@ xprt_setup_rdma(struct xprt_create *args)
|
|||||||
if (!xprt)
|
if (!xprt)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
/* 60 second timeout, no retries */
|
|
||||||
xprt->timeout = &xprt_rdma_default_timeout;
|
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->bind_timeout = RPCRDMA_BIND_TO;
|
||||||
xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
|
xprt->reestablish_timeout = RPCRDMA_INIT_REEST_TO;
|
||||||
xprt->idle_timeout = RPCRDMA_IDLE_DISC_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
|
* @xprt: transport state
|
||||||
* @task: RPC scheduler context
|
* @task: RPC scheduler context (unused)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
||||||
{
|
{
|
||||||
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
|
||||||
|
unsigned long delay;
|
||||||
|
|
||||||
trace_xprtrdma_op_connect(r_xprt);
|
trace_xprtrdma_op_connect(r_xprt);
|
||||||
|
|
||||||
|
delay = 0;
|
||||||
if (r_xprt->rx_ep.rep_connected != 0) {
|
if (r_xprt->rx_ep.rep_connected != 0) {
|
||||||
/* Reconnect */
|
delay = xprt_reconnect_delay(xprt);
|
||||||
schedule_delayed_work(&r_xprt->rx_connect_worker,
|
xprt_reconnect_backoff(xprt, RPCRDMA_INIT_REEST_TO);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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,
|
.send_request = xprt_rdma_send_request,
|
||||||
.close = xprt_rdma_close,
|
.close = xprt_rdma_close,
|
||||||
.destroy = xprt_rdma_destroy,
|
.destroy = xprt_rdma_destroy,
|
||||||
|
.set_connect_timeout = xprt_rdma_tcp_set_connect_timeout,
|
||||||
.print_stats = xprt_rdma_print_stats,
|
.print_stats = xprt_rdma_print_stats,
|
||||||
.enable_swap = xprt_rdma_enable_swap,
|
.enable_swap = xprt_rdma_enable_swap,
|
||||||
.disable_swap = xprt_rdma_disable_swap,
|
.disable_swap = xprt_rdma_disable_swap,
|
||||||
|
@ -432,6 +432,7 @@ struct rpcrdma_xprt {
|
|||||||
struct rpcrdma_ep rx_ep;
|
struct rpcrdma_ep rx_ep;
|
||||||
struct rpcrdma_buffer rx_buf;
|
struct rpcrdma_buffer rx_buf;
|
||||||
struct delayed_work rx_connect_worker;
|
struct delayed_work rx_connect_worker;
|
||||||
|
struct rpc_timeout rx_timeout;
|
||||||
struct rpcrdma_stats rx_stats;
|
struct rpcrdma_stats rx_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2402,25 +2402,6 @@ out:
|
|||||||
xprt_wake_pending_tasks(xprt, status);
|
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
|
* xs_connect - connect a socket to a remote endpoint
|
||||||
* @xprt: pointer to transport structure
|
* @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 */
|
/* Start by resetting any existing state */
|
||||||
xs_reset_transport(transport);
|
xs_reset_transport(transport);
|
||||||
|
|
||||||
delay = xs_reconnect_delay(xprt);
|
delay = xprt_reconnect_delay(xprt);
|
||||||
xs_reconnect_backoff(xprt);
|
xprt_reconnect_backoff(xprt, XS_TCP_INIT_REEST_TO);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
|
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
|
||||||
|
Loading…
Reference in New Issue
Block a user