netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] net/smc: socket closing improvements
@ 2018-01-24  9:28 Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 1/6] net/smc: use local struct sock variables consistently Ursula Braun
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Dave,

while the first 2 patches are just small cleanups, the remaing
patches affect socket closing.

Thanks, Ursula

Ursula Braun (6):
  net/smc: use local struct sock variables consistently
  net/smc: simplify function smc_clcsock_accept()
  net/smc: get rid of tx_pend waits in socket closing
  net/smc: make wait for work request uninterruptible
  net/smc: improve state change handling after close wait
  net/smc: continue waiting if peer signals write_shutdown

 net/smc/af_smc.c    |  40 +++++++++-----------
 net/smc/smc_cdc.c   |  11 ------
 net/smc/smc_cdc.h   |   1 -
 net/smc/smc_close.c | 103 +++++++++++++++++++++++-----------------------------
 net/smc/smc_tx.c    |   4 +-
 net/smc/smc_wr.c    |  31 +++-------------
 net/smc/smc_wr.h    |   2 -
 7 files changed, 71 insertions(+), 121 deletions(-)

-- 
2.13.5

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next 1/6] net/smc: use local struct sock variables consistently
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 2/6] net/smc: simplify function smc_clcsock_accept() Ursula Braun
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Cleanup to consistently exploit the local struct sock definitions.
No functional change.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/af_smc.c    | 33 +++++++++++++++++----------------
 net/smc/smc_close.c | 38 ++++++++++++++++++++------------------
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index daf8075f5a4c..eccccf743b9f 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -581,39 +581,39 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr,
 
 static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
 {
-	struct sock *sk = &lsmc->sk;
-	struct socket *new_clcsock;
+	struct socket *new_clcsock = NULL;
+	struct sock *lsk = &lsmc->sk;
 	struct sock *new_sk;
 	int rc;
 
-	release_sock(&lsmc->sk);
-	new_sk = smc_sock_alloc(sock_net(sk), NULL);
+	release_sock(lsk);
+	new_sk = smc_sock_alloc(sock_net(lsk), NULL);
 	if (!new_sk) {
 		rc = -ENOMEM;
-		lsmc->sk.sk_err = ENOMEM;
+		lsk->sk_err = ENOMEM;
 		*new_smc = NULL;
-		lock_sock(&lsmc->sk);
+		lock_sock(lsk);
 		goto out;
 	}
 	*new_smc = smc_sk(new_sk);
 
 	rc = kernel_accept(lsmc->clcsock, &new_clcsock, 0);
-	lock_sock(&lsmc->sk);
+	lock_sock(lsk);
 	if  (rc < 0) {
-		lsmc->sk.sk_err = -rc;
+		lsk->sk_err = -rc;
 		new_sk->sk_state = SMC_CLOSED;
 		sock_set_flag(new_sk, SOCK_DEAD);
-		sk->sk_prot->unhash(new_sk);
+		new_sk->sk_prot->unhash(new_sk);
 		sock_put(new_sk);
 		*new_smc = NULL;
 		goto out;
 	}
-	if (lsmc->sk.sk_state == SMC_CLOSED) {
+	if (lsk->sk_state == SMC_CLOSED) {
 		if (new_clcsock)
 			sock_release(new_clcsock);
 		new_sk->sk_state = SMC_CLOSED;
 		sock_set_flag(new_sk, SOCK_DEAD);
-		sk->sk_prot->unhash(new_sk);
+		new_sk->sk_prot->unhash(new_sk);
 		sock_put(new_sk);
 		*new_smc = NULL;
 		goto out;
@@ -936,11 +936,12 @@ static void smc_tcp_listen_work(struct work_struct *work)
 {
 	struct smc_sock *lsmc = container_of(work, struct smc_sock,
 					     tcp_listen_work);
+	struct sock *lsk = &lsmc->sk;
 	struct smc_sock *new_smc;
 	int rc = 0;
 
-	lock_sock(&lsmc->sk);
-	while (lsmc->sk.sk_state == SMC_LISTEN) {
+	lock_sock(lsk);
+	while (lsk->sk_state == SMC_LISTEN) {
 		rc = smc_clcsock_accept(lsmc, &new_smc);
 		if (rc)
 			goto out;
@@ -949,15 +950,15 @@ static void smc_tcp_listen_work(struct work_struct *work)
 
 		new_smc->listen_smc = lsmc;
 		new_smc->use_fallback = false; /* assume rdma capability first*/
-		sock_hold(&lsmc->sk); /* sock_put in smc_listen_work */
+		sock_hold(lsk); /* sock_put in smc_listen_work */
 		INIT_WORK(&new_smc->smc_listen_work, smc_listen_work);
 		smc_copy_sock_settings_to_smc(new_smc);
 		schedule_work(&new_smc->smc_listen_work);
 	}
 
 out:
-	release_sock(&lsmc->sk);
-	lsmc->sk.sk_data_ready(&lsmc->sk); /* no more listening, wake accept */
+	release_sock(lsk);
+	lsk->sk_data_ready(lsk); /* no more listening, wake accept */
 }
 
 static int smc_listen(struct socket *sock, int backlog)
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index e194c6cc308a..11793912f001 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -115,36 +115,38 @@ static int smc_close_abort(struct smc_connection *conn)
  */
 static void smc_close_active_abort(struct smc_sock *smc)
 {
+	struct sock *sk = &smc->sk;
+
 	struct smc_cdc_conn_state_flags *txflags =
 		&smc->conn.local_tx_ctrl.conn_state_flags;
 
-	smc->sk.sk_err = ECONNABORTED;
+	sk->sk_err = ECONNABORTED;
 	if (smc->clcsock && smc->clcsock->sk) {
 		smc->clcsock->sk->sk_err = ECONNABORTED;
 		smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
 	}
-	switch (smc->sk.sk_state) {
+	switch (sk->sk_state) {
 	case SMC_INIT:
 	case SMC_ACTIVE:
-		smc->sk.sk_state = SMC_PEERABORTWAIT;
+		sk->sk_state = SMC_PEERABORTWAIT;
 		break;
 	case SMC_APPCLOSEWAIT1:
 	case SMC_APPCLOSEWAIT2:
 		txflags->peer_conn_abort = 1;
 		sock_release(smc->clcsock);
 		if (!smc_cdc_rxed_any_close(&smc->conn))
-			smc->sk.sk_state = SMC_PEERABORTWAIT;
+			sk->sk_state = SMC_PEERABORTWAIT;
 		else
-			smc->sk.sk_state = SMC_CLOSED;
+			sk->sk_state = SMC_CLOSED;
 		break;
 	case SMC_PEERCLOSEWAIT1:
 	case SMC_PEERCLOSEWAIT2:
 		if (!txflags->peer_conn_closed) {
-			smc->sk.sk_state = SMC_PEERABORTWAIT;
+			sk->sk_state = SMC_PEERABORTWAIT;
 			txflags->peer_conn_abort = 1;
 			sock_release(smc->clcsock);
 		} else {
-			smc->sk.sk_state = SMC_CLOSED;
+			sk->sk_state = SMC_CLOSED;
 		}
 		break;
 	case SMC_PROCESSABORT:
@@ -153,7 +155,7 @@ static void smc_close_active_abort(struct smc_sock *smc)
 			txflags->peer_conn_abort = 1;
 			sock_release(smc->clcsock);
 		}
-		smc->sk.sk_state = SMC_CLOSED;
+		sk->sk_state = SMC_CLOSED;
 		break;
 	case SMC_PEERFINCLOSEWAIT:
 	case SMC_PEERABORTWAIT:
@@ -161,8 +163,8 @@ static void smc_close_active_abort(struct smc_sock *smc)
 		break;
 	}
 
-	sock_set_flag(&smc->sk, SOCK_DEAD);
-	smc->sk.sk_state_change(&smc->sk);
+	sock_set_flag(sk, SOCK_DEAD);
+	sk->sk_state_change(sk);
 }
 
 static inline bool smc_close_sent_any_close(struct smc_connection *conn)
@@ -278,7 +280,7 @@ int smc_close_active(struct smc_sock *smc)
 	}
 
 	if (old_state != sk->sk_state)
-		sk->sk_state_change(&smc->sk);
+		sk->sk_state_change(sk);
 	return rc;
 }
 
@@ -331,7 +333,7 @@ static void smc_close_passive_work(struct work_struct *work)
 	struct sock *sk = &smc->sk;
 	int old_state;
 
-	lock_sock(&smc->sk);
+	lock_sock(sk);
 	old_state = sk->sk_state;
 
 	if (!conn->alert_token_local) {
@@ -340,7 +342,7 @@ static void smc_close_passive_work(struct work_struct *work)
 		goto wakeup;
 	}
 
-	rxflags = &smc->conn.local_rx_ctrl.conn_state_flags;
+	rxflags = &conn->local_rx_ctrl.conn_state_flags;
 	if (rxflags->peer_conn_abort) {
 		smc_close_passive_abort_received(smc);
 		goto wakeup;
@@ -348,7 +350,7 @@ static void smc_close_passive_work(struct work_struct *work)
 
 	switch (sk->sk_state) {
 	case SMC_INIT:
-		if (atomic_read(&smc->conn.bytes_to_rcv) ||
+		if (atomic_read(&conn->bytes_to_rcv) ||
 		    (rxflags->peer_done_writing &&
 		     !smc_cdc_rxed_any_close(conn)))
 			sk->sk_state = SMC_APPCLOSEWAIT1;
@@ -365,7 +367,7 @@ static void smc_close_passive_work(struct work_struct *work)
 		/* to check for closing */
 	case SMC_PEERCLOSEWAIT2:
 	case SMC_PEERFINCLOSEWAIT:
-		if (!smc_cdc_rxed_any_close(&smc->conn))
+		if (!smc_cdc_rxed_any_close(conn))
 			break;
 		if (sock_flag(sk, SOCK_DEAD) &&
 		    smc_close_sent_any_close(conn)) {
@@ -394,12 +396,12 @@ static void smc_close_passive_work(struct work_struct *work)
 		sk->sk_state_change(sk);
 		if ((sk->sk_state == SMC_CLOSED) &&
 		    (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
-			smc_conn_free(&smc->conn);
+			smc_conn_free(conn);
 			schedule_delayed_work(&smc->sock_put_work,
 					      SMC_CLOSE_SOCK_PUT_DELAY);
 		}
 	}
-	release_sock(&smc->sk);
+	release_sock(sk);
 }
 
 void smc_close_sock_put_work(struct work_struct *work)
@@ -462,7 +464,7 @@ int smc_close_shutdown_write(struct smc_sock *smc)
 	}
 
 	if (old_state != sk->sk_state)
-		sk->sk_state_change(&smc->sk);
+		sk->sk_state_change(sk);
 	return rc;
 }
 
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 2/6] net/smc: simplify function smc_clcsock_accept()
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 1/6] net/smc: use local struct sock variables consistently Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 3/6] net/smc: get rid of tx_pend waits in socket closing Ursula Braun
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Cleanup to avoid duplicate code in smc_clcsock_accept().
No functional change.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/af_smc.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index eccccf743b9f..05cbcd3a6f60 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -599,16 +599,9 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
 
 	rc = kernel_accept(lsmc->clcsock, &new_clcsock, 0);
 	lock_sock(lsk);
