Skip to content
Snippets Groups Projects
Commit 26012f07 authored by Animesh K Trivedi's avatar Animesh K Trivedi Committed by Roland Dreier
Browse files

RDMA/iwcm: Fix hang in uninterruptible wait on cm_id destroy


A process can get stuck in an uninterruptible wait in the
kernel while destroying a cm_id when iw_cm_connect() fails:

For example, When creation of a PD fails but the user continues with
an attempt to connect to the server without checking the return value,
in iw_cm_connect() a NULL qp is found so the call fails.  However the
IWCM_F_CONNECT_WAIT bit is not cleared.  destroy_cm_id() then waits
forever for IWCM_F_CONNECT_WAIT to be cleared.

The same problem exists on the passive side with the accept call.

Fix this by clearing the bit and waking up any waiters in the
appropriate spots.

Signed-off-by: default avatarAnimesh Trivedi <atr@zurich.ibm.com>
Acked-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 557d0540
No related branches found
No related tags found
No related merge requests found
...@@ -506,6 +506,8 @@ int iw_cm_accept(struct iw_cm_id *cm_id, ...@@ -506,6 +506,8 @@ int iw_cm_accept(struct iw_cm_id *cm_id,
qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn); qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
if (!qp) { if (!qp) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags); spin_unlock_irqrestore(&cm_id_priv->lock, flags);
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
wake_up_all(&cm_id_priv->connect_wait);
return -EINVAL; return -EINVAL;
} }
cm_id->device->iwcm->add_ref(qp); cm_id->device->iwcm->add_ref(qp);
...@@ -565,6 +567,8 @@ int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) ...@@ -565,6 +567,8 @@ int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param)
qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn); qp = cm_id->device->iwcm->get_qp(cm_id->device, iw_param->qpn);
if (!qp) { if (!qp) {
spin_unlock_irqrestore(&cm_id_priv->lock, flags); spin_unlock_irqrestore(&cm_id_priv->lock, flags);
clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
wake_up_all(&cm_id_priv->connect_wait);
return -EINVAL; return -EINVAL;
} }
cm_id->device->iwcm->add_ref(qp); cm_id->device->iwcm->add_ref(qp);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment