Commit fffbfeaa authored by Ralph Campbell's avatar Ralph Campbell Committed by Roland Dreier

IB/ipath: Fix a race where s_last is updated without lock held

There is a small window where a send work queue entry could be
overwritten by ib_post_send() because s_last is updated before the
entry is read.

This patch closes the window by acquiring the lock and updating
the last send work queue entry index after reading the wr_id.
Signed-off-by: default avatarRalph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 96db0e03
...@@ -630,11 +630,8 @@ bail:; ...@@ -630,11 +630,8 @@ bail:;
void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe,
enum ib_wc_status status) enum ib_wc_status status)
{ {
u32 last = qp->s_last; unsigned long flags;
u32 last;
if (++last == qp->s_size)
last = 0;
qp->s_last = last;
/* See ch. 11.2.4.1 and 10.7.3.1 */ /* See ch. 11.2.4.1 and 10.7.3.1 */
if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) || if (!(qp->s_flags & IPATH_S_SIGNAL_REQ_WR) ||
...@@ -658,4 +655,11 @@ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe, ...@@ -658,4 +655,11 @@ void ipath_send_complete(struct ipath_qp *qp, struct ipath_swqe *wqe,
wc.port_num = 0; wc.port_num = 0;
ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0); ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 0);
} }
spin_lock_irqsave(&qp->s_lock, flags);
last = qp->s_last;
if (++last >= qp->s_size)
last = 0;
qp->s_last = last;
spin_unlock_irqrestore(&qp->s_lock, flags);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment