Skip to content

Commit bd71a35

Browse files
author
Jakub Kicinski
committed
Merge branch 'net-smc-improve-termination-handling'
Karsten Graul says: ==================== More patches to address abnormal termination processing of sockets and link groups. ==================== Signed-off-by: Jakub Kicinski <[email protected]>
2 parents fe28afe + 81cf4f4 commit bd71a35

File tree

11 files changed

+157
-72
lines changed

11 files changed

+157
-72
lines changed

net/smc/af_smc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ static int smc_release(struct socket *sock)
167167
if (!sk)
168168
goto out;
169169

170+
sock_hold(sk); /* sock_put below */
170171
smc = smc_sk(sk);
171172

172173
/* cleanup for a dangling non-blocking connect */
@@ -189,6 +190,7 @@ static int smc_release(struct socket *sock)
189190
sock->sk = NULL;
190191
release_sock(sk);
191192

193+
sock_put(sk); /* sock_hold above */
192194
sock_put(sk); /* final sock_put */
193195
out:
194196
return rc;
@@ -970,12 +972,14 @@ void smc_close_non_accepted(struct sock *sk)
970972
{
971973
struct smc_sock *smc = smc_sk(sk);
972974

975+
sock_hold(sk); /* sock_put below */
973976
lock_sock(sk);
974977
if (!sk->sk_lingertime)
975978
/* wait for peer closing */
976979
sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
977980
__smc_release(smc);
978981
release_sock(sk);
982+
sock_put(sk); /* sock_hold above */
979983
sock_put(sk); /* final sock_put */
980984
}
981985

net/smc/smc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ struct smc_connection {
188188
* 0 for SMC-R, 32 for SMC-D
189189
*/
190190
u64 peer_token; /* SMC-D token of peer */
191+
u8 killed : 1; /* abnormal termination */
191192
};
192193

193194
struct smc_sock { /* smc sock container */

net/smc/smc_cdc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ int smc_cdc_get_free_slot(struct smc_connection *conn,
6363
rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
6464
wr_rdma_buf,
6565
(struct smc_wr_tx_pend_priv **)pend);
66-
if (!conn->alert_token_local)
66+
if (conn->killed)
6767
/* abnormal termination */
6868
rc = -EPIPE;
6969
return rc;
@@ -328,7 +328,7 @@ static void smcd_cdc_rx_tsklet(unsigned long data)
328328
struct smcd_cdc_msg cdc;
329329
struct smc_sock *smc;
330330

331-
if (!conn)
331+
if (!conn || conn->killed)
332332
return;
333333

334334
data_cdc = (struct smcd_cdc_msg *)conn->rmb_desc->cpu_addr;

net/smc/smc_close.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/sched/signal.h>
1414

1515
#include <net/sock.h>
16+
#include <net/tcp.h>
1617

1718
#include "smc.h"
1819
#include "smc_tx.h"
@@ -66,7 +67,8 @@ static void smc_close_stream_wait(struct smc_sock *smc, long timeout)
6667
rc = sk_wait_event(sk, &timeout,
6768
!smc_tx_prepared_sends(&smc->conn) ||
6869
sk->sk_err == ECONNABORTED ||
69-
sk->sk_err == ECONNRESET,
70+
sk->sk_err == ECONNRESET ||
71+
smc->conn.killed,
7072
&wait);
7173
if (rc)
7274
break;
@@ -95,11 +97,13 @@ static int smc_close_final(struct smc_connection *conn)
9597
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
9698
else
9799
conn->local_tx_ctrl.conn_state_flags.peer_conn_closed = 1;
100+
if (conn->killed)
101+
return -EPIPE;
98102

99103
return smc_cdc_get_slot_and_msg_send(conn);
100104
}
101105

102-
static int smc_close_abort(struct smc_connection *conn)
106+
int smc_close_abort(struct smc_connection *conn)
103107
{
104108
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
105109

@@ -109,16 +113,15 @@ static int smc_close_abort(struct smc_connection *conn)
109113
/* terminate smc socket abnormally - active abort
110114
* link group is terminated, i.e. RDMA communication no longer possible
111115
*/
112-
static void smc_close_active_abort(struct smc_sock *smc)
116+
void smc_close_active_abort(struct smc_sock *smc)
113117
{
114118
struct sock *sk = &smc->sk;
119+
bool release_clcsock = false;
115120

116121
if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
117122
sk->sk_err = ECONNABORTED;
118-
if (smc->clcsock && smc->clcsock->sk) {
119-
smc->clcsock->sk->sk_err = ECONNABORTED;
120-
smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
121-
}
123+
if (smc->clcsock && smc->clcsock->sk)
124+
tcp_abort(smc->clcsock->sk, ECONNABORTED);
122125
}
123126
switch (sk->sk_state) {
124127
case SMC_ACTIVE:
@@ -135,11 +138,14 @@ static void smc_close_active_abort(struct smc_sock *smc)
135138
cancel_delayed_work_sync(&smc->conn.tx_work);
136139
lock_sock(sk);
137140
sk->sk_state = SMC_CLOSED;
141+
sock_put(sk); /* postponed passive closing */
138142
break;
139143
case SMC_PEERCLOSEWAIT1:
140144
case SMC_PEERCLOSEWAIT2:
141145
case SMC_PEERFINCLOSEWAIT:
142146
sk->sk_state = SMC_CLOSED;
147+
smc_conn_free(&smc->conn);
148+
release_clcsock = true;
143149
sock_put(sk); /* passive closing */
144150
break;
145151
case SMC_PROCESSABORT:
@@ -154,6 +160,12 @@ static void smc_close_active_abort(struct smc_sock *smc)
154160

155161
sock_set_flag(sk, SOCK_DEAD);
156162
sk->sk_state_change(sk);
163+
164+
if (release_clcsock) {
165+
release_sock(sk);
166+
smc_clcsock_release(smc);
167+
lock_sock(sk);
168+
}
157169
}
158170

159171
static inline bool smc_close_sent_any_close(struct smc_connection *conn)
@@ -326,12 +338,6 @@ static void smc_close_passive_work(struct work_struct *work)
326338
lock_sock(sk);
327339
old_state = sk->sk_state;
328340

329-
if (!conn->alert_token_local) {
330-
/* abnormal termination */
331-
smc_close_active_abort(smc);
332-
goto wakeup;
333-
}
334-
335341
rxflags = &conn->local_rx_ctrl.conn_state_flags;
336342
if (rxflags->peer_conn_abort) {
337343
/* peer has not received all data */

net/smc/smc_close.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ int smc_close_active(struct smc_sock *smc);
2424
int smc_close_shutdown_write(struct smc_sock *smc);
2525
void smc_close_init(struct smc_sock *smc);
2626
void smc_clcsock_release(struct smc_sock *smc);
27+
int smc_close_abort(struct smc_connection *conn);
28+
void smc_close_active_abort(struct smc_sock *smc);
2729

2830
#endif /* SMC_CLOSE_H */

0 commit comments

Comments
 (0)