-	if  (rc < 0) {
+	if  (rc < 0)
 		lsk->sk_err = -rc;
-		new_sk->sk_state = SMC_CLOSED;
-		sock_set_flag(new_sk, SOCK_DEAD);
-		new_sk->sk_prot->unhash(new_sk);
-		sock_put(new_sk);
-		*new_smc = NULL;
-		goto out;
-	}
-	if (lsk->sk_state == SMC_CLOSED) {
+	if (rc < 0 || lsk->sk_state == SMC_CLOSED) {
 		if (new_clcsock)
 			sock_release(new_clcsock);
 		new_sk->sk_state = SMC_CLOSED;
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 3/6] net/smc: get rid of tx_pend waits in socket closing
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 1/6] net/smc: use local struct sock variables consistently Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 2/6] net/smc: simplify function smc_clcsock_accept() Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 4/6] net/smc: make wait for work request uninterruptible Ursula Braun
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

There is no need to wait for confirmation of pending tx requests
for a closing connection, since pending tx slots are dismissed
when finishing a connection.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/smc_cdc.c   | 11 -----------
 net/smc/smc_cdc.h   |  1 -
 net/smc/smc_close.c | 25 -------------------------
 net/smc/smc_wr.c    | 18 ------------------
 net/smc/smc_wr.h    |  2 --
 5 files changed, 57 deletions(-)

diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index d4155ff6acde..51805334e001 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -57,9 +57,6 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
 			       cdcpend->conn);
 	}
 	smc_tx_sndbuf_nonfull(smc);
-	if (smc->sk.sk_state != SMC_ACTIVE)
-		/* wake up smc_close_wait_tx_pends() */
-		smc->sk.sk_state_change(&smc->sk);
 	bh_unlock_sock(&smc->sk);
 }
 
@@ -155,14 +152,6 @@ void smc_cdc_tx_dismiss_slots(struct smc_connection *conn)
 				(unsigned long)conn);
 }
 
-bool smc_cdc_tx_has_pending(struct smc_connection *conn)
-{
-	struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
-
-	return smc_wr_tx_has_pending(link, SMC_CDC_MSG_TYPE,
-				     smc_cdc_tx_filter, (unsigned long)conn);
-}
-
 /********************************* receive ***********************************/
 
 static inline bool smc_cdc_before(u16 seq1, u16 seq2)
diff --git a/net/smc/smc_cdc.h b/net/smc/smc_cdc.h
index 149ceda1b088..ab240b37ad11 100644
--- a/net/smc/smc_cdc.h
+++ b/net/smc/smc_cdc.h
@@ -214,7 +214,6 @@ void smc_cdc_tx_dismiss_slots(struct smc_connection *conn);
 int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf,
 		     struct smc_cdc_tx_pend *pend);
 int smc_cdc_get_slot_and_msg_send(struct smc_connection *conn);
