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

sean.hefty-ral2JQCrhuEAvxtiuMwx3w
2014-03-23T20:18:19Z

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-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
src/acm.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)

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);