From c2b9ff9c57fef7aa5cad25794946d2f8d6a0d5eb Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Fri, 23 Dec 2011 08:03:41 -0500 Subject: [PATCH] --- yaml --- r: 280603 b: refs/heads/master c: 489471095170ed1c6d0341739a243461638b0e06 h: refs/heads/master i: 280601: eaae16df0afe5e4bf6e8a105bb60e6d20aec0e09 280599: 6445cff00277d240a55c06c2a6da1d7c94aff883 v: v3 --- [refs] | 2 +- trunk/drivers/infiniband/hw/qib/qib_verbs.c | 43 ++++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index c701bb769dcd..dff85b3dd3b7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eddfb675256f49d14e8c5763098afe3eb2c93701 +refs/heads/master: 489471095170ed1c6d0341739a243461638b0e06 diff --git a/trunk/drivers/infiniband/hw/qib/qib_verbs.c b/trunk/drivers/infiniband/hw/qib/qib_verbs.c index a894762da462..7b6c3bffa9d9 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_verbs.c +++ b/trunk/drivers/infiniband/hw/qib/qib_verbs.c @@ -913,8 +913,8 @@ static void copy_io(u32 __iomem *piobuf, struct qib_sge_state *ss, __raw_writel(last, piobuf); } -static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, - struct qib_qp *qp, int *retp) +static noinline struct qib_verbs_txreq *__get_txreq(struct qib_ibdev *dev, + struct qib_qp *qp) { struct qib_verbs_txreq *tx; unsigned long flags; @@ -926,8 +926,9 @@ static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, struct list_head *l = dev->txreq_free.next; list_del(l); + spin_unlock(&dev->pending_lock); + spin_unlock_irqrestore(&qp->s_lock, flags); tx = list_entry(l, struct qib_verbs_txreq, txreq.list); - *retp = 0; } else { if (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK && list_empty(&qp->iowait)) { @@ -935,14 +936,33 @@ static struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, qp->s_flags |= QIB_S_WAIT_TX; list_add_tail(&qp->iowait, &dev->txwait); } - tx = NULL; qp->s_flags &= ~QIB_S_BUSY; - *retp = -EBUSY; + spin_unlock(&dev->pending_lock); + spin_unlock_irqrestore(&qp->s_lock, flags); + tx = ERR_PTR(-EBUSY); } + return tx; +} - spin_unlock(&dev->pending_lock); - spin_unlock_irqrestore(&qp->s_lock, flags); +static inline struct qib_verbs_txreq *get_txreq(struct qib_ibdev *dev, + struct qib_qp *qp) +{ + struct qib_verbs_txreq *tx; + unsigned long flags; + spin_lock_irqsave(&dev->pending_lock, flags); + /* assume the list non empty */ + if (likely(!list_empty(&dev->txreq_free))) { + struct list_head *l = dev->txreq_free.next; + + list_del(l); + spin_unlock_irqrestore(&dev->pending_lock, flags); + tx = list_entry(l, struct qib_verbs_txreq, txreq.list); + } else { + /* call slow path to get the extra lock */ + spin_unlock_irqrestore(&dev->pending_lock, flags); + tx = __get_txreq(dev, qp); + } return tx; } @@ -1122,9 +1142,9 @@ static int qib_verbs_send_dma(struct qib_qp *qp, struct qib_ib_header *hdr, goto bail; } - tx = get_txreq(dev, qp, &ret); - if (!tx) - goto bail; + tx = get_txreq(dev, qp); + if (IS_ERR(tx)) + goto bail_tx; control = dd->f_setpbc_control(ppd, plen, qp->s_srate, be16_to_cpu(hdr->lrh[0]) >> 12); @@ -1195,6 +1215,9 @@ static int qib_verbs_send_dma(struct qib_qp *qp, struct qib_ib_header *hdr, ibp->n_unaligned++; bail: return ret; +bail_tx: + ret = PTR_ERR(tx); + goto bail; } /*