RDS: move rds_shutdown_worker impl. to rds_conn_shutdown
This fits better in connection.c, rather than threads.c. Signed-off-by: Andy Grover <andy.grover@oracle.com>
This commit is contained in:
Родитель
9de0864cf5
Коммит
2dc3935734
|
@ -263,6 +263,59 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
|
EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
|
||||||
|
|
||||||
|
void rds_conn_shutdown(struct rds_connection *conn)
|
||||||
|
{
|
||||||
|
/* shut it down unless it's down already */
|
||||||
|
if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
|
||||||
|
/*
|
||||||
|
* Quiesce the connection mgmt handlers before we start tearing
|
||||||
|
* things down. We don't hold the mutex for the entire
|
||||||
|
* duration of the shutdown operation, else we may be
|
||||||
|
* deadlocking with the CM handler. Instead, the CM event
|
||||||
|
* handler is supposed to check for state DISCONNECTING
|
||||||
|
*/
|
||||||
|
mutex_lock(&conn->c_cm_lock);
|
||||||
|
if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING)
|
||||||
|
&& !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
|
||||||
|
rds_conn_error(conn, "shutdown called in state %d\n",
|
||||||
|
atomic_read(&conn->c_state));
|
||||||
|
mutex_unlock(&conn->c_cm_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mutex_unlock(&conn->c_cm_lock);
|
||||||
|
|
||||||
|
mutex_lock(&conn->c_send_lock);
|
||||||
|
conn->c_trans->conn_shutdown(conn);
|
||||||
|
rds_conn_reset(conn);
|
||||||
|
mutex_unlock(&conn->c_send_lock);
|
||||||
|
|
||||||
|
if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
|
||||||
|
/* This can happen - eg when we're in the middle of tearing
|
||||||
|
* down the connection, and someone unloads the rds module.
|
||||||
|
* Quite reproduceable with loopback connections.
|
||||||
|
* Mostly harmless.
|
||||||
|
*/
|
||||||
|
rds_conn_error(conn,
|
||||||
|
"%s: failed to transition to state DOWN, "
|
||||||
|
"current state is %d\n",
|
||||||
|
__func__,
|
||||||
|
atomic_read(&conn->c_state));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then reconnect if it's still live.
|
||||||
|
* The passive side of an IB loopback connection is never added
|
||||||
|
* to the conn hash, so we never trigger a reconnect on this
|
||||||
|
* conn - the reconnect is always triggered by the active peer. */
|
||||||
|
cancel_delayed_work_sync(&conn->c_conn_w);
|
||||||
|
if (!hlist_unhashed(&conn->c_hash_node))
|
||||||
|
rds_queue_reconnect(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stop and free a connection.
|
||||||
|
*/
|
||||||
void rds_conn_destroy(struct rds_connection *conn)
|
void rds_conn_destroy(struct rds_connection *conn)
|
||||||
{
|
{
|
||||||
struct rds_message *rm, *rtmp;
|
struct rds_message *rm, *rtmp;
|
||||||
|
|
|
@ -527,6 +527,7 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
|
||||||
struct rds_transport *trans, gfp_t gfp);
|
struct rds_transport *trans, gfp_t gfp);
|
||||||
struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
|
struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
|
||||||
struct rds_transport *trans, gfp_t gfp);
|
struct rds_transport *trans, gfp_t gfp);
|
||||||
|
void rds_conn_shutdown(struct rds_connection *conn);
|
||||||
void rds_conn_destroy(struct rds_connection *conn);
|
void rds_conn_destroy(struct rds_connection *conn);
|
||||||
void rds_conn_reset(struct rds_connection *conn);
|
void rds_conn_reset(struct rds_connection *conn);
|
||||||
void rds_conn_drop(struct rds_connection *conn);
|
void rds_conn_drop(struct rds_connection *conn);
|
||||||
|
@ -681,6 +682,7 @@ extern unsigned int rds_sysctl_trace_level;
|
||||||
int __init rds_threads_init(void);
|
int __init rds_threads_init(void);
|
||||||
void rds_threads_exit(void);
|
void rds_threads_exit(void);
|
||||||
extern struct workqueue_struct *rds_wq;
|
extern struct workqueue_struct *rds_wq;
|
||||||
|
void rds_queue_reconnect(struct rds_connection *conn);
|
||||||
void rds_connect_worker(struct work_struct *);
|
void rds_connect_worker(struct work_struct *);
|
||||||
void rds_shutdown_worker(struct work_struct *);
|
void rds_shutdown_worker(struct work_struct *);
|
||||||
void rds_send_worker(struct work_struct *);
|
void rds_send_worker(struct work_struct *);
|
||||||
|
|
|
@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete);
|
||||||
* We should *always* start with a random backoff; otherwise a broken connection
|
* We should *always* start with a random backoff; otherwise a broken connection
|
||||||
* will always take several iterations to be re-established.
|
* will always take several iterations to be re-established.
|
||||||
*/
|
*/
|
||||||
static void rds_queue_reconnect(struct rds_connection *conn)
|
void rds_queue_reconnect(struct rds_connection *conn)
|
||||||
{
|
{
|
||||||
unsigned long rand;
|
unsigned long rand;
|
||||||
|
|
||||||
|
@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rds_shutdown_worker(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
|
|
||||||
|
|
||||||
/* shut it down unless it's down already */
|
|
||||||
if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) {
|
|
||||||
/*
|
|
||||||
* Quiesce the connection mgmt handlers before we start tearing
|
|
||||||
* things down. We don't hold the mutex for the entire
|
|
||||||
* duration of the shutdown operation, else we may be
|
|
||||||
* deadlocking with the CM handler. Instead, the CM event
|
|
||||||
* handler is supposed to check for state DISCONNECTING
|
|
||||||
*/
|
|
||||||
mutex_lock(&conn->c_cm_lock);
|
|
||||||
if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) &&
|
|
||||||
!rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) {
|
|
||||||
rds_conn_error(conn, "shutdown called in state %d\n",
|
|
||||||
atomic_read(&conn->c_state));
|
|
||||||
mutex_unlock(&conn->c_cm_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mutex_unlock(&conn->c_cm_lock);
|
|
||||||
|
|
||||||
mutex_lock(&conn->c_send_lock);
|
|
||||||
conn->c_trans->conn_shutdown(conn);
|
|
||||||
rds_conn_reset(conn);
|
|
||||||
mutex_unlock(&conn->c_send_lock);
|
|
||||||
|
|
||||||
if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) {
|
|
||||||
/* This can happen - eg when we're in the middle of tearing
|
|
||||||
* down the connection, and someone unloads the rds module.
|
|
||||||
* Quite reproduceable with loopback connections.
|
|
||||||
* Mostly harmless.
|
|
||||||
*/
|
|
||||||
rds_conn_error(conn,
|
|
||||||
"%s: failed to transition to state DOWN, "
|
|
||||||
"current state is %d\n",
|
|
||||||
__func__,
|
|
||||||
atomic_read(&conn->c_state));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then reconnect if it's still live.
|
|
||||||
* The passive side of an IB loopback connection is never added
|
|
||||||
* to the conn hash, so we never trigger a reconnect on this
|
|
||||||
* conn - the reconnect is always triggered by the active peer. */
|
|
||||||
cancel_delayed_work(&conn->c_conn_w);
|
|
||||||
if (!hlist_unhashed(&conn->c_hash_node))
|
|
||||||
rds_queue_reconnect(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rds_send_worker(struct work_struct *work)
|
void rds_send_worker(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work);
|
struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work);
|
||||||
|
@ -252,6 +200,13 @@ void rds_recv_worker(struct work_struct *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rds_shutdown_worker(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w);
|
||||||
|
|
||||||
|
rds_conn_shutdown(conn);
|
||||||
|
}
|
||||||
|
|
||||||
void rds_threads_exit(void)
|
void rds_threads_exit(void)
|
||||||
{
|
{
|
||||||
destroy_workqueue(rds_wq);
|
destroy_workqueue(rds_wq);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче