Skip to content

Commit bfd4b32

Browse files
committed
Merge branch 'net-smc-more-socket-closing-improvements'
Ursula Braun says: ==================== net/smc: more socket closing improvements these patches improve the smc behavior for abnormal socket closing. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2611df7 + 1a0a04c commit bfd4b32

File tree

7 files changed

+83
-31
lines changed

7 files changed

+83
-31
lines changed

net/smc/af_smc.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,15 @@ static void smc_link_save_peer_info(struct smc_link *link,
377377
link->peer_mtu = clc->qp_mtu;
378378
}
379379

380+
static void smc_lgr_forget(struct smc_link_group *lgr)
381+
{
382+
spin_lock_bh(&smc_lgr_list.lock);
383+
/* do not use this link group for new connections */
384+
if (!list_empty(&lgr->list))
385+
list_del_init(&lgr->list);
386+
spin_unlock_bh(&smc_lgr_list.lock);
387+
}
388+
380389
/* setup for RDMA connection of client */
381390
static int smc_connect_rdma(struct smc_sock *smc)
382391
{
@@ -513,6 +522,8 @@ static int smc_connect_rdma(struct smc_sock *smc)
513522
return rc ? rc : local_contact;
514523

515524
decline_rdma_unlock:
525+
if (local_contact == SMC_FIRST_CONTACT)
526+
smc_lgr_forget(smc->conn.lgr);
516527
mutex_unlock(&smc_create_lgr_pending);
517528
smc_conn_free(&smc->conn);
518529
decline_rdma:
@@ -526,6 +537,8 @@ static int smc_connect_rdma(struct smc_sock *smc)
526537
goto out_connected;
527538

528539
out_err_unlock:
540+
if (local_contact == SMC_FIRST_CONTACT)
541+
smc_lgr_forget(smc->conn.lgr);
529542
mutex_unlock(&smc_create_lgr_pending);
530543
smc_conn_free(&smc->conn);
531544
out_err:
@@ -906,6 +919,8 @@ static void smc_listen_work(struct work_struct *work)
906919
return;
907920

908921
decline_rdma_unlock:
922+
if (local_contact == SMC_FIRST_CONTACT)
923+
smc_lgr_forget(new_smc->conn.lgr);
909924
mutex_unlock(&smc_create_lgr_pending);
910925
decline_rdma:
911926
/* RDMA setup failed, switch back to TCP */
@@ -918,6 +933,8 @@ static void smc_listen_work(struct work_struct *work)
918933
goto out_connected;
919934

920935
out_err_unlock:
936+
if (local_contact == SMC_FIRST_CONTACT)
937+
smc_lgr_forget(new_smc->conn.lgr);
921938
mutex_unlock(&smc_create_lgr_pending);
922939
out_err:
923940
newsmcsk->sk_state = SMC_CLOSED;

net/smc/smc_cdc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,14 @@ int smc_cdc_get_free_slot(struct smc_connection *conn,
6565
struct smc_cdc_tx_pend **pend)
6666
{
6767
struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
68+
int rc;
6869

69-
return smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
70-
(struct smc_wr_tx_pend_priv **)pend);
70+
rc = smc_wr_tx_get_free_slot(link, smc_cdc_tx_handler, wr_buf,
71+
(struct smc_wr_tx_pend_priv **)pend);
72+
if (!conn->alert_token_local)
73+
/* abnormal termination */
74+
rc = -EPIPE;
75+
return rc;
7176
}
7277

7378
static inline void smc_cdc_add_pending_send(struct smc_connection *conn,

net/smc/smc_close.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static int smc_close_abort(struct smc_connection *conn)
8989
}
9090

