diff mbox series

[21/31] rdma/siw: let siw_listen_address() call siw_cep_alloc() first

Message ID 66ef71c4c9cd6767746e0d48c75423487e59834a.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
This simplifies the cleanup path and makes the following
changes easier to review.

Check with "git show -w".

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 | 39 +++++++++++++++---------------
 1 file changed, 19 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index 9a550f040678..fe6f7bb4d615 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1916,9 +1916,16 @@  int siw_create_listen(struct iw_cm_id *id, int backlog)
 	if (addr_family != AF_INET && addr_family != AF_INET6)
 		return -EAFNOSUPPORT;
 
+	cep = siw_cep_alloc(sdev);
+	if (!cep)
+		return -ENOMEM;
+
 	rv = sock_create(addr_family, SOCK_STREAM, IPPROTO_TCP, &s);
-	if (rv < 0)
-		return rv;
+	if (rv < 0) {
+		siw_dbg(id->device, "sock_create error: %d\n", rv);
+		goto error;
+	}
+	siw_cep_socket_assoc(cep, s);
 
 	/*
 	 * Allow binding local port when still in TIME_WAIT from last close.
@@ -1957,12 +1964,6 @@  int siw_create_listen(struct iw_cm_id *id, int backlog)
 		siw_dbg(id->device, "socket bind error: %d\n", rv);
 		goto error;
 	}
-	cep = siw_cep_alloc(sdev);
-	if (!cep) {
-		rv = -ENOMEM;
-		goto error;
-	}
-	siw_cep_socket_assoc(cep, s);
 
 	rv = siw_cm_alloc_work(cep, backlog);
 	if (rv) {
@@ -2018,20 +2019,18 @@  int siw_create_listen(struct iw_cm_id *id, int backlog)
 error:
 	siw_dbg(id->device, "failed: %d\n", rv);
 
-	if (cep) {
-		siw_cep_set_inuse(cep);
-
-		if (cep->cm_id) {
-			cep->cm_id->rem_ref(cep->cm_id);
-			cep->cm_id = NULL;
-		}
-		cep->sock = NULL;
-		siw_socket_disassoc(s);
-		cep->state = SIW_EPSTATE_CLOSED;
+	siw_cep_set_inuse(cep);
 
-		siw_cep_set_free(cep);
-		siw_cep_put(cep);
+	if (cep->cm_id) {
+		cep->cm_id->rem_ref(cep->cm_id);
+		cep->cm_id = NULL;
 	}
+	cep->sock = NULL;
+	siw_socket_disassoc(s);
+	cep->state = SIW_EPSTATE_CLOSED;
+
+	siw_cep_set_free(cep);
+	siw_cep_put(cep);
 	sock_release(s);
 
 	return rv;