summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_rc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-11 16:30:08 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-11 16:30:08 -0800
commitf1d6d6cd9029daa7e7d4a0b14347b5392320f22a (patch)
tree673e1940d385cfc625ed7583b54117ca97216734 /drivers/infiniband/hw/qib/qib_rc.c
parentb9d919a4ac6cf031b8e065f82ad8f1b0c9ed74b1 (diff)
parent2b76c05794e66655e10633d2d78287854c991f63 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (42 commits) IB/qib: Fix refcount leak in lkey/rkey validation IB/qib: Improve SERDES tunning on QMH boards IB/qib: Unnecessary delayed completions on RC connection IB/qib: Issue pre-emptive NAKs on eager buffer overflow IB/qib: RDMA lkey/rkey validation is inefficient for large MRs IB/qib: Change QPN increment IB/qib: Add fix missing from earlier patch IB/qib: Change receive queue/QPN selection IB/qib: Fix interrupt mitigation IB/qib: Avoid duplicate writes to the rcv head register IB/qib: Add a few new SERDES tunings IB/qib: Reset packet list after freeing IB/qib: New SERDES init routine and improvements to SI quality IB/qib: Clear WAIT_SEND flags when setting QP to error state IB/qib: Fix context allocation with multiple HCAs IB/qib: Fix multi-Florida HCA host panic on reboot IB/qib: Handle transitions from ACTIVE_DEFERRED to ACTIVE better IB/qib: UD send with immediate receive completion has wrong size IB/qib: Set port physical state even if other fields are invalid IB/qib: Generate completion callback on errors ...
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_rc.c')
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index 955fb715779..8245237b67c 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -1407,6 +1407,7 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp,
struct qib_ctxtdata *rcd)
{
struct qib_swqe *wqe;
+ struct qib_pportdata *ppd = ppd_from_ibp(ibp);
enum ib_wc_status status;
unsigned long flags;
int diff;
@@ -1414,6 +1415,29 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp,
u32 aeth;
u64 val;
+ if (opcode != OP(RDMA_READ_RESPONSE_MIDDLE)) {
+ /*
+ * If ACK'd PSN on SDMA busy list try to make progress to
+ * reclaim SDMA credits.
+ */
+ if ((qib_cmp24(psn, qp->s_sending_psn) >= 0) &&
+ (qib_cmp24(qp->s_sending_psn, qp->s_sending_hpsn) <= 0)) {
+
+ /*
+ * If send tasklet not running attempt to progress
+ * SDMA queue.
+ */
+ if (!(qp->s_flags & QIB_S_BUSY)) {
+ /* Acquire SDMA Lock */
+ spin_lock_irqsave(&ppd->sdma_lock, flags);
+ /* Invoke sdma make progress */
+ qib_sdma_make_progress(ppd);
+ /* Release SDMA Lock */
+ spin_unlock_irqrestore(&ppd->sdma_lock, flags);
+ }
+ }
+ }
+
spin_lock_irqsave(&qp->s_lock, flags);
/* Ignore invalid responses. */