aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2007-10-26 11:02:39 -0400
committerRoland Dreier <rolandd@cisco.com>2007-11-13 18:26:58 -0500
commitf4ad1bcc4425a772ea584e1f24abadc64c2b839f (patch)
tree374f7462a229e0506aa54516cf1029a95dc9adb4 /drivers/infiniband
parenta6e7550d8f73d6b75c20afff321f0f06fe144775 (diff)
IB/ipath: Fix race with ACK retry timeout list management
When an ACK is received, the QP is removed from the timeout list and then if there are still pending send WQEs, the QP is put back on the timeout list. It is possible that another post send has put the QP on the timeout list thus, a check needs to be made before trying to do it again or the list is corrupted. Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 5c29b2bfea17..120a61b03bc4 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -959,8 +959,9 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode,
959 /* If this is a partial ACK, reset the retransmit timer. */ 959 /* If this is a partial ACK, reset the retransmit timer. */
960 if (qp->s_last != qp->s_tail) { 960 if (qp->s_last != qp->s_tail) {
961 spin_lock(&dev->pending_lock); 961 spin_lock(&dev->pending_lock);
962 list_add_tail(&qp->timerwait, 962 if (list_empty(&qp->timerwait))
963 &dev->pending[dev->pending_index]); 963 list_add_tail(&qp->timerwait,
964 &dev->pending[dev->pending_index]);
964 spin_unlock(&dev->pending_lock); 965 spin_unlock(&dev->pending_lock);
965 /* 966 /*
966 * If we get a partial ACK for a resent operation, 967 * If we get a partial ACK for a resent operation,