Skip to content

Commit b38d732

Browse files
Ursula Braundavem330
Ursula Braun
authored andcommitted
smc: socket closing and linkgroup cleanup
smc_shutdown() and smc_release() handling delayed linkgroup cleanup for linkgroups without connections Signed-off-by: Ursula Braun <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 952310c commit b38d732

11 files changed

+668
-36
lines changed

net/smc/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
obj-$(CONFIG_SMC) += smc.o
22
smc-y := af_smc.o smc_pnet.o smc_ib.o smc_clc.o smc_core.o smc_wr.o smc_llc.o
3-
smc-y += smc_cdc.o smc_tx.o smc_rx.o
3+
smc-y += smc_cdc.o smc_tx.o smc_rx.o smc_close.o

net/smc/af_smc.c

+105-22
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "smc_pnet.h"
4040
#include "smc_tx.h"
4141
#include "smc_rx.h"
42+
#include "smc_close.h"
4243

4344
static DEFINE_MUTEX(smc_create_lgr_pending); /* serialize link group
4445
* creation
@@ -70,14 +71,29 @@ static int smc_release(struct socket *sock)
7071
{
7172
struct sock *sk = sock->sk;
7273
struct smc_sock *smc;
74+
int rc = 0;
7375

7476
if (!sk)
7577
goto out;
7678

7779
smc = smc_sk(sk);
78-
lock_sock(sk);
80+
sock_hold(sk);
81+
if (sk->sk_state == SMC_LISTEN)
82+
/* smc_close_non_accepted() is called and acquires
83+
* sock lock for child sockets again
84+
*/
85+
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
86+
else
87+
lock_sock(sk);
7988

80-
sk->sk_state = SMC_CLOSED;
89+
if (smc->use_fallback) {
90+
sk->sk_state = SMC_CLOSED;
91+
sk->sk_state_change(sk);
92+
} else {
93+
rc = smc_close_active(smc);
94+
sock_set_flag(sk, SOCK_DEAD);
95+
sk->sk_shutdown |= SHUTDOWN_MASK;
96+
}
8197
if (smc->clcsock) {
8298
sock_release(smc->clcsock);
8399
smc->clcsock = NULL;
@@ -86,11 +102,18 @@ static int smc_release(struct socket *sock)
86102
/* detach socket */
87103
sock_orphan(sk);
88104
sock->sk = NULL;
105+
if (smc->use_fallback) {
106+
schedule_delayed_work(&smc->sock_put_work, TCP_TIMEWAIT_LEN);
107+
} else if (sk->sk_state == SMC_CLOSED) {
108+
smc_conn_free(&smc->conn);
109+
schedule_delayed_work(&smc->sock_put_work,
110+
SMC_CLOSE_SOCK_PUT_DELAY);
111+
}
89112
release_sock(sk);
90113

91114
sock_put(sk);
92115
out:
93-
return 0;
116+
return rc;
94117
}
95118

96119
static void smc_destruct(struct sock *sk)
@@ -120,6 +143,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock)
120143
INIT_WORK(&smc->tcp_listen_work, smc_tcp_listen_work);
121144
INIT_LIST_HEAD(&smc->accept_q);
122145
spin_lock_init(&smc->accept_q_lock);
146+
INIT_DELAYED_WORK(&smc->sock_put_work, smc_close_sock_put_work);
123147
sk_refcnt_debug_inc(sk);
124148

125149
return sk;
@@ -417,7 +441,8 @@ static int smc_connect_rdma(struct smc_sock *smc)
417441

418442
out_connected:
419443
smc_copy_sock_settings_to_clc(smc);
420-
smc->sk.sk_state = SMC_ACTIVE;
444+
if (smc->sk.sk_state == SMC_INIT)
445+
smc->sk.sk_state = SMC_ACTIVE;
421446

422447
return rc ? rc : local_contact;
423448

@@ -559,8 +584,8 @@ static void smc_accept_unlink(struct sock *sk)
559584
/* remove a sock from the accept queue to bind it to a new socket created
560585
* for a socket accept call from user space
561586
*/
562-
static struct sock *smc_accept_dequeue(struct sock *parent,
563-
struct socket *new_sock)
587+
struct sock *smc_accept_dequeue(struct sock *parent,
588+
struct socket *new_sock)
564589
{
565590
struct smc_sock *isk, *n;
566591
struct sock *new_sk;
@@ -581,19 +606,34 @@ static struct sock *smc_accept_dequeue(struct sock *parent,
581606
}
582607

583608
/* clean up for a created but never accepted sock */
584-
static void smc_close_non_accepted(struct sock *sk)
609+
void smc_close_non_accepted(struct sock *sk)
585610
{
586611
struct smc_sock *smc = smc_sk(sk);
587612

588613
sock_hold(sk);
614+
lock_sock(sk);
615+
if (!sk->sk_lingertime)
616+
/* wait for peer closing */
617+
sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
618+
if (!smc->use_fallback)
619+
smc_close_active(smc);
589620
if (smc->clcsock) {
590621
struct socket *tcp;
591622

592623
tcp = smc->clcsock;
593624
smc->clcsock = NULL;
594625
sock_release(tcp);
595626
}
596-
/* more closing stuff to be added with socket closing patch */
627+
sock_set_flag(sk, SOCK_DEAD);
628+
sk->sk_shutdown |= SHUTDOWN_MASK;
629+
if (smc->use_fallback) {
630+
schedule_delayed_work(&smc->sock_put_work, TCP_TIMEWAIT_LEN);
631+
} else {
632+
smc_conn_free(&smc->conn);
633+
schedule_delayed_work(&smc->sock_put_work,
634+
SMC_CLOSE_SOCK_PUT_DELAY);
635+
}
636+
release_sock(sk);
597637
sock_put(sk);
598638
}
599639

@@ -761,11 +801,12 @@ static void smc_listen_work(struct work_struct *work)
761801

762802
out_connected:
763803
sk_refcnt_debug_inc(newsmcsk);
764-
newsmcsk->sk_state = SMC_ACTIVE;
804+
if (newsmcsk->sk_state == SMC_INIT)
805+
newsmcsk->sk_state = SMC_ACTIVE;
765806
enqueue:
766807
if (local_contact == SMC_FIRST_CONTACT)
767808
mutex_unlock(&smc_create_lgr_pending);
768-
lock_sock(&lsmc->sk);
809+
lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING);
769810
if (lsmc->sk.sk_state == SMC_LISTEN) {
770811
smc_accept_enqueue(&lsmc->sk, newsmcsk);
771812
} else { /* no longer listening */
@@ -791,6 +832,7 @@ static void smc_listen_work(struct work_struct *work)
791832

792833
out_err:
793834
newsmcsk->sk_state = SMC_CLOSED;
835+
smc_conn_free(&new_smc->conn);
794836
goto enqueue; /* queue new sock with sk_err set */
795837
}
796838

