IB/qib: optimize CQ callbacks
PATCH 1/1 IB/qib: optimize CQ callbacks
The current workqueue implemention has the following performance deficiencies on QDR HCAs:
- The CQ call backs tend to run on the CPUs processing the receive queues
- The single thread queue isn't optimal for multiple HCAs
This patch adds a dedicated per HCA bound thread to process CQ callbacks.
Reviewed-by Ramkrishna Vepa <[email protected]>
Signed-off-by Mike Marciniszyn <[email protected]>
--- drivers/infiniband/hw/qib/qib.h | 5 ++ drivers/infiniband/hw/qib/qib_cq.c | 67 ++++++++++++++++++++++++++++++--- drivers/infiniband/hw/qib/qib_init.c | 18 ++------- drivers/infiniband/hw/qib/qib_verbs.h | 10 +++-- 4 files changed, 76 insertions(+), 24 deletions(-)
drivers/infiniband/hw/qib/qib.h +4 -1
@@ -1,7 +1,7 @@#ifndef _QIB_KERNEL_H#define _QIB_KERNEL_H/* -* Copyright (c) 2012 Intel Corporation. All rights reserved. +* Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. *
@@ -51,6 +51,7 @@#include <linux/completion.h> #include <linux/kref.h> #include <linux/sched.h> +#include <linux/kthread.h> #include "qib_common.h" #include "qib_verbs.h"
@@ -1094,6 +1095,8 @@ struct qib_devdata {u16 psxmitwait_check_rate;/* high volume overflow errors defered to tasklet */ struct tasklet_struct error_tasklet; +/* per device cq worker */ +struct kthread_worker *worker;int assigned_node_id;/* NUMA node closest to HCA */ };
drivers/infiniband/hw/qib/qib_cq.c +61 -6
114 lines not on this page · raw message
drivers/infiniband/hw/qib/qib_init.c +4 -14
@@ -97,8 +97,6 @@ unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */module_param_named (wc_pat, qib_wc_pat, uint,S_IRUGO );MODULE_PARM_DESC (wc_pat,"enable write-combining via PAT mechanism" ); -struct workqueue_struct *qib_cq_wq; -static void verify_interrupt (unsigned long );static struct idr qib_unit_table;
@@ -445,6 +443,7 @@ static int loadtime_init(struct qib_devdata *dd) dd->intrchk_timer.function = verify_interrupt; dd->intrchk_timer.data = (unsigned long ) dd; + ret =qib_cq_init (dd); done:return ret; }
@@ -1215,12 +1214,6 @@ static int __init qlogic_ib_init(void)if (ret) goto bail; - qib_cq_wq =create_singlethread_workqueue ("qib_cq" ); -if (!qib_cq_wq) { - ret = -ENOMEM ; - goto bail_dev; - } -/* * These must be called before the driver is registered with * the PCI subsystem.
@@ -1233,7 +1226,7 @@ static int __init qlogic_ib_init(void) ret =pci_register_driver (&qib_driver);if (ret <0 ) {pr_err ("Unable to register driver: error %d\n" , -ret); - goto bail_unit; + goto bail_dev; }/* not fatal if it doesn't work */
@@ -1241,13 +1234,11 @@ static int __init qlogic_ib_init(void)pr_err ("Unable to register ipathfs\n" ); goto bail;/* all OK */ -bail_unit: +bail_dev:#ifdef CONFIG_INFINIBAND_QIB_DCA dca_unregister_notify (&dca_notifier);#endif idr_destroy (&qib_unit_table); -destroy_workqueue (qib_cq_wq); -bail_dev:qib_dev_cleanup (); bail:return ret;
@@ -1273,8 +1264,6 @@ static void __exit qlogic_ib_cleanup(void)#endif pci_unregister_driver (&qib_driver); -destroy_workqueue (qib_cq_wq); - qib_cpulist_count =0 ;kfree (qib_cpulist);
@@ -1365,6 +1354,7 @@ static void cleanup_device_data(struct qib_devdata *dd) }kfree (tmp);kfree (dd->boardname); +qib_cq_exit (dd); }/*
drivers/infiniband/hw/qib/qib_verbs.h +7 -3
@@ -41,6 +41,7 @@#include <linux/interrupt.h> #include <linux/kref.h> #include <linux/workqueue.h> +#include <linux/kthread.h> #include <linux/completion.h> #include <rdma/ib_pack.h> #include <rdma/ib_user_verbs.h>
@@ -267,7 +268,8 @@ struct qib_cq_wc {*/ struct qib_cq {struct ib_cq ibcq; -struct work_struct comptask; +struct kthread_work comptask; +struct qib_devdata *dd;spinlock_t lock;/* protect changes in this struct */ u8 notify;u8 triggered;
@@ -832,8 +834,6 @@ static inline int qib_send_ok(struct qib_qp *qp) !(qp->s_flags & QIB_S_ANY_WAIT_SEND)); } -extern struct workqueue_struct *qib_cq_wq; -/* * This must be called with s_lock held. */
@@ -972,6 +972,10 @@ int qib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr);int qib_destroy_srq (struct ib_srq *ibsrq); +int qib_cq_init (struct qib_devdata *dd); + +void qib_cq_exit (struct qib_devdata *dd); +void qib_cq_enter (struct qib_cq *cq,struct ib_wc *entry,int sig);int qib_poll_cq (struct ib_cq *ibcq,int num_entries,struct ib_wc *entry);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html