@@ -117,14 +117,14 @@ void smc_close_active_abort(struct smc_sock *smc)
117117 struct smc_cdc_conn_state_flags * txflags =
118118 & smc -> conn .local_tx_ctrl .conn_state_flags ;
119119
120- bh_lock_sock (& smc -> sk );
121120 smc -> sk .sk_err = ECONNABORTED ;
122121 if (smc -> clcsock && smc -> clcsock -> sk ) {
123122 smc -> clcsock -> sk -> sk_err = ECONNABORTED ;
124123 smc -> clcsock -> sk -> sk_state_change (smc -> clcsock -> sk );
125124 }
126125 switch (smc -> sk .sk_state ) {
127126 case SMC_INIT :
127+ case SMC_ACTIVE :
128128 smc -> sk .sk_state = SMC_PEERABORTWAIT ;
129129 break ;
130130 case SMC_APPCLOSEWAIT1 :
@@ -161,10 +161,15 @@ void smc_close_active_abort(struct smc_sock *smc)
161161 }
162162
163163 sock_set_flag (& smc -> sk , SOCK_DEAD );
164- bh_unlock_sock (& smc -> sk );
165164 smc -> sk .sk_state_change (& smc -> sk );
166165}
167166
167+ static inline bool smc_close_sent_any_close (struct smc_connection * conn )
168+ {
169+ return conn -> local_tx_ctrl .conn_state_flags .peer_conn_abort ||
170+ conn -> local_tx_ctrl .conn_state_flags .peer_conn_closed ;
171+ }
172+
168173int smc_close_active (struct smc_sock * smc )
169174{
170175 struct smc_cdc_conn_state_flags * txflags =
@@ -185,8 +190,7 @@ int smc_close_active(struct smc_sock *smc)
185190 case SMC_INIT :
186191 sk -> sk_state = SMC_CLOSED ;
187192 if (smc -> smc_listen_work .func )
188- flush_work (& smc -> smc_listen_work );
189- sock_put (sk );
193+ cancel_work_sync (& smc -> smc_listen_work );
190194 break ;
191195 case SMC_LISTEN :
192196 sk -> sk_state = SMC_CLOSED ;
@@ -198,7 +202,7 @@ int smc_close_active(struct smc_sock *smc)
198202 }
199203 release_sock (sk );
200204 smc_close_cleanup_listen (sk );
201- flush_work (& smc -> tcp_listen_work );
205+ cancel_work_sync (& smc -> smc_listen_work );
202206 lock_sock (sk );
203207 break ;
204208 case SMC_ACTIVE :
@@ -218,7 +222,7 @@ int smc_close_active(struct smc_sock *smc)
218222 case SMC_APPFINCLOSEWAIT :
219223 /* socket already shutdown wr or both (active close) */
220224 if (txflags -> peer_done_writing &&
221- !txflags -> peer_conn_closed ) {
225+ !smc_close_sent_any_close ( conn ) ) {
222226 /* just shutdown wr done, send close request */
223227 rc = smc_close_final (conn );
224228 }
@@ -248,6 +252,13 @@ int smc_close_active(struct smc_sock *smc)
248252 break ;
249253 case SMC_PEERCLOSEWAIT1 :
250254 case SMC_PEERCLOSEWAIT2 :
255+ if (txflags -> peer_done_writing &&
256+ !smc_close_sent_any_close (conn )) {
257+ /* just shutdown wr done, send close request */
258+ rc = smc_close_final (conn );
259+ }
260+ /* peer sending PeerConnectionClosed will cause transition */
261+ break ;
251262 case SMC_PEERFINCLOSEWAIT :
252263 /* peer sending PeerConnectionClosed will cause transition */
253264 break ;
@@ -285,7 +296,7 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
285296 case SMC_PEERCLOSEWAIT1 :
286297 case SMC_PEERCLOSEWAIT2 :
287298 if (txflags -> peer_done_writing &&
288- !txflags -> peer_conn_closed ) {
299+ !smc_close_sent_any_close ( & smc -> conn ) ) {
289300 /* just shutdown, but not yet closed locally */
290301 smc_close_abort (& smc -> conn );
291302 sk -> sk_state = SMC_PROCESSABORT ;
@@ -306,22 +317,27 @@ static void smc_close_passive_abort_received(struct smc_sock *smc)
306317
307318/* Some kind of closing has been received: peer_conn_closed, peer_conn_abort,
308319 * or peer_done_writing.
309- * Called under tasklet context.
310320 */
311- void smc_close_passive_received (struct smc_sock * smc )
321+ static void smc_close_passive_work (struct work_struct * work )
312322{
313- struct smc_cdc_conn_state_flags * rxflags =
314- & smc -> conn .local_rx_ctrl .conn_state_flags ;
323+ struct smc_connection * conn = container_of (work ,
324+ struct smc_connection ,
325+ close_work );
326+ struct smc_sock * smc = container_of (conn , struct smc_sock , conn );
327+ struct smc_cdc_conn_state_flags * rxflags ;
315328 struct sock * sk = & smc -> sk ;
316329 int old_state ;
317330
318- sk -> sk_shutdown |= RCV_SHUTDOWN ;
319- if (smc -> clcsock && smc -> clcsock -> sk )
320- smc -> clcsock -> sk -> sk_shutdown |= RCV_SHUTDOWN ;
321- sock_set_flag (& smc -> sk , SOCK_DONE );
322-
331+ lock_sock (& smc -> sk );
323332 old_state = sk -> sk_state ;
324333
334+ if (!conn -> alert_token_local ) {
335+ /* abnormal termination */
336+ smc_close_active_abort (smc );
337+ goto wakeup ;
338+ }
339+
340+ rxflags = & smc -> conn .local_rx_ctrl .conn_state_flags ;
325341 if (rxflags -> peer_conn_abort ) {
326342 smc_close_passive_abort_received (smc );
327343 goto wakeup ;
@@ -331,7 +347,7 @@ void smc_close_passive_received(struct smc_sock *smc)
331347 case SMC_INIT :
332348 if (atomic_read (& smc -> conn .bytes_to_rcv ) ||
333349 (rxflags -> peer_done_writing &&
334- !rxflags -> peer_conn_closed ))
350+ !smc_cdc_rxed_any_close ( conn ) ))
335351 sk -> sk_state = SMC_APPCLOSEWAIT1 ;
336352 else
337353 sk -> sk_state = SMC_CLOSED ;
@@ -348,7 +364,7 @@ void smc_close_passive_received(struct smc_sock *smc)
348364 if (!smc_cdc_rxed_any_close (& smc -> conn ))
349365 break ;
350366 if (sock_flag (sk , SOCK_DEAD ) &&
351- ( sk -> sk_shutdown == SHUTDOWN_MASK )) {
367+ smc_close_sent_any_close ( conn )) {
352368 /* smc_release has already been called locally */
353369 sk -> sk_state = SMC_CLOSED ;
354370 } else {
@@ -367,17 +383,19 @@ void smc_close_passive_received(struct smc_sock *smc)
367383 }
368384
369385wakeup :
370- if (old_state != sk -> sk_state )
371- sk -> sk_state_change (sk );
372386 sk -> sk_data_ready (sk ); /* wakeup blocked rcvbuf consumers */
373387 sk -> sk_write_space (sk ); /* wakeup blocked sndbuf producers */
374388
375- if ((sk -> sk_state == SMC_CLOSED ) &&
376- (sock_flag (sk , SOCK_DEAD ) || (old_state == SMC_INIT ))) {
377- smc_conn_free (& smc -> conn );
378- schedule_delayed_work (& smc -> sock_put_work ,
379- SMC_CLOSE_SOCK_PUT_DELAY );
389+ if (old_state != sk -> sk_state ) {
390+ sk -> sk_state_change (sk );
391+ if ((sk -> sk_state == SMC_CLOSED ) &&
392+ (sock_flag (sk , SOCK_DEAD ) || !sk -> sk_socket )) {
393+ smc_conn_free (& smc -> conn );
394+ schedule_delayed_work (& smc -> sock_put_work ,
395+ SMC_CLOSE_SOCK_PUT_DELAY );
396+ }
380397 }
398+ release_sock (& smc -> sk );
381399}
382400
383401void smc_close_sock_put_work (struct work_struct * work )
@@ -442,3 +460,9 @@ int smc_close_shutdown_write(struct smc_sock *smc)
442460 sk -> sk_state_change (& smc -> sk );
443461 return rc ;
444462}
463+
464+ /* Initialize close properties on connection establishment. */
465+ void smc_close_init (struct smc_sock * smc )
466+ {
467+ INIT_WORK (& smc -> conn .close_work , smc_close_passive_work );
468+ }
0 commit comments