aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/qib/qib_uc.c
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2010-08-02 18:39:30 -0400
committerRoland Dreier <rolandd@cisco.com>2010-08-03 16:59:47 -0400
commita5210c12b7c4e34e904f4820a4abd048a2d75db5 (patch)
tree9ab443a2bbddf4296bf4b7cf0914edfed51d86c3 /drivers/infiniband/hw/qib/qib_uc.c
parent3e3aed0b88f680fed5c604caf7b10d77b2ec45c4 (diff)
IB/qib: Fix race between qib_error_qp() and receive packet processing
When transitioning a QP to the error state, in progress RWQEs need to be marked complete. This also involves releasing the reference count to the memory regions referenced in the SGEs. The locking in the receive packet processing wasn't sufficient to prevent qib_error_qp() from modifying the r_sge state at the same time, thus leading to kernel panics. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/qib/qib_uc.c')
-rw-r--r--drivers/infiniband/hw/qib/qib_uc.c6
1 files changed, 0 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c
index 6c7fe78cca64..b9c8b6346c1b 100644
--- a/drivers/infiniband/hw/qib/qib_uc.c
+++ b/drivers/infiniband/hw/qib/qib_uc.c
@@ -272,9 +272,6 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,
272 opcode >>= 24; 272 opcode >>= 24;
273 memset(&wc, 0, sizeof wc); 273 memset(&wc, 0, sizeof wc);
274 274
275 /* Prevent simultaneous processing after APM on different CPUs */
276 spin_lock(&qp->r_lock);
277
278 /* Compare the PSN verses the expected PSN. */ 275 /* Compare the PSN verses the expected PSN. */
279 if (unlikely(qib_cmp24(psn, qp->r_psn) != 0)) { 276 if (unlikely(qib_cmp24(psn, qp->r_psn) != 0)) {
280 /* 277 /*
@@ -534,7 +531,6 @@ rdma_last:
534 } 531 }
535 qp->r_psn++; 532 qp->r_psn++;
536 qp->r_state = opcode; 533 qp->r_state = opcode;
537 spin_unlock(&qp->r_lock);
538 return; 534 return;
539 535
540rewind: 536rewind:
@@ -542,12 +538,10 @@ rewind:
542 qp->r_sge.num_sge = 0; 538 qp->r_sge.num_sge = 0;
543drop: 539drop:
544 ibp->n_pkt_drops++; 540 ibp->n_pkt_drops++;
545 spin_unlock(&qp->r_lock);
546 return; 541 return;
547 542
548op_err: 543op_err:
549 qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR); 544 qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
550 spin_unlock(&qp->r_lock);
551 return; 545 return;
552 546
553sunlock: 547sunlock: