From a9009e3d328b9b999a4ca6e1837199c5886aaea4 Mon Sep 17 00:00:00 2001 From: Chien-Hua Yen Date: Thu, 22 May 2014 21:57:06 -0700 Subject: [PATCH] RDS: add workqueue for local loopback connections Switch reboot takes too long to recover Orabug: 18892366 Signed-off-by: Chien-Hua Yen Signed-off-by: Bang Nguyen Signed-off-by: Ajaykumar Hotchandani (cherry picked from commit 38a7f3de7dfbae339ff82149277f7794cd925711) --- net/rds/connection.c | 7 ++++++- net/rds/ib.c | 1 + net/rds/rds.h | 1 + net/rds/threads.c | 21 ++++++++++++++++++--- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index c57e2d953f8b..c973425cb354 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -640,7 +640,12 @@ void rds_conn_drop(struct rds_connection *conn) conn->c_reconnect_drops++; atomic_set(&conn->c_state, RDS_CONN_ERROR); - queue_work(rds_wq, &conn->c_down_w); + + if (conn->c_loopback) + queue_work(rds_local_wq, &conn->c_down_w); + else + queue_work(rds_wq, &conn->c_down_w); + } EXPORT_SYMBOL_GPL(rds_conn_drop); diff --git a/net/rds/ib.c b/net/rds/ib.c index f75a95c4fc7c..187f2c909161 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -1560,6 +1560,7 @@ static void rds_ib_unregister_client(void) ib_unregister_client(&rds_ib_client); /* wait for rds_ib_dev_free() to complete */ flush_workqueue(rds_wq); + flush_workqueue(rds_local_wq); } static void rds_ib_update_ip_config(void) diff --git a/net/rds/rds.h b/net/rds/rds.h index 9f6d29fbb30f..0295ee34f354 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -866,6 +866,7 @@ extern unsigned int rds_sysctl_trace_level; int rds_threads_init(void); void rds_threads_exit(void); extern struct workqueue_struct *rds_wq; +extern struct workqueue_struct *rds_local_wq; void rds_queue_reconnect(struct rds_connection *conn); void rds_connect_worker(struct work_struct *); void rds_shutdown_worker(struct work_struct *); diff --git a/net/rds/threads.c b/net/rds/threads.c index c911cdc701a8..7ef1948b6734 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -74,6 +74,8 @@ MODULE_PARM_DESC(rds_conn_hb_timeout, " Connection heartbeat timeout"); */ struct workqueue_struct *rds_wq; EXPORT_SYMBOL_GPL(rds_wq); +struct workqueue_struct *rds_local_wq; +EXPORT_SYMBOL_GPL(rds_local_wq); void rds_connect_complete(struct rds_connection *conn) { @@ -141,11 +143,19 @@ void rds_queue_reconnect(struct rds_connection *conn) rdsdebug("%lu delay %lu ceil conn %p for %pI4 -> %pI4\n", rand % conn->c_reconnect_jiffies, conn->c_reconnect_jiffies, conn, &conn->c_laddr, &conn->c_faddr); - if (conn->c_laddr >= conn->c_faddr) - queue_delayed_work(rds_wq, &conn->c_conn_w, + + if (conn->c_loopback) { + if (conn->c_laddr >= conn->c_faddr) + queue_delayed_work(rds_local_wq, &conn->c_conn_w, + rand % conn->c_reconnect_jiffies); + else + queue_delayed_work(rds_local_wq, &conn->c_conn_w, + msecs_to_jiffies(100)); + } else if (conn->c_laddr >= conn->c_faddr) + queue_delayed_work(rds_wq, &conn->c_conn_w, rand % conn->c_reconnect_jiffies); else - queue_delayed_work(rds_wq, &conn->c_conn_w, + queue_delayed_work(rds_wq, &conn->c_conn_w, msecs_to_jiffies(100)); conn->c_reconnect_jiffies = min(conn->c_reconnect_jiffies * 2, @@ -298,6 +308,7 @@ void rds_shutdown_worker(struct work_struct *work) void rds_threads_exit(void) { destroy_workqueue(rds_wq); + destroy_workqueue(rds_local_wq); } int rds_threads_init(void) @@ -306,5 +317,9 @@ int rds_threads_init(void) if (!rds_wq) return -ENOMEM; + rds_local_wq = create_singlethread_workqueue("krdsd_local"); + if (!rds_local_wq) + return -ENOMEM; + return 0; } -- 2.50.1