On Wed, Jun 03, 2020 at 08:46:17PM +0800, Ka-Cheong Poon wrote: > On 6/3/20 7:55 PM, Jason Gunthorpe wrote: > > On Wed, Jun 03, 2020 at 04:53:57PM +0800, Ka-Cheong Poon wrote: > > > Suppose the cm_id state is IB_CM_REP_SENT when cm_destroy_id() is > > > called. Then it calls cm_send_rej_locked(). In cm_send_rej_locked(), > > > it calls cm_enter_timewait() and the state is changed to IB_CM_TIMEWAIT. > > > Now back to cm_destroy_id(), it breaks from the switch statement. And > > > the next call is WARN_ON(cm_id->state != IB_CM_IDLE). The cm_id state > > > is IB_CM_TIMEWAIT so it will log a warning. Is the warning intended in > > > this case? > > > > Yes the warning is intended, most likely the break should be changed > > to goto retest > > > Like this? > > diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c > index 17f14e0..1c2bf18 100644 > +++ b/drivers/infiniband/core/cm.c > @@ -1076,7 +1076,9 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err) > case IB_CM_REP_SENT: > case IB_CM_MRA_REP_RCVD: > ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); > - /* Fall through */ > + cm_send_rej_locked(cm_id_priv, IB_CM_REJ_CONSUMER_DEFINED, NULL, > + 0, NULL, 0); > + goto retest; Yes, that is good, can you make a formal patch? Jason