-bool smc_cdc_tx_has_pending(struct smc_connection *conn);
 int smc_cdc_init(void) __init;
 
 #endif /* SMC_CDC_H */
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 11793912f001..bc539ccb8fa0 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -19,8 +19,6 @@
 #include "smc_cdc.h"
 #include "smc_close.h"
 
-#define SMC_CLOSE_WAIT_TX_PENDS_TIME		(5 * HZ)
-
 static void smc_close_cleanup_listen(struct sock *parent)
 {
 	struct sock *sk;
@@ -30,26 +28,6 @@ static void smc_close_cleanup_listen(struct sock *parent)
 		smc_close_non_accepted(sk);
 }
 
-static void smc_close_wait_tx_pends(struct smc_sock *smc)
-{
-	DEFINE_WAIT_FUNC(wait, woken_wake_function);
-	struct sock *sk = &smc->sk;
-	signed long timeout;
-
-	timeout = SMC_CLOSE_WAIT_TX_PENDS_TIME;
-	add_wait_queue(sk_sleep(sk), &wait);
-	while (!signal_pending(current) && timeout) {
-		int rc;
-
-		rc = sk_wait_event(sk, &timeout,
-				   !smc_cdc_tx_has_pending(&smc->conn),
-				   &wait);
-		if (rc)
-			break;
-	}
-	remove_wait_queue(sk_sleep(sk), &wait);
-}
-
 /* wait for sndbuf data being transmitted */
 static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
 {
@@ -230,7 +208,6 @@ int smc_close_active(struct smc_sock *smc)
 			rc = smc_close_final(conn);
 		}
 		sk->sk_state = SMC_CLOSED;
-		smc_close_wait_tx_pends(smc);
 		break;
 	case SMC_APPCLOSEWAIT1:
 	case SMC_APPCLOSEWAIT2:
@@ -251,7 +228,6 @@ int smc_close_active(struct smc_sock *smc)
 		else
 			/* peer has just issued a shutdown write */
 			sk->sk_state = SMC_PEERFINCLOSEWAIT;
-		smc_close_wait_tx_pends(smc);
 		break;
 	case SMC_PEERCLOSEWAIT1:
 	case SMC_PEERCLOSEWAIT2:
@@ -271,7 +247,6 @@ int smc_close_active(struct smc_sock *smc)
 		lock_sock(sk);
 		smc_close_abort(conn);
 		sk->sk_state = SMC_CLOSED;
-		smc_close_wait_tx_pends(smc);
 		break;
 	case SMC_PEERABORTWAIT:
 	case SMC_CLOSED:
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c
index de4537f66832..a4477b4a9c18 100644
--- a/net/smc/smc_wr.c
+++ b/net/smc/smc_wr.c
@@ -319,24 +319,6 @@ void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_rx_hdr_type,
 	}
 }
 