9191
/* terminate smc socket abnormally - active abort
92-
* RDMA communication no longer possible
92+
* link group is terminated, i.e. RDMA communication no longer possible
9393
*/
9494
static void smc_close_active_abort(struct smc_sock *smc)
9595
{
@@ -107,32 +107,34 @@ static void smc_close_active_abort(struct smc_sock *smc)
107107
case SMC_INIT:
108108
case SMC_ACTIVE:
109109
sk->sk_state = SMC_PEERABORTWAIT;
110+
release_sock(sk);
111+
cancel_delayed_work_sync(&smc->conn.tx_work);
112+
lock_sock(sk);
110113
break;
111114
case SMC_APPCLOSEWAIT1:
112115
case SMC_APPCLOSEWAIT2:
113-
txflags->peer_conn_abort = 1;
114116
sock_release(smc->clcsock);
115117
if (!smc_cdc_rxed_any_close(&smc->conn))
116118
sk->sk_state = SMC_PEERABORTWAIT;
117119
else
118120
sk->sk_state = SMC_CLOSED;
121+
release_sock(sk);
122+
cancel_delayed_work_sync(&smc->conn.tx_work);
123+
lock_sock(sk);
119124
break;
120125
case SMC_PEERCLOSEWAIT1:
121126
case SMC_PEERCLOSEWAIT2:
122127
if (!txflags->peer_conn_closed) {
123128
sk->sk_state = SMC_PEERABORTWAIT;
124-
txflags->peer_conn_abort = 1;
125129
sock_release(smc->clcsock);
126130
} else {
127131
sk->sk_state = SMC_CLOSED;
128132
}
129133
break;
130134
case SMC_PROCESSABORT:
131135
case SMC_APPFINCLOSEWAIT:
132-
if (!txflags->peer_conn_closed) {
133-
txflags->peer_conn_abort = 1;
136+
if (!txflags->peer_conn_closed)
134137
sock_release(smc->clcsock);
135-
}
136138
sk->sk_state = SMC_CLOSED;
137139
break;
138140
case SMC_PEERFINCLOSEWAIT:
@@ -249,9 +251,6 @@ int smc_close_active(struct smc_sock *smc)
249251
/* peer sending PeerConnectionClosed will cause transition */
250252
break;
251253
case SMC_PROCESSABORT:
252-
release_sock(sk);
253-
cancel_delayed_work_sync(&conn->tx_work);
254-
lock_sock(sk);
255254
smc_close_abort(conn);
256255
sk->sk_state = SMC_CLOSED;
257256
break;
@@ -277,15 +276,13 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
277276
case SMC_APPFINCLOSEWAIT:
278277
case SMC_APPCLOSEWAIT1:
279278
case SMC_APPCLOSEWAIT2:
280-
smc_close_abort(&smc->conn);
281279
sk->sk_state = SMC_PROCESSABORT;
282280
break;
283281
case SMC_PEERCLOSEWAIT1:
284282
case SMC_PEERCLOSEWAIT2:
285283
if (txflags->peer_done_writing &&
286284
!smc_close_sent_any_close(&smc->conn)) {
287285
/* just shutdown, but not yet closed locally */
288-
smc_close_abort(&smc->conn);
289286
sk->sk_state = SMC_PROCESSABORT;
290287
} else {
291288
sk->sk_state = SMC_CLOSED;
@@ -302,8 +299,9 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
302299
}
303300
}
304301

305-
/* Some kind of closing has been received: peer_conn_closed, peer_conn_abort,
306-
* or peer_done_writing.
302+
/* Either some kind of closing has been received: peer_conn_closed,
303+
* peer_conn_abort, or peer_done_writing
304+
* or the link group of the connection terminates abnormally.
307305
*/
308306
static void smc_close_passive_work(struct work_struct *work)
309307
{
@@ -326,7 +324,11 @@ static void smc_close_passive_work(struct work_struct *work)
326324

327325
rxflags = &conn->local_rx_ctrl.conn_state_flags;
328326
if (rxflags->peer_conn_abort) {
327+
/* peer has not received all data */
329328
smc_close_passive_abort_received(smc);
329+
release_sock(&smc->sk);
330+
cancel_delayed_work_sync(&conn->tx_work);
331+
lock_sock(&smc->sk);
330332
goto wakeup;
331333
}
332334

@@ -348,7 +350,6 @@ static void smc_close_passive_work(struct work_struct *work)
348350
/* fall through */
349351
/* to check for closing */
350352
case SMC_PEERCLOSEWAIT2:
351-
case SMC_PEERFINCLOSEWAIT:
352353
if (!smc_cdc_rxed_any_close(conn))
353354
break;
354355
if (sock_flag(sk, SOCK_DEAD) &&
@@ -360,6 +361,10 @@ static void smc_close_passive_work(struct work_struct *work)
360361
sk->sk_state = SMC_APPFINCLOSEWAIT;
361362
}
362363
break;
364+
case SMC_PEERFINCLOSEWAIT:
365+
if (smc_cdc_rxed_any_close(conn))
366+
sk->sk_state = SMC_CLOSED;
367+
break;
363368
case SMC_APPCLOSEWAIT1:
364369
case SMC_APPCLOSEWAIT2:
365370
case SMC_APPFINCLOSEWAIT:

net/smc/smc_core.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ static void smc_lgr_free_work(struct work_struct *work)
128128
bool conns;
129129

130130
spin_lock_bh(&smc_lgr_list.lock);
131+
if (list_empty(&lgr->list))
132+
goto free;
131133
read_lock_bh(&lgr->conns_lock);
132134
conns = RB_EMPTY_ROOT(&lgr->conns_all);
133135
read_unlock_bh(&lgr->conns_lock);
@@ -136,6 +138,7 @@ static void smc_lgr_free_work(struct work_struct *work)
136138
return;
137139
}
138140
list_del_init(&lgr->list); /* remove from smc_lgr_list */
141+
free:
139142
spin_unlock_bh(&smc_lgr_list.lock);
140143
smc_lgr_free(lgr);
141144
}
@@ -231,9 +234,7 @@ static void smc_buf_unuse(struct smc_connection *conn)
231234
/* remove a finished connection from its link group */
232235
void smc_conn_free(struct smc_connection *conn)
233236
{
234-
struct smc_link_group *lgr = conn->lgr;
235-
236-
if (!lgr)
237+
if (!conn->lgr)
237238
return;
238239
smc_cdc_tx_dismiss_slots(conn);
239240
smc_lgr_unregister_conn(conn);
@@ -328,12 +329,16 @@ void smc_lgr_terminate(struct smc_link_group *lgr)
328329
conn = rb_entry(node, struct smc_connection, alert_node);
329330
smc = container_of(conn, struct smc_sock, conn);
330331
sock_hold(&smc->sk);
332+
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
331333
__smc_lgr_unregister_conn(conn);
334+
write_unlock_bh(&lgr->conns_lock);
332335
schedule_work(&conn->close_work);
336+
write_lock_bh(&lgr->conns_lock);
333337
sock_put(&smc->sk);
334338
node = rb_first(&lgr->conns_all);
335339
}
336340
write_unlock_bh(&lgr->conns_lock);
341+
wake_up(&lgr->lnk[SMC_SINGLE_LINK].wr_reg_wait);
337342
}
338343

339344
/* Determine vlan of internal TCP socket.

net/smc/smc_diag.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
8686
if (smc_diag_msg_attrs_fill(sk, skb, r, user_ns))
8787
goto errout;
8888

89-
if ((req->diag_ext & (1 << (SMC_DIAG_CONNINFO - 1))) && smc->conn.lgr) {
89+
if ((req->diag_ext & (1 << (SMC_DIAG_CONNINFO - 1))) &&
90+
smc->conn.alert_token_local) {
9091
struct smc_connection *conn = &smc->conn;
9192
struct smc_diag_conninfo cinfo = {
9293
.token = conn->alert_token_local,
@@ -124,7 +125,8 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
124125
goto errout;
125126
}
126127

127-
if ((req->diag_ext & (1 << (SMC_DIAG_LGRINFO - 1))) && smc->conn.lgr) {
128+
if ((req->diag_ext & (1 << (SMC_DIAG_LGRINFO - 1))) && smc->conn.lgr &&
129+
!list_empty(&smc->conn.lgr->list)) {
128130
struct smc_diag_lgrinfo linfo = {
129131
.role = smc->conn.lgr->role,
130132
.lnk[0].ibport = smc->conn.lgr->lnk[0].ibport,

net/smc/smc_tx.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,10 @@ static int smc_tx_rdma_write(struct smc_connection *conn, int peer_rmbe_offset,
248248
peer_rmbe_offset;
249249
rdma_wr.rkey = lgr->rtokens[conn->rtoken_idx][SMC_SINGLE_LINK].rkey;
250250
rc = ib_post_send(link->roce_qp, &rdma_wr.wr, &failed_wr);
251-
if (rc)
251+
if (rc) {
252252
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
253+
smc_lgr_terminate(lgr);
254+
}
253255
return rc;
254256
}
255257

@@ -406,8 +408,9 @@ int smc_tx_sndbuf_nonempty(struct smc_connection *conn)
406408
goto out_unlock;
407409
}
408410
rc = 0;
409-
schedule_delayed_work(&conn->tx_work,
410-
SMC_TX_WORK_DELAY);
411+
if (conn->alert_token_local) /* connection healthy */
412+
schedule_delayed_work(&conn->tx_work,
413+
SMC_TX_WORK_DELAY);
411414
}
412415
goto out_unlock;
413416
}
@@ -438,10 +441,17 @@ static void smc_tx_work(struct work_struct *work)
438441
int rc;
439442

