aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@qlogic.com>2011-12-23 08:03:41 -0500
committerRoland Dreier <roland@purestorage.com>2012-01-03 23:53:31 -0500
commit489471095170ed1c6d0341739a243461638b0e06 (patch)
treed5820187d1d24dac7526bba2dd4dafb47c1bb0b3 /drivers/infiniband
parenteddfb675256f49d14e8c5763098afe3eb2c93701 (diff)
IB/qib: Optimize locking for get_txreq()
The current code locks the QP s_lock, followed by the pending_lock, I guess to to protect against the allocate failing. This patch only locks the pending_lock, assuming that the empty case is an exeception, in which case the pending_lock is dropped, and the original code is executed. This will save a lock of s_lock in the normal case. The observation is that the sdma descriptors will deplete at twice the rate of txreq's, so this should be rare. Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index a894762da462..7b6c3bffa9d9 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -913,8 +913,8 @@ static void copy_io(u32 __iomem *piobuf, struct qib_sge_state *ss,
913 __raw_writel(last, piobuf); 913 __raw_writel(last, piobuf);
914} 914}
915 915
916static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, 916static noinline struct qib_verbs_txreq *__get_txreq(struct qib_ibdev *dev,
917 struct qib_qp *qp, int *retp) 917 struct qib_qp *qp)
918{ 918{
919 struct qib_verbs_txreq *tx; 919 struct qib_verbs_txreq *tx;
920 unsigned long flags; 920 unsigned long flags;
@@ -926,8 +926,9 @@ static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev,
926 struct list_head *l = dev->txreq_free.next; 926 struct list_head *l = dev->txreq_free.next;
927 927
928 list_del(l); 928 list_del(l);
929 spin_unlock(&dev->pending_lock);
930 spin_unlock_irqrestore(&qp->s_lock, flags);
929 tx = list_entry(l, struct qib_verbs_txreq, txreq.list); 931 tx = list_entry(l, struct qib_verbs_txreq, txreq.list);
930 *retp = 0;
931 } else { 932 } else {
932 if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK && 933 if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK &&
933 list_empty(&qp->iowait)) { 934 list_empty(&qp->iowait)) {
@@ -935,14 +936,33 @@ static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev,
935 qp->s_flags |= QIB_S_WAIT_TX; 936 qp->s_flags |= QIB_S_WAIT_TX;
936 list_add_tail(&qp->iowait, &dev->txwait); 937 list_add_tail(&qp->iowait, &dev->txwait);
937 } 938 }
938 tx = NULL;
939 qp->s_flags &= ~QIB_S_BUSY; 939 qp->s_flags &= ~QIB_S_BUSY;
940 *retp = -EBUSY; 940 spin_unlock(&dev->pending_lock);
941 spin_unlock_irqrestore(&qp->s_lock, flags);
942 tx = ERR_PTR(-EBUSY);
941 } 943 }
944 return tx;
945}
942 946
943 spin_unlock(&dev->pending_lock); 947static inline struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev,
944 spin_unlock_irqrestore(&qp->s_lock, flags); 948 struct qib_qp *qp)
949{
950 struct qib_verbs_txreq *tx;
951 unsigned long flags;
945 952
953 spin_lock_irqsave(&dev->pending_lock, flags);
954 /* assume the list non empty */
955 if (likely(!list_empty(&dev->txreq_free))) {
956 struct list_head *l = dev->txreq_free.next;
957
958 list_del(l);
959 spin_unlock_irqrestore(&dev->pending_lock, flags);
960 tx = list_entry(l, struct qib_verbs_txreq, txreq.list);
961 } else {
962 /* call slow path to get the extra lock */
963 spin_unlock_irqrestore(&dev->pending_lock, flags);
964 tx = __get_txreq(dev, qp);
965 }
946 return tx; 966 return tx;
947} 967}
948 968
@@ -1122,9 +1142,9 @@ static int qib_verbs_send_dma(struct qib_qp *qp, struct qib_ib_header *hdr,
1122 goto bail; 1142 goto bail;
1123 } 1143 }
1124 1144
1125 tx = get_txreq(dev, qp, &ret); 1145 tx = get_txreq(dev, qp);
1126 if (!tx) 1146 if (IS_ERR(tx))
1127 goto bail; 1147 goto bail_tx;
1128 1148
1129 control = dd->f_setpbc_control(ppd, plen, qp->s_srate, 1149 control = dd->f_setpbc_control(ppd, plen, qp->s_srate,
1130 be16_to_cpu(hdr->lrh[0]) >> 12); 1150 be16_to_cpu(hdr->lrh[0]) >> 12);
@@ -1195,6 +1215,9 @@ unaligned:
1195 ibp->n_unaligned++; 1215 ibp->n_unaligned++;
1196bail: 1216bail:
1197 return ret; 1217 return ret;
1218bail_tx:
1219 ret = PTR_ERR(tx);
1220 goto bail;
1198} 1221}
1199 1222
1200/* 1223/*