@@ -911,7 +953,8 @@ static int smc_getname(struct socket *sock, struct sockaddr *addr,
911953
{
912954
struct smc_sock *smc;
913955

914-
if (peer && (sock->sk->sk_state != SMC_ACTIVE))
956+
if (peer && (sock->sk->sk_state != SMC_ACTIVE) &&
957+
(sock->sk->sk_state != SMC_APPCLOSEWAIT1))
915958
return -ENOTCONN;
916959

917960
smc = smc_sk(sock->sk);
@@ -927,7 +970,9 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
927970

928971
smc = smc_sk(sk);
929972
lock_sock(sk);
930-
if (sk->sk_state != SMC_ACTIVE)
973+
if ((sk->sk_state != SMC_ACTIVE) &&
974+
(sk->sk_state != SMC_APPCLOSEWAIT1) &&
975+
(sk->sk_state != SMC_INIT))
931976
goto out;
932977
if (smc->use_fallback)
933978
rc = smc->clcsock->ops->sendmsg(smc->clcsock, msg, len);
@@ -947,13 +992,21 @@ static int smc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
947992

948993
smc = smc_sk(sk);
949994
lock_sock(sk);
950-
if ((sk->sk_state != SMC_ACTIVE) && (sk->sk_state != SMC_CLOSED))
995+
if ((sk->sk_state == SMC_INIT) ||
996+
(sk->sk_state == SMC_LISTEN) ||
997+
(sk->sk_state == SMC_CLOSED))
998+
goto out;
999+
1000+
if (sk->sk_state == SMC_PEERFINCLOSEWAIT) {
1001+
rc = 0;
9511002
goto out;
1003+
}
9521004

9531005
if (smc->use_fallback)
9541006
rc = smc->clcsock->ops->recvmsg(smc->clcsock, msg, len, flags);
9551007
else
9561008
rc = smc_rx_recvmsg(smc, msg, len, flags);
1009+
9571010
out:
9581011
release_sock(sk);
9591012
return rc;
@@ -1013,15 +1066,23 @@ static unsigned int smc_poll(struct file *file, struct socket *sock,
10131066
mask |= smc_accept_poll(sk);
10141067
if (sk->sk_err)
10151068
mask |= POLLERR;
1016-
if (atomic_read(&smc->conn.sndbuf_space)) {
1069+
if (atomic_read(&smc->conn.sndbuf_space) ||
1070+
(sk->sk_shutdown & SEND_SHUTDOWN)) {
10171071
mask |= POLLOUT | POLLWRNORM;
10181072
} else {
10191073
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
10201074
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
10211075
}
10221076
if (atomic_read(&smc->conn.bytes_to_rcv))
10231077
mask |= POLLIN | POLLRDNORM;
1024-
/* for now - to be enhanced in follow-on patch */
1078+
if ((sk->sk_shutdown == SHUTDOWN_MASK) ||
1079+
(sk->sk_state == SMC_CLOSED))
1080+
mask |= POLLHUP;
1081+
if (sk->sk_shutdown & RCV_SHUTDOWN)
1082+
mask |= POLLIN | POLLRDNORM | POLLRDHUP;
1083+
if (sk->sk_state == SMC_APPCLOSEWAIT1)
1084+
mask |= POLLIN;
1085+
10251086
}
10261087

10271088
return mask;
@@ -1032,31 +1093,53 @@ static int smc_shutdown(struct socket *sock, int how)
10321093
struct sock *sk = sock->sk;
10331094
struct smc_sock *smc;
10341095
int rc = -EINVAL;
1096+
int rc1 = 0;
10351097

10361098
smc = smc_sk(sk);
10371099

10381100
if ((how < SHUT_RD) || (how > SHUT_RDWR))
1039-
goto out_err;
1101+
return rc;
10401102

10411103
lock_sock(sk);
10421104

10431105
rc = -ENOTCONN;
1044-
if (sk->sk_state == SMC_CLOSED)
1106+
if ((sk->sk_state != SMC_LISTEN) &&
1107+
(sk->sk_state != SMC_ACTIVE) &&
1108+
(sk->sk_state != SMC_PEERCLOSEWAIT1) &&
1109+
(sk->sk_state != SMC_PEERCLOSEWAIT2) &&
1110+
(sk->sk_state != SMC_APPCLOSEWAIT1) &&
1111+
(sk->sk_state != SMC_APPCLOSEWAIT2) &&
1112+
(sk->sk_state != SMC_APPFINCLOSEWAIT))
10451113
goto out;
10461114
if (smc->use_fallback) {
10471115
rc = kernel_sock_shutdown(smc->clcsock, how);
10481116
sk->sk_shutdown = smc->clcsock->sk->sk_shutdown;
10491117
if (sk->sk_shutdown == SHUTDOWN_MASK)
10501118
sk->sk_state = SMC_CLOSED;
1051-
} else {
1052-
rc = sock_no_shutdown(sock, how);
1119+
goto out;
1120+
}
1121+
switch (how) {
1122+
case SHUT_RDWR: /* shutdown in both directions */
1123+
rc = smc_close_active(smc);
1124+
break;
1125+
case SHUT_WR:
1126+
rc = smc_close_shutdown_write(smc);
1127+
break;
1128+
case SHUT_RD:
1129+
if (sk->sk_state == SMC_LISTEN)
1130+
rc = smc_close_active(smc);
1131+
else
1132+
rc = 0;
1133+
/* nothing more to do because peer is not involved */
1134+
break;
10531135
}
1136+
rc1 = kernel_sock_shutdown(smc->clcsock, how);
1137+
/* map sock_shutdown_cmd constants to sk_shutdown value range */
1138+
sk->sk_shutdown |= how + 1;
10541139

10551140
out:
10561141
release_sock(sk);
1057-
1058-
out_err:
1059-
return rc;
1142+
return rc ? rc : rc1;
10601143
}
10611144

10621145
static int smc_setsockopt(struct socket *sock, int level, int optname,

net/smc/smc.h

+18
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ enum smc_state { /* possible states of an SMC socket */
3030
SMC_INIT = 2,
3131
SMC_CLOSED = 7,
3232
SMC_LISTEN = 10,
33+
/* normal close */
34+
SMC_PEERCLOSEWAIT1 = 20,
35+
SMC_PEERCLOSEWAIT2 = 21,
36+
SMC_APPFINCLOSEWAIT = 24,
37+
SMC_APPCLOSEWAIT1 = 22,
38+
SMC_APPCLOSEWAIT2 = 23,
39+
SMC_PEERFINCLOSEWAIT = 25,
40+
/* abnormal close */
41+
SMC_PEERABORTWAIT = 26,
42+
SMC_PROCESSABORT = 27,
3343
};
3444

3545
struct smc_link_group;
@@ -164,7 +174,13 @@ struct smc_sock { /* smc sock container */
164174
struct work_struct smc_listen_work;/* prepare new accept socket */
165175
struct list_head accept_q; /* sockets to be accepted */
166176
spinlock_t accept_q_lock; /* protects accept_q */
177+
struct delayed_work sock_put_work; /* final socket freeing */
167178
bool use_fallback; /* fallback to tcp */
179+
u8 wait_close_tx_prepared : 1;
180+
/* shutdown wr or close
181+
* started, waiting for unsent
182+
* data to be sent
183+
*/
168184
};
169185

170186
static inline struct smc_sock *smc_sk(const struct sock *sk)
@@ -250,5 +266,7 @@ void smc_conn_free(struct smc_connection *conn);
250266
int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr,
251267
struct smc_ib_device *smcibdev, u8 ibport,
252268
struct smc_clc_msg_local *lcl, int srv_first_contact);
269+
struct sock *smc_accept_dequeue(struct sock *parent, struct socket *new_sock);
270+
void smc_close_non_accepted(struct sock *sk);
253271

254272
#endif /* __SMC_H */

net/smc/smc_cdc.c

+20-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "smc_cdc.h"
1717
#include "smc_tx.h"
1818
#include "smc_rx.h"
19+
#include "smc_close.h"
1920

2021
/********************************** send *************************************/
2122

@@ -55,6 +56,9 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
5556
cdcpend->conn);
5657
}
5758
smc_tx_sndbuf_nonfull(smc);
59+
if (smc->sk.sk_state != SMC_ACTIVE)
60+
/* wake up smc_close_wait_tx_pends() */
61+
smc->sk.sk_state_change(&smc->sk);
5862
bh_unlock_sock(&smc->sk);
5963
}
6064

