]> git.baikalelectronics.ru Git - kernel.git/commitdiff
RDMA/siw: Fix connection failure handling
authorBernard Metzler <bmt@zurich.ibm.com>
Tue, 5 Sep 2023 14:58:22 +0000 (16:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 20:00:45 +0000 (22:00 +0200)
commit 53a3f777049771496f791504e7dc8ef017cba590 upstream.

In case immediate MPA request processing fails, the newly
created endpoint unlinks the listening endpoint and is
ready to be dropped. This special case was not handled
correctly by the code handling the later TCP socket close,
causing a NULL dereference crash in siw_cm_work_handler()
when dereferencing a NULL listener. We now also cancel
the useless MPA timeout, if immediate MPA request
processing fails.

This patch furthermore simplifies MPA processing in general:
Scheduling a useless TCP socket read in sk_data_ready() upcall
is now surpressed, if the socket is already moved out of
TCP_ESTABLISHED state.

Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
Link: https://lore.kernel.org/r/20230905145822.446263-1-bmt@zurich.ibm.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/infiniband/sw/siw/siw_cm.c

index 552d8271e423b25d4bbd8809f55161d25c1b33ed..dc679c34ceefa678e9b6595e4cfe48f4e5c48866 100644 (file)
@@ -973,6 +973,7 @@ static void siw_accept_newconn(struct siw_cep *cep)
                        siw_cep_put(cep);
                        new_cep->listen_cep = NULL;
                        if (rv) {
+                               siw_cancel_mpatimer(new_cep);
                                siw_cep_set_free(new_cep);
                                goto error;
                        }
@@ -1097,9 +1098,12 @@ static void siw_cm_work_handler(struct work_struct *w)
                                /*
                                 * Socket close before MPA request received.
                                 */
-                               siw_dbg_cep(cep, "no mpareq: drop listener\n");
-                               siw_cep_put(cep->listen_cep);
-                               cep->listen_cep = NULL;
+                               if (cep->listen_cep) {
+                                       siw_dbg_cep(cep,
+                                               "no mpareq: drop listener\n");
+                                       siw_cep_put(cep->listen_cep);
+                                       cep->listen_cep = NULL;
+                               }
                        }
                }
                release_cep = 1;
@@ -1222,7 +1226,11 @@ static void siw_cm_llp_data_ready(struct sock *sk)
        if (!cep)
                goto out;
 
-       siw_dbg_cep(cep, "state: %d\n", cep->state);
+       siw_dbg_cep(cep, "cep state: %d, socket state %d\n",
+                   cep->state, sk->sk_state);
+
+       if (sk->sk_state != TCP_ESTABLISHED)
+               goto out;
 
        switch (cep->state) {
        case SIW_EPSTATE_RDMA_MODE: