diff mbox series

[04/31] rdma/siw: let siw_accept() deferr RDMA_MODE until EVENT_ESTABLISHED

Message ID 4d26a4cfd96bfcb3fe0362a37d595608b09ddd91.1620343860.git.metze@samba.org (mailing list archive)
State Changes Requested
Headers show
Series rdma/siw: fix a lot of deadlocks and use after free bugs | expand

Commit Message

Stefan Metzmacher May 6, 2021, 11:36 p.m. UTC
If we receive an TCP FIN before sending the MPA response
we'll get an error and posted IW_CM_EVENT_CLOSE.
But the IWCM layer didn't receive IW_CM_EVENT_ESTABLISHED
yet and doesn't expect IW_CM_EVENT_CLOSE. Instead
it expects IW_CM_EVENT_CONNECT_REPLY.

If we stay in SIW_EPSTATE_RECVD_MPAREQ until we posted
IW_CM_EVENT_ESTABLISHED __siw_cep_terminate_upcall()
will use IW_CM_EVENT_CONNECT_REPLY.

This can be triggered by the following change on the
client:

   --- a/drivers/infiniband/sw/siw/siw_cm.c
   +++ b/drivers/infiniband/sw/siw/siw_cm.c
   @@ -1507,6 +1507,9 @@ int siw_connect(struct iw_cm_id *id, struct iw_cm_conn_param *params)
           if (rv >= 0) {
                   rv = siw_cm_queue_work(cep, SIW_CM_WORK_MPATIMEOUT);
                   if (!rv) {
   +                       rv = -ECONNRESET;
   +                       msleep_interruptible(100);
   +                       goto error;
                           siw_dbg_cep(cep, "[QP %u]: exit\n", qp_id(qp));
                           siw_cep_set_free(cep);
                           return 0;

Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Cc: Bernard Metzler <bmt@zurich.ibm.com>
Cc: linux-rdma@vger.kernel.org
---
 drivers/infiniband/sw/siw/siw_cm.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Comments

Bernard Metzler May 11, 2021, 11:38 a.m. UTC | #1
-----"Stefan Metzmacher" <metze@samba.org> wrote: -----

>To: "Bernard Metzler" <bmt@zurich.ibm.com>
>From: "Stefan Metzmacher" <metze@samba.org>
>Date: 05/07/2021 01:37AM
>Cc: linux-rdma@vger.kernel.org, "Stefan Metzmacher" <metze@samba.org>
>Subject: [EXTERNAL] [PATCH 04/31] rdma/siw: let siw_accept() deferr
>RDMA_MODE until EVENT_ESTABLISHED
>
>If we receive an TCP FIN before sending the MPA response
>we'll get an error and posted IW_CM_EVENT_CLOSE.
>But the IWCM layer didn't receive IW_CM_EVENT_ESTABLISHED
>yet and doesn't expect IW_CM_EVENT_CLOSE. Instead
>it expects IW_CM_EVENT_CONNECT_REPLY.
>
>If we stay in SIW_EPSTATE_RECVD_MPAREQ until we posted
>IW_CM_EVENT_ESTABLISHED __siw_cep_terminate_upcall()
>will use IW_CM_EVENT_CONNECT_REPLY.
>
>This can be triggered by the following change on the
>client:
>
>   --- a/drivers/infiniband/sw/siw/siw_cm.c
>   +++ b/drivers/infiniband/sw/siw/siw_cm.c
>   @@ -1507,6 +1507,9 @@ int siw_connect(struct iw_cm_id *id, struct
>iw_cm_conn_param *params)
>           if (rv >= 0) {
>                   rv = siw_cm_queue_work(cep,
>SIW_CM_WORK_MPATIMEOUT);
>                   if (!rv) {
>   +                       rv = -ECONNRESET;
>   +                       msleep_interruptible(100);
>   +                       goto error;
>                           siw_dbg_cep(cep, "[QP %u]: exit\n",
>qp_id(qp));
>                           siw_cep_set_free(cep);
>                           return 0;
>
>Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
>Signed-off-by: Stefan Metzmacher <metze@samba.org>
>Cc: Bernard Metzler <bmt@zurich.ibm.com>
>Cc: linux-rdma@vger.kernel.org
>---
> drivers/infiniband/sw/siw/siw_cm.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/infiniband/sw/siw/siw_cm.c
>b/drivers/infiniband/sw/siw/siw_cm.c
>index da84686a21fd..145ab6e4e0ed 100644
>--- a/drivers/infiniband/sw/siw/siw_cm.c
>+++ b/drivers/infiniband/sw/siw/siw_cm.c
>@@ -129,8 +129,10 @@ static void siw_rtr_data_ready(struct sock *sk)
> 	 * Failed data processing would have already scheduled
> 	 * connection drop.
> 	 */
>-	if (!qp->rx_stream.rx_suspend)
>+	if (!qp->rx_stream.rx_suspend) {
> 		siw_cm_upcall(cep, IW_CM_EVENT_ESTABLISHED, 0);
>+		cep->state = SIW_EPSTATE_RDMA_MODE;
>+	}
> out:
> 	read_unlock(&sk->sk_callback_lock);
> 	if (qp)
>@@ -1656,8 +1658,6 @@ int siw_accept(struct iw_cm_id *id, struct
>iw_cm_conn_param *params)
> 	/* siw_qp_get(qp) already done by QP lookup */
> 	cep->qp = qp;
> 
>-	cep->state = SIW_EPSTATE_RDMA_MODE;
>-
> 	/* Move socket RX/TX under QP control */
> 	rv = siw_qp_modify(qp, &qp_attrs,
> 			   SIW_QP_ATTR_STATE | SIW_QP_ATTR_LLP_HANDLE |
>@@ -1683,6 +1683,7 @@ int siw_accept(struct iw_cm_id *id, struct
>iw_cm_conn_param *params)
> 		rv = siw_cm_upcall(cep, IW_CM_EVENT_ESTABLISHED, 0);
> 		if (rv)
> 			goto error;
>+		cep->state = SIW_EPSTATE_RDMA_MODE;
> 	}
> 	siw_cep_set_free(cep);
> 
>-- 
>2.25.1
>
>
Thanks!

Reviewed-by: Bernard Metzler <bmt@zurich.ibm.com>
diff mbox series

Patch

diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index da84686a21fd..145ab6e4e0ed 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -129,8 +129,10 @@  static void siw_rtr_data_ready(struct sock *sk)
 	 * Failed data processing would have already scheduled
 	 * connection drop.
 	 */
-	if (!qp->rx_stream.rx_suspend)
+	if (!qp->rx_stream.rx_suspend) {
 		siw_cm_upcall(cep, IW_CM_EVENT_ESTABLISHED, 0);
+		cep->state = SIW_EPSTATE_RDMA_MODE;
+	}
 out:
 	read_unlock(&sk->sk_callback_lock);
 	if (qp)
@@ -1656,8 +1658,6 @@  int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
 	/* siw_qp_get(qp) already done by QP lookup */
 	cep->qp = qp;
 
-	cep->state = SIW_EPSTATE_RDMA_MODE;
-
 	/* Move socket RX/TX under QP control */
 	rv = siw_qp_modify(qp, &qp_attrs,
 			   SIW_QP_ATTR_STATE | SIW_QP_ATTR_LLP_HANDLE |
@@ -1683,6 +1683,7 @@  int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
 		rv = siw_cm_upcall(cep, IW_CM_EVENT_ESTABLISHED, 0);
 		if (rv)
 			goto error;
+		cep->state = SIW_EPSTATE_RDMA_MODE;
 	}
 	siw_cep_set_free(cep);