|
@@ -2173,6 +2173,8 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
|
|
write_unlock_bh(&sk->sk_callback_lock);
|
|
write_unlock_bh(&sk->sk_callback_lock);
|
|
}
|
|
}
|
|
xs_udp_do_set_buffer_size(xprt);
|
|
xs_udp_do_set_buffer_size(xprt);
|
|
|
|
+
|
|
|
|
+ xprt->stat.connect_start = jiffies;
|
|
}
|
|
}
|
|
|
|
|
|
static void xs_udp_setup_socket(struct work_struct *work)
|
|
static void xs_udp_setup_socket(struct work_struct *work)
|
|
@@ -2384,6 +2386,16 @@ 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;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 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
|
|
@@ -2401,6 +2413,7 @@ out:
|
|
static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|
static void xs_connect(struct rpc_xprt *xprt, struct rpc_task *task)
|
|
{
|
|
{
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
|
|
+ unsigned long delay = 0;
|
|
|
|
|
|
WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
|
|
WARN_ON_ONCE(!xprt_lock_connect(xprt, task, transport));
|
|
|
|
|
|
@@ -2412,19 +2425,19 @@ 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);
|
|
|
|
|
|
- queue_delayed_work(xprtiod_workqueue,
|
|
|
|
- &transport->connect_worker,
|
|
|
|
- xprt->reestablish_timeout);
|
|
|
|
|
|
+ delay = xs_reconnect_delay(xprt);
|
|
|
|
+
|
|
xprt->reestablish_timeout <<= 1;
|
|
xprt->reestablish_timeout <<= 1;
|
|
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
|
|
if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO)
|
|
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
|
|
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
|
|
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
|
|
if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
|
|
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
|
|
xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
|
|
- } else {
|
|
|
|
|
|
+ } else
|
|
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
|
|
dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
|
|
- queue_delayed_work(xprtiod_workqueue,
|
|
|
|
- &transport->connect_worker, 0);
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ queue_delayed_work(xprtiod_workqueue,
|
|
|
|
+ &transport->connect_worker,
|
|
|
|
+ delay);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|