Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 747f4d7a authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Doug Ledford
Browse files

IB/qib, IB/hfi1: Fix up UD loopback use of irq flags



The dual lock patch moved locking around and missed an issue
with handling irq flags when processing UD loopback
packets.  This issue was revealed by smatch.

Fix for both qib and hfi1 to pass the saved flags to the UD request
builder and handle the changes correctly.

Fixes: 46a80d62 ("IB/qib, staging/rdma/hfi1: add s_hlock for use in post send")
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f39cc34d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ static int qib_make_rc_ack(struct qib_ibdev *dev, struct rvt_qp *qp,
 *
 * Return 1 if constructed; otherwise, return 0.
 */
int qib_make_rc_req(struct rvt_qp *qp)
int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags)
{
	struct qib_qp_priv *priv = qp->priv;
	struct qib_ibdev *dev = to_idev(qp->ibqp.device);
+2 −2
Original line number Diff line number Diff line
@@ -739,7 +739,7 @@ void qib_do_send(struct rvt_qp *qp)
	struct qib_qp_priv *priv = qp->priv;
	struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
	struct qib_pportdata *ppd = ppd_from_ibp(ibp);
	int (*make_req)(struct rvt_qp *qp);
	int (*make_req)(struct rvt_qp *qp, unsigned long *flags);
	unsigned long flags;

	if ((qp->ibqp.qp_type == IB_QPT_RC ||
@@ -781,7 +781,7 @@ void qib_do_send(struct rvt_qp *qp)
			qp->s_hdrwords = 0;
			spin_lock_irqsave(&qp->s_lock, flags);
		}
	} while (make_req(qp));
	} while (make_req(qp, &flags));

	spin_unlock_irqrestore(&qp->s_lock, flags);
}
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@
 *
 * Return 1 if constructed; otherwise, return 0.
 */
int qib_make_uc_req(struct rvt_qp *qp)
int qib_make_uc_req(struct rvt_qp *qp, unsigned long *flags)
{
	struct qib_qp_priv *priv = qp->priv;
	struct qib_other_headers *ohdr;
+5 −5
Original line number Diff line number Diff line
@@ -238,7 +238,7 @@ static void qib_ud_loopback(struct rvt_qp *sqp, struct rvt_swqe *swqe)
 *
 * Return 1 if constructed; otherwise, return 0.
 */
int qib_make_ud_req(struct rvt_qp *qp)
int qib_make_ud_req(struct rvt_qp *qp, unsigned long *flags)
{
	struct qib_qp_priv *priv = qp->priv;
	struct qib_other_headers *ohdr;
@@ -294,7 +294,7 @@ int qib_make_ud_req(struct rvt_qp *qp)
		this_cpu_inc(ibp->pmastats->n_unicast_xmit);
		lid = ah_attr->dlid & ~((1 << ppd->lmc) - 1);
		if (unlikely(lid == ppd->lid)) {
			unsigned long flags;
			unsigned long tflags = *flags;
			/*
			 * If DMAs are in progress, we can't generate
			 * a completion for the loopback packet since
@@ -307,10 +307,10 @@ int qib_make_ud_req(struct rvt_qp *qp)
				goto bail;
			}
			qp->s_cur = next_cur;
			local_irq_save(flags);
			spin_unlock_irqrestore(&qp->s_lock, flags);
			spin_unlock_irqrestore(&qp->s_lock, tflags);
			qib_ud_loopback(qp, wqe);
			spin_lock_irqsave(&qp->s_lock, flags);
			spin_lock_irqsave(&qp->s_lock, tflags);
			*flags = tflags;
			qib_send_complete(qp, wqe, IB_WC_SUCCESS);
			goto done;
		}
+3 −3
Original line number Diff line number Diff line
@@ -430,11 +430,11 @@ void qib_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,

void qib_send_rc_ack(struct rvt_qp *qp);

int qib_make_rc_req(struct rvt_qp *qp);
int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags);

int qib_make_uc_req(struct rvt_qp *qp);
int qib_make_uc_req(struct rvt_qp *qp, unsigned long *flags);

int qib_make_ud_req(struct rvt_qp *qp);
int qib_make_ud_req(struct rvt_qp *qp, unsigned long *flags);

int qib_register_ib_device(struct qib_devdata *);

Loading