@@ -149,6 +153,14 @@ void smc_cdc_tx_dismiss_slots(struct smc_connection *conn)
149153
(unsigned long)conn);
150154
}
151155

156+
bool smc_cdc_tx_has_pending(struct smc_connection *conn)
157+
{
158+
struct smc_link *link = &conn->lgr->lnk[SMC_SINGLE_LINK];
159+
160+
return smc_wr_tx_has_pending(link, SMC_CDC_MSG_TYPE,
161+
smc_cdc_tx_filter, (unsigned long)conn);
162+
}
163+
152164
/********************************* receive ***********************************/
153165

154166
static inline bool smc_cdc_before(u16 seq1, u16 seq2)
@@ -201,15 +213,20 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
201213
smc->sk.sk_data_ready(&smc->sk);
202214
}
203215

204-
if (conn->local_rx_ctrl.conn_state_flags.peer_conn_abort)
216+
if (conn->local_rx_ctrl.conn_state_flags.peer_conn_abort) {
205217
smc->sk.sk_err = ECONNRESET;
218+
conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
219+
}
206220
if (smc_cdc_rxed_any_close_or_senddone(conn))
207-
/* subsequent patch: terminate connection */
221+
smc_close_passive_received(smc);
208222

209223
/* piggy backed tx info */
210224
/* trigger sndbuf consumer: RDMA write into peer RMBE and CDC */
211-
if (diff_cons && smc_tx_prepared_sends(conn))
225+
if (diff_cons && smc_tx_prepared_sends(conn)) {
212226
smc_tx_sndbuf_nonempty(conn);
227+
/* trigger socket release if connection closed */
228+
smc_close_wake_tx_prepared(smc);
229+
}
213230

214231
/* subsequent patch: trigger socket release if connection closed */
215232

net/smc/smc_cdc.h

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ void smc_cdc_tx_dismiss_slots(struct smc_connection *conn);
212212
int smc_cdc_msg_send(struct smc_connection *conn, struct smc_wr_buf *wr_buf,
213213
struct smc_cdc_tx_pend *pend);
214214
int smc_cdc_get_slot_and_msg_send(struct smc_connection *conn);
215+
bool smc_cdc_tx_has_pending(struct smc_connection *conn);
215216
int smc_cdc_init(void) __init;
216217

217218
#endif /* SMC_CDC_H */

0 commit comments

Comments
 (0)