mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
IB/qib: Remove s_lock around header validation
Review of qib_ruc_check_hdr() shows that the s_lock is not required in the normal case. The r_lock is held in all cases, and protects the qp fields that are read. The s_lock will be needed to around the call to qib_migrate_qp() to insure that the send engine sees a consistent set of fields. Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
d0f2faf72d
commit
9fd5473deb
4 changed files with 8 additions and 15 deletions
|
@ -310,7 +310,6 @@ static u32 qib_rcv_hdrerr(struct qib_ctxtdata *rcd, struct qib_pportdata *ppd,
|
|||
u32 opcode;
|
||||
u32 psn;
|
||||
int diff;
|
||||
unsigned long flags;
|
||||
|
||||
/* Sanity check packet */
|
||||
if (tlen < 24)
|
||||
|
@ -365,7 +364,6 @@ static u32 qib_rcv_hdrerr(struct qib_ctxtdata *rcd, struct qib_pportdata *ppd,
|
|||
|
||||
switch (qp->ibqp.qp_type) {
|
||||
case IB_QPT_RC:
|
||||
spin_lock_irqsave(&qp->s_lock, flags);
|
||||
ruc_res =
|
||||
qib_ruc_check_hdr(
|
||||
ibp, hdr,
|
||||
|
@ -373,11 +371,8 @@ static u32 qib_rcv_hdrerr(struct qib_ctxtdata *rcd, struct qib_pportdata *ppd,
|
|||
qp,
|
||||
be32_to_cpu(ohdr->bth[0]));
|
||||
if (ruc_res) {
|
||||
spin_unlock_irqrestore(&qp->s_lock,
|
||||
flags);
|
||||
goto unlock;
|
||||
}
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
|
||||
/* Only deal with RDMA Writes for now */
|
||||
if (opcode <
|
||||
|
|
|
@ -1889,10 +1889,8 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct qib_ib_header *hdr,
|
|||
}
|
||||
|
||||
opcode = be32_to_cpu(ohdr->bth[0]);
|
||||
spin_lock_irqsave(&qp->s_lock, flags);
|
||||
if (qib_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode))
|
||||
goto sunlock;
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
return;
|
||||
|
||||
psn = be32_to_cpu(ohdr->bth[2]);
|
||||
opcode >>= 24;
|
||||
|
|
|
@ -260,12 +260,15 @@ static int gid_ok(union ib_gid *gid, __be64 gid_prefix, __be64 id)
|
|||
|
||||
/*
|
||||
*
|
||||
* This should be called with the QP s_lock held.
|
||||
* This should be called with the QP r_lock held.
|
||||
*
|
||||
* The s_lock will be acquired around the qib_migrate_qp() call.
|
||||
*/
|
||||
int qib_ruc_check_hdr(struct qib_ibport *ibp, struct qib_ib_header *hdr,
|
||||
int has_grh, struct qib_qp *qp, u32 bth0)
|
||||
{
|
||||
__be64 guid;
|
||||
unsigned long flags;
|
||||
|
||||
if (qp->s_mig_state == IB_MIG_ARMED && (bth0 & IB_BTH_MIG_REQ)) {
|
||||
if (!has_grh) {
|
||||
|
@ -295,7 +298,9 @@ int qib_ruc_check_hdr(struct qib_ibport *ibp, struct qib_ib_header *hdr,
|
|||
if (be16_to_cpu(hdr->lrh[3]) != qp->alt_ah_attr.dlid ||
|
||||
ppd_from_ibp(ibp)->port != qp->alt_ah_attr.port_num)
|
||||
goto err;
|
||||
spin_lock_irqsave(&qp->s_lock, flags);
|
||||
qib_migrate_qp(qp);
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
} else {
|
||||
if (!has_grh) {
|
||||
if (qp->remote_ah_attr.ah_flags & IB_AH_GRH)
|
||||
|
|
|
@ -243,7 +243,6 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,
|
|||
int has_grh, void *data, u32 tlen, struct qib_qp *qp)
|
||||
{
|
||||
struct qib_other_headers *ohdr;
|
||||
unsigned long flags;
|
||||
u32 opcode;
|
||||
u32 hdrsize;
|
||||
u32 psn;
|
||||
|
@ -263,10 +262,8 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,
|
|||
}
|
||||
|
||||
opcode = be32_to_cpu(ohdr->bth[0]);
|
||||
spin_lock_irqsave(&qp->s_lock, flags);
|
||||
if (qib_ruc_check_hdr(ibp, hdr, has_grh, qp, opcode))
|
||||
goto sunlock;
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
return;
|
||||
|
||||
psn = be32_to_cpu(ohdr->bth[2]);
|
||||
opcode >>= 24;
|
||||
|
@ -554,6 +551,4 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct qib_ib_header *hdr,
|
|||
qib_rc_error(qp, IB_WC_LOC_QP_OP_ERR);
|
||||
return;
|
||||
|
||||
sunlock:
|
||||
spin_unlock_irqrestore(&qp->s_lock, flags);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue