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);
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 *);
*/
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)
{
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,
void rds_threads_exit(void)
{
destroy_workqueue(rds_wq);
+ destroy_workqueue(rds_local_wq);
}
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;
}