440443
lock_sock(&smc->sk);
444+
if (smc->sk.sk_err ||
445+
!conn->alert_token_local ||
446+
conn->local_rx_ctrl.conn_state_flags.peer_conn_abort)
447+
goto out;
448+
441449
rc = smc_tx_sndbuf_nonempty(conn);
442450
if (!rc && conn->local_rx_ctrl.prod_flags.write_blocked &&
443451
!atomic_read(&conn->bytes_to_rcv))
444452
conn->local_rx_ctrl.prod_flags.write_blocked = 0;
453+
454+
out:
445455
release_sock(&smc->sk);
446456
}
447457

@@ -462,7 +472,8 @@ void smc_tx_consumer_update(struct smc_connection *conn)
462472
((to_confirm > conn->rmbe_update_limit) &&
463473
((to_confirm > (conn->rmbe_size / 2)) ||
464474
conn->local_rx_ctrl.prod_flags.write_blocked))) {
465-
if (smc_cdc_get_slot_and_msg_send(conn) < 0) {
475+
if ((smc_cdc_get_slot_and_msg_send(conn) < 0) &&
476+
conn->alert_token_local) { /* connection healthy */
466477
schedule_delayed_work(&conn->tx_work,
467478
SMC_TX_WORK_DELAY);
468479
return;

net/smc/smc_wr.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
174174
struct smc_wr_tx_pend_priv **wr_pend_priv)
175175
{
176176
struct smc_wr_tx_pend *wr_pend;
177+
u32 idx = link->wr_tx_cnt;
177178
struct ib_send_wr *wr_ib;
178179
u64 wr_id;
179-
u32 idx;
180180
int rc;
181181

182182
*wr_buf = NULL;
@@ -186,16 +186,17 @@ int smc_wr_tx_get_free_slot(struct smc_link *link,
186186
if (rc)
187187
return rc;
188188
} else {
189+
struct smc_link_group *lgr;
190+
191+
lgr = container_of(link, struct smc_link_group,
192+
lnk[SMC_SINGLE_LINK]);
189193
rc = wait_event_timeout(
190194
link->wr_tx_wait,
195+
list_empty(&lgr->list) || /* lgr terminated */
191196
(smc_wr_tx_get_free_slot_index(link, &idx) != -EBUSY),
192197
SMC_WR_TX_WAIT_FREE_SLOT_TIME);
193198
if (!rc) {
194199
/* timeout - terminate connections */
195-
struct smc_link_group *lgr;
196-
197-
lgr = container_of(link, struct smc_link_group,
198-
lnk[SMC_SINGLE_LINK]);
199200
smc_lgr_terminate(lgr);
200201
return -EPIPE;
201202
}
@@ -248,8 +249,14 @@ int smc_wr_tx_send(struct smc_link *link, struct smc_wr_tx_pend_priv *priv)
248249
pend = container_of(priv, struct smc_wr_tx_pend, priv);
249250
rc = ib_post_send(link->roce_qp, &link->wr_tx_ibs[pend->idx],
250251
&failed_wr);
251-
if (rc)
252+
if (rc) {
253+
struct smc_link_group *lgr =
254+
container_of(link, struct smc_link_group,
255+
lnk[SMC_SINGLE_LINK]);
256+
252257
smc_wr_tx_put_slot(link, priv);
258+
smc_lgr_terminate(lgr);
259+
}
253260
return rc;
254261
}
255262

0 commit comments

Comments
 (0)