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
--- a/drivers/infiniband/core/cm.c
+++ 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;
case IB_CM_MRA_REQ_SENT:
case IB_CM_REP_RCVD:
case IB_CM_MRA_REP_SENT:
--
K. Poon
ka-cheong.poon@xxxxxxxxxx