RDS uses rds_wq for various operations. During ADDR_CHANGE event,
each connection queues at least two tasks into this single-threaded
workqueue. Furthermore, the TOS connections have dependency on its
base connection. Thus, a separate workqueue is created specifically
for the base connections to speed up base connection establishment.
Orabug:
25521901
Signed-off-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Reviewed-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>
Reviewed-by: Ajaykumar Hotchandani <ajaykumar.hotchandani@oracle.com>
Tested-by: Dib Chatterjee <dib.chatterjee@oracle.com>
Tested-by: Rosa Isela Lopez Romero <rosa.lopez@oracle.com>
}
conn->c_trans = trans;
-
init_waitqueue_head(&conn->c_hs_waitq);
for (i = 0; i < RDS_MPATH_WORKERS; i++) {
struct rds_conn_path *cp;
if (conn->c_loopback)
cp->cp_wq = rds_local_wq;
else
- cp->cp_wq = rds_wq;
+ cp->cp_wq = tos ? rds_wq : rds_tos_wq;
}
ret = trans->conn_alloc(conn, gfp);
if (ret) {
ib_unregister_client(&rds_ib_client);
/* wait for rds_ib_dev_free() to complete */
flush_workqueue(rds_ip_wq);
+ flush_workqueue(rds_wq);
+ flush_workqueue(rds_tos_wq);
flush_workqueue(rds_local_wq);
}
int rds_threads_init(void);
void rds_threads_exit(void);
extern struct workqueue_struct *rds_wq;
+extern struct workqueue_struct *rds_tos_wq;
extern struct workqueue_struct *rds_local_wq;
void rds_queue_reconnect(struct rds_conn_path *cp);
void rds_connect_worker(struct work_struct *);
*/
struct workqueue_struct *rds_wq;
EXPORT_SYMBOL_GPL(rds_wq);
+struct workqueue_struct *rds_tos_wq;
+EXPORT_SYMBOL_GPL(rds_tos_wq);
struct workqueue_struct *rds_local_wq;
EXPORT_SYMBOL_GPL(rds_local_wq);
void rds_threads_exit(void)
{
destroy_workqueue(rds_wq);
+ destroy_workqueue(rds_tos_wq);
destroy_workqueue(rds_local_wq);
}
if (!rds_wq)
return -ENOMEM;
+ rds_tos_wq = create_singlethread_workqueue("krdsd_tos");
+ if (!rds_wq)
+ return -ENOMEM;
+
rds_local_wq = create_singlethread_workqueue("krdsd_local");
if (!rds_local_wq)
return -ENOMEM;