* [PATCH net-next 00/10] net/smc: patches for net-next
@ 2017-04-10 12:57 Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 01/10] net/smc: get rid of old comment Ursula Braun
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:57 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
Hi Dave,
here are some patches for net/smc. Most important are
improvements for socket closing.
Thanks, Ursula
Ursula Braun (10):
net/smc: get rid of old comment
net/smc: remove useless smc_ib_devices_list check
net/smc: return active RoCE port only
net/smc: guarantee reset of write_blocked for heavy workload
net/smc: always call the POLL_IN part of sk_wake_async
net/smc: no socket state changes in tasklet context
net/smc: guarantee ConnClosed send after shutdown SHUT_WR
net/smc: remove duplicate unhash
net/smc: destruct non-accepted sockets
net/smc: do not use IB_SEND_INLINE together with mapped data
net/smc/af_smc.c | 23 +++++++++++------
net/smc/smc.h | 1 +
net/smc/smc_cdc.c | 11 +++++---
net/smc/smc_close.c | 74 +++++++++++++++++++++++++++++++++++------------------
net/smc/smc_close.h | 2 +-
net/smc/smc_core.c | 2 +-
net/smc/smc_ib.c | 3 ---
net/smc/smc_pnet.c | 9 ++++---
net/smc/smc_pnet.h | 1 -
net/smc/smc_rx.c | 3 +--
net/smc/smc_tx.c | 6 ++++-
net/smc/smc_wr.c | 2 +-
12 files changed, 87 insertions(+), 50 deletions(-)
--
2.10.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next 01/10] net/smc: get rid of old comment
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
@ 2017-04-10 12:57 ` Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 02/10] net/smc: remove useless smc_ib_devices_list check Ursula Braun
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:57 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
This patch removes an outdated comment.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_cdc.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index 5a33949..4c9c2f6 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -228,8 +228,6 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
smc_close_wake_tx_prepared(smc);
}
- /* subsequent patch: trigger socket release if connection closed */
-
/* socket connected but not accepted */
if (!smc->sk.sk_socket)
return;
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 02/10] net/smc: remove useless smc_ib_devices_list check
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 01/10] net/smc: get rid of old comment Ursula Braun
@ 2017-04-10 12:57 ` Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 03/10] net/smc: return active RoCE port only Ursula Braun
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:57 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
The global event handler is created only, if the ib_device has already
been used by at least one link group. It is guaranteed that there exists
the corresponding entry in the smc_ib_devices list. Get rid of this
superfluous check.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_ib.c | 2 --
net/smc/smc_pnet.c | 2 +-
net/smc/smc_pnet.h | 1 -
3 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index e6743c0..b762577 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -179,8 +179,6 @@ static void smc_ib_global_event_handler(struct ib_event_handler *handler,
u8 port_idx;
smcibdev = container_of(handler, struct smc_ib_device, event_handler);
- if (!smc_pnet_find_ib(smcibdev->ibdev->name))
- return;
switch (ibevent->event) {
case IB_EVENT_PORT_ERR:
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 9d3e7fb..f1cff01 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -219,7 +219,7 @@ static bool smc_pnetid_valid(const char *pnet_name, char *pnetid)
}
/* Find an infiniband device by a given name. The device might not exist. */
-struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
+static struct smc_ib_device *smc_pnet_find_ib(char *ib_name)
{
struct smc_ib_device *ibdev;
diff --git a/net/smc/smc_pnet.h b/net/smc/smc_pnet.h
index 32ab3df..c4f1bcc 100644
--- a/net/smc/smc_pnet.h
+++ b/net/smc/smc_pnet.h
@@ -16,7 +16,6 @@ struct smc_ib_device;
int smc_pnet_init(void) __init;
void smc_pnet_exit(void);
int smc_pnet_remove_by_ibdev(struct smc_ib_device *ibdev);
-struct smc_ib_device *smc_pnet_find_ib(char *ib_name);
void smc_pnet_find_roce_resource(struct sock *sk,
struct smc_ib_device **smcibdev, u8 *ibport);
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 03/10] net/smc: return active RoCE port only
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 01/10] net/smc: get rid of old comment Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 02/10] net/smc: remove useless smc_ib_devices_list check Ursula Braun
@ 2017-04-10 12:57 ` Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 04/10] net/smc: guarantee reset of write_blocked for heavy workload Ursula Braun
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:57 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
SMC requires an active ib port on the RoCE device.
smc_pnet_find_roce_resource() determines the matching RoCE device port
according to the configured PNET table. Do not return the found
RoCE device port, if it is not flagged active.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_pnet.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index f1cff01..78f7af2 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -523,8 +523,11 @@ void smc_pnet_find_roce_resource(struct sock *sk,
read_lock(&smc_pnettable.lock);
list_for_each_entry(pnetelem, &smc_pnettable.pnetlist, list) {
if (dst->dev == pnetelem->ndev) {
- *smcibdev = pnetelem->smcibdev;
- *ibport = pnetelem->ib_port;
+ if (smc_ib_port_active(pnetelem->smcibdev,
+ pnetelem->ib_port)) {
+ *smcibdev = pnetelem->smcibdev;
+ *ibport = pnetelem->ib_port;
+ }
break;
}
}
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 04/10] net/smc: guarantee reset of write_blocked for heavy workload
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (2 preceding siblings ...)
2017-04-10 12:57 ` [PATCH net-next 03/10] net/smc: return active RoCE port only Ursula Braun
@ 2017-04-10 12:57 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 05/10] net/smc: always call the POLL_IN part of sk_wake_async Ursula Braun
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:57 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
If peer indicates write_blocked, the cursor state of the received data
should be send to the peer immediately (in smc_tx_consumer_update()).
Afterwards the write_blocked indicator is cleared.
If there is no free slot for another write request, sending is postponed
to worker smc_tx_work, and the write_blocked indicator is not cleared.
Therefore another clearing check is needed in smc_tx_work().
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_tx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index 69a0013..21ec183 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -431,9 +431,13 @@ static void smc_tx_work(struct work_struct *work)
struct smc_connection,
tx_work);
struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
+ int rc;
lock_sock(&smc->sk);
- smc_tx_sndbuf_nonempty(conn);
+ rc = smc_tx_sndbuf_nonempty(conn);
+ if (!rc && conn->local_rx_ctrl.prod_flags.write_blocked &&
+ !atomic_read(&conn->bytes_to_rcv))
+ conn->local_rx_ctrl.prod_flags.write_blocked = 0;
release_sock(&smc->sk);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 05/10] net/smc: always call the POLL_IN part of sk_wake_async
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (3 preceding siblings ...)
2017-04-10 12:57 ` [PATCH net-next 04/10] net/smc: guarantee reset of write_blocked for heavy workload Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 06/10] net/smc: no socket state changes in tasklet context Ursula Braun
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
Wake up reading file descriptors for a closing socket as well, otherwise
some socket applications may stall.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_rx.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index c4ef9a4..f0c8b08 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -36,11 +36,10 @@ static void smc_rx_data_ready(struct sock *sk)
if (skwq_has_sleeper(wq))
wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
POLLRDNORM | POLLRDBAND);
+ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
(sk->sk_state == SMC_CLOSED))
sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP);
- else
- sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
rcu_read_unlock();
}
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 06/10] net/smc: no socket state changes in tasklet context
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (4 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 05/10] net/smc: always call the POLL_IN part of sk_wake_async Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 07/10] net/smc: guarantee ConnClosed send after shutdown SHUT_WR Ursula Braun
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
Several state changes occur during SMC socket closing. Currently
state changes triggered locally occur in process context with
lock_sock() taken while state changes triggered by peer occur in
tasklet context with bh_lock_sock() taken. bh_lock_sock() does not
wait till a lock_sock(() task in process context is finished. This
may lead to races in socket state transitions resulting in dangling
SMC-sockets, or it may lead to duplicate SMC socket freeing.
This patch introduces a closing worker to run all state changes under
lock_sock().
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Reported-by: Dave Jones <davej@codemonkey.org.uk>
---
net/smc/af_smc.c | 8 ++++++--
net/smc/smc.h | 1 +
net/smc/smc_cdc.c | 9 +++++++--
net/smc/smc_close.c | 39 +++++++++++++++++++++++++--------------
net/smc/smc_close.h | 2 +-
net/smc/smc_core.c | 2 +-
6 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 0938037..3b7eda6 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -451,6 +451,9 @@ static int smc_connect_rdma(struct smc_sock *smc)
goto decline_rdma_unlock;
}
+ smc_close_init(smc);
+ smc_rx_init(smc);
+
if (local_contact == SMC_FIRST_CONTACT) {
rc = smc_ib_ready_link(link);
if (rc) {
@@ -477,7 +480,6 @@ static int smc_connect_rdma(struct smc_sock *smc)
mutex_unlock(&smc_create_lgr_pending);
smc_tx_init(smc);
- smc_rx_init(smc);
out_connected:
smc_copy_sock_settings_to_clc(smc);
@@ -800,6 +802,9 @@ static void smc_listen_work(struct work_struct *work)
goto decline_rdma;
}
+ smc_close_init(new_smc);
+ smc_rx_init(new_smc);
+
rc = smc_clc_send_accept(new_smc, local_contact);
if (rc)
goto out_err;
@@ -839,7 +844,6 @@ static void smc_listen_work(struct work_struct *work)
}
smc_tx_init(new_smc);
- smc_rx_init(new_smc);
out_connected:
sk_refcnt_debug_inc(newsmcsk);
diff --git a/net/smc/smc.h b/net/smc/smc.h
index ee5fbea..6e44313e 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -164,6 +164,7 @@ struct smc_connection {
#ifndef KERNEL_HAS_ATOMIC64
spinlock_t acurs_lock; /* protect cursors */
#endif
+ struct work_struct close_work; /* peer sent some closing */
};
struct smc_sock { /* smc sock container */
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index 4c9c2f6..a7294ed 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -217,8 +217,13 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
smc->sk.sk_err = ECONNRESET;
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
}
- if (smc_cdc_rxed_any_close_or_senddone(conn))
- smc_close_passive_received(smc);
+ if (smc_cdc_rxed_any_close_or_senddone(conn)) {
+ smc->sk.sk_shutdown |= RCV_SHUTDOWN;
+ if (smc->clcsock && smc->clcsock->sk)
+ smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN;
+ sock_set_flag(&smc->sk, SOCK_DONE);
+ schedule_work(&conn->close_work);
+ }
/* piggy backed tx info */
/* trigger sndbuf consumer: RDMA write into peer RMBE and CDC */
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 67a71d1..388503b 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -117,7 +117,6 @@ void smc_close_active_abort(struct smc_sock *smc)
struct smc_cdc_conn_state_flags *txflags =
&smc->conn.local_tx_ctrl.conn_state_flags;
- bh_lock_sock(&smc->sk);
smc->sk.sk_err = ECONNABORTED;
if (smc->clcsock && smc->clcsock->sk) {
smc->clcsock->sk->sk_err = ECONNABORTED;
@@ -125,6 +124,7 @@ void smc_close_active_abort(struct smc_sock *smc)
}
switch (smc->sk.sk_state) {
case SMC_INIT:
+ case SMC_ACTIVE:
smc->sk.sk_state = SMC_PEERABORTWAIT;
break;
case SMC_APPCLOSEWAIT1:
@@ -161,7 +161,6 @@ void smc_close_active_abort(struct smc_sock *smc)
}
sock_set_flag(&smc->sk, SOCK_DEAD);
- bh_unlock_sock(&smc->sk);
smc->sk.sk_state_change(&smc->sk);
}
@@ -185,7 +184,7 @@ int smc_close_active(struct smc_sock *smc)
case SMC_INIT:
sk->sk_state = SMC_CLOSED;
if (smc->smc_listen_work.func)
- flush_work(&smc->smc_listen_work);
+ cancel_work_sync(&smc->smc_listen_work);
sock_put(sk);
break;
case SMC_LISTEN:
@@ -198,7 +197,7 @@ int smc_close_active(struct smc_sock *smc)
}
release_sock(sk);
smc_close_cleanup_listen(sk);
- flush_work(&smc->tcp_listen_work);
+ cancel_work_sync(&smc->smc_listen_work);
lock_sock(sk);
break;
case SMC_ACTIVE:
@@ -306,22 +305,27 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
/* Some kind of closing has been received: peer_conn_closed, peer_conn_abort,
* or peer_done_writing.
- * Called under tasklet context.
*/
-void smc_close_passive_received(struct smc_sock *smc)
+static void smc_close_passive_work(struct work_struct *work)
{
- struct smc_cdc_conn_state_flags *rxflags =
- &smc->conn.local_rx_ctrl.conn_state_flags;
+ struct smc_connection *conn = container_of(work,
+ struct smc_connection,
+ close_work);
+ struct smc_sock *smc = container_of(conn, struct smc_sock, conn);
+ struct smc_cdc_conn_state_flags *rxflags;
struct sock *sk = &smc->sk;
int old_state;
- sk->sk_shutdown |= RCV_SHUTDOWN;
- if (smc->clcsock && smc->clcsock->sk)
- smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN;
- sock_set_flag(&smc->sk, SOCK_DONE);
-
+ lock_sock(&smc->sk);
old_state = sk->sk_state;
+ if (!conn->alert_token_local) {
+ /* abnormal termination */
+ smc_close_active_abort(smc);
+ goto wakeup;
+ }
+
+ rxflags = &smc->conn.local_rx_ctrl.conn_state_flags;
if (rxflags->peer_conn_abort) {
smc_close_passive_abort_received(smc);
goto wakeup;
@@ -373,11 +377,12 @@ void smc_close_passive_received(struct smc_sock *smc)
sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
if ((sk->sk_state == SMC_CLOSED) &&
- (sock_flag(sk, SOCK_DEAD) || (old_state == SMC_INIT))) {
+ (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
smc_conn_free(&smc->conn);
schedule_delayed_work(&smc->sock_put_work,
SMC_CLOSE_SOCK_PUT_DELAY);
}
+ release_sock(&smc->sk);
}
void smc_close_sock_put_work(struct work_struct *work)
@@ -442,3 +447,9 @@ int smc_close_shutdown_write(struct smc_sock *smc)
sk->sk_state_change(&smc->sk);
return rc;
}
+
+/* Initialize close properties on connection establishment. */
+void smc_close_init(struct smc_sock *smc)
+{
+ INIT_WORK(&smc->conn.close_work, smc_close_passive_work);
+}
diff --git a/net/smc/smc_close.h b/net/smc/smc_close.h
index bc9a2df..4a3d99a 100644
--- a/net/smc/smc_close.h
+++ b/net/smc/smc_close.h
@@ -21,8 +21,8 @@
void smc_close_wake_tx_prepared(struct smc_sock *smc);
void smc_close_active_abort(struct smc_sock *smc);
int smc_close_active(struct smc_sock *smc);
-void smc_close_passive_received(struct smc_sock *smc);
void smc_close_sock_put_work(struct work_struct *work);
int smc_close_shutdown_write(struct smc_sock *smc);
+void smc_close_init(struct smc_sock *smc);
#endif /* SMC_CLOSE_H */
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index 0eac633..65020e9 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -316,7 +316,7 @@ void smc_lgr_terminate(struct smc_link_group *lgr)
smc = container_of(conn, struct smc_sock, conn);
sock_hold(&smc->sk);
__smc_lgr_unregister_conn(conn);
- smc_close_active_abort(smc);
+ schedule_work(&conn->close_work);
sock_put(&smc->sk);
node = rb_first(&lgr->conns_all);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 07/10] net/smc: guarantee ConnClosed send after shutdown SHUT_WR
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (5 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 06/10] net/smc: no socket state changes in tasklet context Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 08/10] net/smc: remove duplicate unhash Ursula Braun
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
State SMC_CLOSED should be reached only, if ConnClosed has been sent to
the peer. If ConnClosed is received from the peer, a socket with
shutdown SHUT_WR done, switches errorneously to state SMC_CLOSED, which
means the peer socket is dangling. The local SMC socket is supposed to
switch to state APPFINCLOSEWAIT to make sure smc_close_final() is called
during socket close.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_close.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 388503b..9070720b 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -164,6 +164,12 @@ void smc_close_active_abort(struct smc_sock *smc)
smc->sk.sk_state_change(&smc->sk);
}
+static inline bool smc_close_sent_any_close(struct smc_connection *conn)
+{
+ return conn->local_tx_ctrl.conn_state_flags.peer_conn_abort ||
+ conn->local_tx_ctrl.conn_state_flags.peer_conn_closed;
+}
+
int smc_close_active(struct smc_sock *smc)
{
struct smc_cdc_conn_state_flags *txflags =
@@ -217,7 +223,7 @@ int smc_close_active(struct smc_sock *smc)
case SMC_APPFINCLOSEWAIT:
/* socket already shutdown wr or both (active close) */
if (txflags->peer_done_writing &&
- !txflags->peer_conn_closed) {
+ !smc_close_sent_any_close(conn)) {
/* just shutdown wr done, send close request */
rc = smc_close_final(conn);
}
@@ -247,6 +253,13 @@ int smc_close_active(struct smc_sock *smc)
break;
case SMC_PEERCLOSEWAIT1:
case SMC_PEERCLOSEWAIT2:
+ if (txflags->peer_done_writing &&
+ !smc_close_sent_any_close(conn)) {
+ /* just shutdown wr done, send close request */
+ rc = smc_close_final(conn);
+ }
+ /* peer sending PeerConnectionClosed will cause transition */
+ break;
case SMC_PEERFINCLOSEWAIT:
/* peer sending PeerConnectionClosed will cause transition */
break;
@@ -284,7 +297,7 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
case SMC_PEERCLOSEWAIT1:
case SMC_PEERCLOSEWAIT2:
if (txflags->peer_done_writing &&
- !txflags->peer_conn_closed) {
+ !smc_close_sent_any_close(&smc->conn)) {
/* just shutdown, but not yet closed locally */
smc_close_abort(&smc->conn);
sk->sk_state = SMC_PROCESSABORT;
@@ -335,7 +348,7 @@ static void smc_close_passive_work(struct work_struct *work)
case SMC_INIT:
if (atomic_read(&smc->conn.bytes_to_rcv) ||
(rxflags->peer_done_writing &&
- !rxflags->peer_conn_closed))
+ !smc_cdc_rxed_any_close(conn)))
sk->sk_state = SMC_APPCLOSEWAIT1;
else
sk->sk_state = SMC_CLOSED;
@@ -352,7 +365,7 @@ static void smc_close_passive_work(struct work_struct *work)
if (!smc_cdc_rxed_any_close(&smc->conn))
break;
if (sock_flag(sk, SOCK_DEAD) &&
- (sk->sk_shutdown == SHUTDOWN_MASK)) {
+ smc_close_sent_any_close(conn)) {
/* smc_release has already been called locally */
sk->sk_state = SMC_CLOSED;
} else {
@@ -371,16 +384,17 @@ static void smc_close_passive_work(struct work_struct *work)
}
wakeup:
- if (old_state != sk->sk_state)
- sk->sk_state_change(sk);
sk->sk_data_ready(sk); /* wakeup blocked rcvbuf consumers */
sk->sk_write_space(sk); /* wakeup blocked sndbuf producers */
- if ((sk->sk_state == SMC_CLOSED) &&
- (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
- smc_conn_free(&smc->conn);
- schedule_delayed_work(&smc->sock_put_work,
- SMC_CLOSE_SOCK_PUT_DELAY);
+ if (old_state != sk->sk_state) {
+ sk->sk_state_change(sk);
+ if ((sk->sk_state == SMC_CLOSED) &&
+ (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) {
+ smc_conn_free(&smc->conn);
+ schedule_delayed_work(&smc->sock_put_work,
+ SMC_CLOSE_SOCK_PUT_DELAY);
+ }
}
release_sock(&smc->sk);
}
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 08/10] net/smc: remove duplicate unhash
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (6 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 07/10] net/smc: guarantee ConnClosed send after shutdown SHUT_WR Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 09/10] net/smc: destruct non-accepted sockets Ursula Braun
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
unhash is already called in sock_put_work. Remove the second call.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/af_smc.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 3b7eda6..491a8b2 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -147,7 +147,6 @@ static int smc_release(struct socket *sock)
schedule_delayed_work(&smc->sock_put_work,
SMC_CLOSE_SOCK_PUT_DELAY);
}
- sk->sk_prot->unhash(sk);
release_sock(sk);
sock_put(sk);
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 09/10] net/smc: destruct non-accepted sockets
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (7 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 08/10] net/smc: remove duplicate unhash Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 10/10] net/smc: do not use IB_SEND_INLINE together with mapped data Ursula Braun
2017-04-12 3:01 ` [PATCH net-next 00/10] net/smc: patches for net-next David Miller
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
Make sure sockets never accepted are removed cleanly.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/af_smc.c | 14 +++++++++-----
net/smc/smc_close.c | 1 -
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 491a8b2..5b6ee21 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -638,7 +638,8 @@ struct sock *smc_accept_dequeue(struct sock *parent,
smc_accept_unlink(new_sk);
if (new_sk->sk_state == SMC_CLOSED) {
- /* tbd in follow-on patch: close this sock */
+ new_sk->sk_prot->unhash(new_sk);
+ sock_put(new_sk);
continue;
}
if (new_sock)
@@ -658,8 +659,13 @@ void smc_close_non_accepted(struct sock *sk)
if (!sk->sk_lingertime)
/* wait for peer closing */
sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
- if (!smc->use_fallback)
+ if (smc->use_fallback) {
+ sk->sk_state = SMC_CLOSED;
+ } else {
smc_close_active(smc);
+ sock_set_flag(sk, SOCK_DEAD);
+ sk->sk_shutdown |= SHUTDOWN_MASK;
+ }
if (smc->clcsock) {
struct socket *tcp;
@@ -667,11 +673,9 @@ void smc_close_non_accepted(struct sock *sk)
smc->clcsock = NULL;
sock_release(tcp);
}
- sock_set_flag(sk, SOCK_DEAD);
- sk->sk_shutdown |= SHUTDOWN_MASK;
if (smc->use_fallback) {
schedule_delayed_work(&smc->sock_put_work, TCP_TIMEWAIT_LEN);
- } else {
+ } else if (sk->sk_state == SMC_CLOSED) {
smc_conn_free(&smc->conn);
schedule_delayed_work(&smc->sock_put_work,
SMC_CLOSE_SOCK_PUT_DELAY);
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c
index 9070720b..3c2e166 100644
--- a/net/smc/smc_close.c
+++ b/net/smc/smc_close.c
@@ -191,7 +191,6 @@ int smc_close_active(struct smc_sock *smc)
sk->sk_state = SMC_CLOSED;
if (smc->smc_listen_work.func)
cancel_work_sync(&smc->smc_listen_work);
- sock_put(sk);
break;
case SMC_LISTEN:
sk->sk_state = SMC_CLOSED;
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 10/10] net/smc: do not use IB_SEND_INLINE together with mapped data
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (8 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 09/10] net/smc: destruct non-accepted sockets Ursula Braun
@ 2017-04-10 12:58 ` Ursula Braun
2017-04-12 3:01 ` [PATCH net-next 00/10] net/smc: patches for net-next David Miller
10 siblings, 0 replies; 12+ messages in thread
From: Ursula Braun @ 2017-04-10 12:58 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl,
ubraun
smc specifies IB_SEND_INLINE for IB_WR_SEND ib_post_send calls, but
provides a mapped buffer to be sent. This is inconsistent, since
IB_SEND_INLINE works without mapped buffer. Problem has not been
detected in the past, because tests had been limited to Connect X3 cards
from Mellanox, whose mlx4 driver just ignored the IB_SEND_INLINE flag.
For now, the IB_SEND_INLINE flag is removed.
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
---
net/smc/smc_ib.c | 1 -
net/smc/smc_wr.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index b762577..16b7c80 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -257,7 +257,6 @@ int smc_ib_create_queue_pair(struct smc_link *lnk)
.max_recv_wr = SMC_WR_BUF_CNT * 3,
.max_send_sge = SMC_IB_MAX_SEND_SGE,
.max_recv_sge = 1,
- .max_inline_data = SMC_WR_TX_SIZE,
},
.sq_sig_type = IB_SIGNAL_REQ_WR,
.qp_type = IB_QPT_RC,
diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c
index eadf157..874ee9f 100644
--- a/net/smc/smc_wr.c
+++ b/net/smc/smc_wr.c
@@ -447,7 +447,7 @@ static void smc_wr_init_sge(struct smc_link *lnk)
lnk->wr_tx_ibs[i].num_sge = 1;
lnk->wr_tx_ibs[i].opcode = IB_WR_SEND;
lnk->wr_tx_ibs[i].send_flags =
- IB_SEND_SIGNALED | IB_SEND_SOLICITED | IB_SEND_INLINE;
+ IB_SEND_SIGNALED | IB_SEND_SOLICITED;
}
for (i = 0; i < lnk->wr_rx_cnt; i++) {
lnk->wr_rx_sges[i].addr =
--
2.10.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 00/10] net/smc: patches for net-next
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
` (9 preceding siblings ...)
2017-04-10 12:58 ` [PATCH net-next 10/10] net/smc: do not use IB_SEND_INLINE together with mapped data Ursula Braun
@ 2017-04-12 3:01 ` David Miller
10 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2017-04-12 3:01 UTC (permalink / raw)
To: ubraun; +Cc: netdev, linux-s390, jwi, schwidefsky, heiko.carstens, raspl
From: Ursula Braun <ubraun@linux.vnet.ibm.com>
Date: Mon, 10 Apr 2017 14:57:55 +0200
> here are some patches for net/smc. Most important are
> improvements for socket closing.
Series applied to net-next, thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-04-12 3:01 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-04-10 12:57 [PATCH net-next 00/10] net/smc: patches for net-next Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 01/10] net/smc: get rid of old comment Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 02/10] net/smc: remove useless smc_ib_devices_list check Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 03/10] net/smc: return active RoCE port only Ursula Braun
2017-04-10 12:57 ` [PATCH net-next 04/10] net/smc: guarantee reset of write_blocked for heavy workload Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 05/10] net/smc: always call the POLL_IN part of sk_wake_async Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 06/10] net/smc: no socket state changes in tasklet context Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 07/10] net/smc: guarantee ConnClosed send after shutdown SHUT_WR Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 08/10] net/smc: remove duplicate unhash Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 09/10] net/smc: destruct non-accepted sockets Ursula Braun
2017-04-10 12:58 ` [PATCH net-next 10/10] net/smc: do not use IB_SEND_INLINE together with mapped data Ursula Braun
2017-04-12 3:01 ` [PATCH net-next 00/10] net/smc: patches for net-next 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).