-bool smc_wr_tx_has_pending(struct smc_link *link, u8 wr_rx_hdr_type,
-			   smc_wr_tx_filter filter, unsigned long data)
-{
-	struct smc_wr_tx_pend_priv *tx_pend;
-	struct smc_wr_rx_hdr *wr_rx;
-	int i;
-
-	for_each_set_bit(i, link->wr_tx_mask, link->wr_tx_cnt) {
-		wr_rx = (struct smc_wr_rx_hdr *)&link->wr_rx_bufs[i];
-		if (wr_rx->type != wr_rx_hdr_type)
-			continue;
-		tx_pend = &link->wr_tx_pends[i].priv;
-		if (filter(tx_pend, data))
-			return true;
-	}
-	return false;
-}
-
 /****************************** receive queue ********************************/
 
 int smc_wr_rx_register_handler(struct smc_wr_rx_handler *handler)
diff --git a/net/smc/smc_wr.h b/net/smc/smc_wr.h
index 2acf12b06063..ef0c3494c9cb 100644
--- a/net/smc/smc_wr.h
+++ b/net/smc/smc_wr.h
@@ -93,8 +93,6 @@ int smc_wr_tx_put_slot(struct smc_link *link,
 int smc_wr_tx_send(struct smc_link *link,
 		   struct smc_wr_tx_pend_priv *wr_pend_priv);
 void smc_wr_tx_cq_handler(struct ib_cq *ib_cq, void *cq_context);
-bool smc_wr_tx_has_pending(struct smc_link *link, u8 wr_rx_hdr_type,
-			   smc_wr_tx_filter filter, unsigned long data);
 void smc_wr_tx_dismiss_slots(struct smc_link *lnk, u8 wr_rx_hdr_type,
 			     smc_wr_tx_filter filter,
 			     smc_wr_tx_dismisser dismisser,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 4/6] net/smc: make wait for work request uninterruptible
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
                   ` (2 preceding siblings ...)
  2018-01-24  9:28 ` [PATCH net-next 3/6] net/smc: get rid of tx_pend waits in socket closing Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 5/6] net/smc: improve state change handling after close wait Ursula Braun
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

Work requests are needed for every ib_post_send(), among them the
ib_post_send() to signal closing. If an smc socket program is cancelled,
the smc connections should be cleaned up, and require sending of closing
signals to the peer. This may fail, if a wait for
a free work request is needed, but is cancelled immediately due to the
cancel interrupt. To guarantee notification of the peer, the wait for
a work request is changed to uninterruptible.

