diff mbox

[7/9] ibacm: Reset endpoint state on error

Message ID 1395605901-9080-8-git-send-email-sean.hefty@intel.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Hefty, Sean March 23, 2014, 8:18 p.m. UTC
From: Sean Hefty <sean.hefty@intel.com>

An endpoint will be set to the ACM_READY state after
joining its multicast group.  If we later receive a
reregister event or port down followed by port up and
try to join the group again but fail, we will leave the
endpoint state as READY, rather than reset it back to INIT.

To fix, always set the mc_dest state to ACM_INIT on
any failure.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
---
 src/acm.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/src/acm.c b/src/acm.c
index a8a1fb9..eba027d 100644
--- a/src/acm.c
+++ b/src/acm.c
@@ -750,21 +750,21 @@  static void acm_process_join_resp(struct acm_ep *ep, struct ib_user_mad *umad)
 	mad = (struct ib_sa_mad *) umad->data;
 	acm_log(1, "response status: 0x%x, mad status: 0x%x\n",
 		umad->status, mad->status);
+	lock_acquire(&ep->lock);
 	if (umad->status) {
 		acm_log(0, "ERROR - send join failed 0x%x\n", umad->status);
-		return;
+		goto err1;
 	}
 	if (mad->status) {
 		acm_log(0, "ERROR - join response status 0x%x\n", mad->status);
-		return;
+		goto err1;
 	}
 
 	mc_rec = (struct ib_mc_member_rec *) mad->data;
-	lock_acquire(&ep->lock);
 	index = acm_mc_index(ep, &mc_rec->mgid);
 	if (index < 0) {
 		acm_log(0, "ERROR - MGID in join response not found\n");
-		goto out;
+		goto err1;
 	}
 
 	dest = &ep->mc_dest[index];
@@ -776,19 +776,25 @@  static void acm_process_join_resp(struct acm_ep *ep, struct ib_user_mad *umad)
 		dest->ah = ibv_create_ah(ep->port->dev->pd, &dest->av);
 		if (!dest->ah) {
 			acm_log(0, "ERROR - unable to create ah\n");
-			goto out;
+			goto err1;
 		}
 		ret = ibv_attach_mcast(ep->qp, &mc_rec->mgid, mc_rec->mlid);
 		if (ret) {
 			acm_log(0, "ERROR - unable to attach QP to multicast group\n");
-			goto out;
+			goto err2;
 		}
 	}
 
 	atomic_set(&dest->refcnt, 1);
 	dest->state = ACM_READY;
 	acm_log(1, "join successful\n");
-out:
+	lock_release(&ep->lock);
+	return;
+err2:
+	ibv_destroy_ah(dest->ah);
+	dest->ah = NULL;
+err1:
+	dest->state = ACM_INIT;
 	lock_release(&ep->lock);
 }