]> git.openfabrics.org - ~shefty/ibacm.git/commitdiff
ibacm: Reset endpoint state on error
authorSean Hefty <sean.hefty@intel.com>
Fri, 21 Mar 2014 06:23:06 +0000 (23:23 -0700)
committerSean Hefty <sean.hefty@intel.com>
Tue, 8 Apr 2014 22:51:00 +0000 (15:51 -0700)
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

index c2c889392082d0d39e9890bc466600433d2690a0..3e717909611f70537f97485cf758c2883d97c75c 100644 (file)
--- a/src/acm.c
+++ b/src/acm.c
@@ -756,21 +756,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];
@@ -782,19 +782,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);
 }