And the area to receive work request completion info with
ib_poll_cq() is cleared first.
And _tx_ variable names are used in the _tx_routines for the
demultiplexing common type in the header.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/smc_wr.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c
index a4477b4a9c18..5ed94109d1d6 100644
--- a/net/smc/smc_wr.c
+++ b/net/smc/smc_wr.c
@@ -122,6 +122,7 @@ static void smc_wr_tx_tasklet_fn(unsigned long data)
 again:
 	polled++;
 	do {
+		memset(&wc, 0, sizeof(wc));
 		rc = ib_poll_cq(dev->roce_cq_send, SMC_WR_MAX_POLL_CQE, wc);
 		if (polled == 1) {
 			ib_req_notify_cq(dev->roce_cq_send,
@@ -185,7 +186,7 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
 		if (rc)
 			return rc;
 	} else {
-		rc = wait_event_interruptible_timeout(
+		rc = wait_event_timeout(
 			link->wr_tx_wait,
 			(smc_wr_tx_get_free_slot_index(link, &idx) != -EBUSY),
 			SMC_WR_TX_WAIT_FREE_SLOT_TIME);
@@ -198,8 +199,6 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
 			smc_lgr_terminate(lgr);
 			return -EPIPE;
 		}
-		if (rc == -ERESTARTSYS)
-			return -EINTR;
 		if (idx == link->wr_tx_cnt)
 			return -EPIPE;
 	}
@@ -300,18 +299,18 @@ int smc_wr_reg_send(struct smc_link *link, struct ib_mr *mr)
 	return rc;
 }
 
-void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_rx_hdr_type,
+void smc_wr_tx_dismiss_slots(struct smc_link *link, u8 wr_tx_hdr_type,
 			     smc_wr_tx_filter filter,
 			     smc_wr_tx_dismisser dismisser,
 			     unsigned long data)
 {
 	struct smc_wr_tx_pend_priv *tx_pend;
-	struct smc_wr_rx_hdr *wr_rx;
+	struct smc_wr_rx_hdr *wr_tx;
 	int i;
 
 	for_each_set_bit(i, link->wr_tx_mask, link->wr_tx_cnt) {
-		wr_rx = (struct smc_wr_rx_hdr *)&link->wr_rx_bufs[i];
-		if (wr_rx->type != wr_rx_hdr_type)
+		wr_tx = (struct smc_wr_rx_hdr *)&link->wr_tx_bufs[i];
+		if (wr_tx->type != wr_tx_hdr_type)
 			continue;
 		tx_pend = &link->wr_tx_pends[i].priv;
 		if (filter(tx_pend, data))
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 5/6] net/smc: improve state change handling after close wait
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
                   ` (3 preceding siblings ...)
  2018-01-24  9:28 ` [PATCH net-next 4/6] net/smc: make wait for work request uninterruptible Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24  9:28 ` [PATCH net-next 6/6] net/smc: continue waiting if peer signals write_shutdown Ursula Braun
  2018-01-24 15:55 ` [PATCH net-next 0/6] net/smc: socket closing improvements David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

When a socket is closed or shutdown, smc waits for data being transmitted
in certain states. If the state changes during this wait, the close
switch depending on state should be reentered.
In addition, state change is avoided if sending of close or shutdown fails.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/smc_close.c | 40 ++++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index bc539ccb8fa0..1468a2a3cdf4 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -165,9 +165,9 @@ int smc_close_active(struct smc_sock *smc)
 		  0 : sock_flag(sk, SOCK_LINGER) ?
 		      sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
 
-again:
 	old_state = sk->sk_state;
-	switch (old_state) {
+again:
+	switch (sk->sk_state) {
 	case SMC_INIT:
 		sk->sk_state = SMC_CLOSED;
 		if (smc->smc_listen_work.func)
@@ -194,6 +194,8 @@ int smc_close_active(struct smc_sock *smc)
 		if (sk->sk_state == SMC_ACTIVE) {
 			/* send close request */
 			rc = smc_close_final(conn);
+			if (rc)
+				break;
 			sk->sk_state = SMC_PEERCLOSEWAIT1;
 		} else {
 			/* peer event has changed the state */
@@ -206,6 +208,8 @@ int smc_close_active(struct smc_sock *smc)
 		    !smc_close_sent_any_close(conn)) {
 			/* just shutdown wr done, send close request */
 			rc = smc_close_final(conn);
+			if (rc)
+				break;
 		}
 		sk->sk_state = SMC_CLOSED;
 		break;
@@ -216,12 +220,13 @@ int smc_close_active(struct smc_sock *smc)
 		release_sock(sk);
 		cancel_delayed_work_sync(&conn->tx_work);
 		lock_sock(sk);
-		if (sk->sk_err != ECONNABORTED) {
-			/* confirm close from peer */
-			rc = smc_close_final(conn);
-			if (rc)
-				break;
-		}
+		if (sk->sk_state != SMC_APPCLOSEWAIT1 &&
+		    sk->sk_state != SMC_APPCLOSEWAIT2)
+			goto again;
+		/* confirm close from peer */
+		rc = smc_close_final(conn);
+		if (rc)
+			break;
 		if (smc_cdc_rxed_any_close(conn))
 			/* peer has closed the socket already */
 			sk->sk_state = SMC_CLOSED;
@@ -235,6 +240,8 @@ int smc_close_active(struct smc_sock *smc)
 		    !smc_close_sent_any_close(conn)) {
 			/* just shutdown wr done, send close request */
 			rc = smc_close_final(conn);
+			if (rc)
+				break;
 		}
 		/* peer sending PeerConnectionClosed will cause transition */
 		break;
@@ -401,20 +408,21 @@ int smc_close_shutdown_write(struct smc_sock *smc)
 		  0 : sock_flag(sk, SOCK_LINGER) ?
 		      sk->sk_lingertime : SMC_MAX_STREAM_WAIT_TIMEOUT;
 
-again:
 	old_state = sk->sk_state;
-	switch (old_state) {
+again:
+	switch (sk->sk_state) {
 	case SMC_ACTIVE:
 		smc_close_stream_wait(smc, timeout);
 		release_sock(sk);
 		cancel_delayed_work_sync(&conn->tx_work);
 		lock_sock(sk);
+		if (sk->sk_state != SMC_ACTIVE)
+			goto again;
 		/* send close wr request */
 		rc = smc_close_wr(conn);
-		if (sk->sk_state == SMC_ACTIVE)
-			sk->sk_state = SMC_PEERCLOSEWAIT1;
-		else
-			goto again;
+		if (rc)
+			break;
+		sk->sk_state = SMC_PEERCLOSEWAIT1;
 		break;
 	case SMC_APPCLOSEWAIT1:
 		/* passive close */
@@ -423,8 +431,12 @@ int smc_close_shutdown_write(struct smc_sock *smc)
 		release_sock(sk);
 		cancel_delayed_work_sync(&conn->tx_work);
 		lock_sock(sk);
+		if (sk->sk_state != SMC_APPCLOSEWAIT1)
+			goto again;
 		/* confirm close from peer */
 		rc = smc_close_wr(conn);
+		if (rc)
+			break;
 		sk->sk_state = SMC_APPCLOSEWAIT2;
 		break;
 	case SMC_APPCLOSEWAIT2:
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 6/6] net/smc: continue waiting if peer signals write_shutdown
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
                   ` (4 preceding siblings ...)
  2018-01-24  9:28 ` [PATCH net-next 5/6] net/smc: improve state change handling after close wait Ursula Braun
@ 2018-01-24  9:28 ` Ursula Braun
  2018-01-24 15:55 ` [PATCH net-next 0/6] net/smc: socket closing improvements David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: Ursula Braun @ 2018-01-24  9:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl, ubraun

If the peer sends a shutdown WRITE, this should not affect sending
in general, and waiting for send buffer space in particular.
Stop waiting of the local socket for send buffer space only, if peer
signals closing, but not if peer signals just shutdown WRITE.

Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
---
 net/smc/smc_tx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index 2e50fddf8ce9..fea6482233a6 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -86,7 +86,7 @@ static int smc_tx_wait_memory(struct smc_sock *smc, int flags)
 			rc = -EPIPE;
 			break;
 		}
-		if (conn->local_rx_ctrl.conn_state_flags.peer_conn_abort) {
+		if (smc_cdc_rxed_any_close(conn)) {
 			rc = -ECONNRESET;
 			break;
 		}
@@ -107,7 +107,7 @@ static int smc_tx_wait_memory(struct smc_sock *smc, int flags)
 		sk_wait_event(sk, &timeo,
 			      sk->sk_err ||
 			      (sk->sk_shutdown & SEND_SHUTDOWN) ||
-			      smc_cdc_rxed_any_close_or_senddone(conn) ||
+			      smc_cdc_rxed_any_close(conn) ||
 			      atomic_read(&conn->sndbuf_space),
 			      &wait);
 	}
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/6] net/smc: socket closing improvements
  2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
                   ` (5 preceding siblings ...)
  2018-01-24  9:28 ` [PATCH net-next 6/6] net/smc: continue waiting if peer signals write_shutdown Ursula Braun
@ 2018-01-24 15:55 ` David Miller
  6 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2018-01-24 15:55 UTC (permalink / raw)
  To: ubraun; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl

From: Ursula Braun <ubraun@linux.vnet.ibm.com>
Date: Wed, 24 Jan 2018 10:28:11 +0100

> while the first 2 patches are just small cleanups, the remaing
> patches affect socket closing.

Series applied, thanks!

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-01-24 15:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-24  9:28 [PATCH net-next 0/6] net/smc: socket closing improvements Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 1/6] net/smc: use local struct sock variables consistently Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 2/6] net/smc: simplify function smc_clcsock_accept() Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 3/6] net/smc: get rid of tx_pend waits in socket closing Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 4/6] net/smc: make wait for work request uninterruptible Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 5/6] net/smc: improve state change handling after close wait Ursula Braun
2018-01-24  9:28 ` [PATCH net-next 6/6] net/smc: continue waiting if peer signals write_shutdown Ursula Braun
2018-01-24 15:55 ` [PATCH net-next 0/6] net/smc: socket closing improvements David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).