diff options
author | Ralph Campbell <ralph.campbell@qlogic.com> | 2010-08-03 00:39:30 +0200 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2010-08-03 22:59:47 +0200 |
commit | a5210c12b7c4e34e904f4820a4abd048a2d75db5 (patch) | |
tree | 9ab443a2bbddf4296bf4b7cf0914edfed51d86c3 /drivers/infiniband/hw/qib/qib_verbs.c | |
parent | IB/qib: Limit the number of packets processed per interrupt (diff) | |
download | linux-a5210c12b7c4e34e904f4820a4abd048a2d75db5.tar.xz linux-a5210c12b7c4e34e904f4820a4abd048a2d75db5.zip |
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_verbs.c')
-rw-r--r-- | drivers/infiniband/hw/qib/qib_verbs.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c index cda8f4173d23..9fab40488850 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.c +++ b/drivers/infiniband/hw/qib/qib_verbs.c @@ -550,10 +550,12 @@ static void qib_qp_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr, { struct qib_ibport *ibp = &rcd->ppd->ibport_data; + spin_lock(&qp->r_lock); + /* Check for valid receive state. */ if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) { ibp->n_pkt_drops++; - return; + goto unlock; } switch (qp->ibqp.qp_type) { @@ -577,6 +579,9 @@ static void qib_qp_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr, default: break; } + +unlock: + spin_unlock(&qp->r_lock); } /** |