goto out;
        }
 
+       if (cm_id->lap_state == IB_CM_LAP_SENT ||
+           cm_id->lap_state == IB_CM_MRA_LAP_RCVD)
+               ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+
        ret = cm_alloc_msg(cm_id_priv, &msg);
        if (ret) {
                cm_enter_timewait(cm_id_priv);
                ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
                break;
        case IB_CM_ESTABLISHED:
+               if (cm_id_priv->id.lap_state == IB_CM_LAP_SENT ||
+                   cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD)
+                       ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
+               break;
        case IB_CM_MRA_REP_RCVD:
                break;
        case IB_CM_TIMEWAIT:
                /* fall through */
        case IB_CM_REP_RCVD:
        case IB_CM_MRA_REP_SENT:
-       case IB_CM_ESTABLISHED:
                cm_enter_timewait(cm_id_priv);
                break;
+       case IB_CM_ESTABLISHED:
+               if (cm_id_priv->id.lap_state == IB_CM_LAP_UNINIT ||
+                   cm_id_priv->id.lap_state == IB_CM_LAP_SENT) {
+                       if (cm_id_priv->id.lap_state == IB_CM_LAP_SENT)
+                               ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+                                             cm_id_priv->msg);
+                       cm_enter_timewait(cm_id_priv);
+                       break;
+               }
+               /* fall through */
        default:
                spin_unlock_irq(&cm_id_priv->lock);
                ret = -EINVAL;