4242#include "smc_rx.h"
4343#include "smc_close.h"
4444
45- static DEFINE_MUTEX (smc_create_lgr_pending ); /* serialize link group
46- * creation
45+ static DEFINE_MUTEX (smc_server_lgr_pending ); /* serialize link group
46+ * creation on server
47+ */
48+ static DEFINE_MUTEX (smc_client_lgr_pending ); /* serialize link group
49+ * creation on client
4750 */
4851
4952static void smc_tcp_listen_work (struct work_struct * );
@@ -145,32 +148,33 @@ static int smc_release(struct socket *sock)
145148 rc = smc_close_active (smc );
146149 sock_set_flag (sk , SOCK_DEAD );
147150 sk -> sk_shutdown |= SHUTDOWN_MASK ;
148- }
149-
150- sk -> sk_prot -> unhash (sk );
151-
152- if (smc -> clcsock ) {
153- if (smc -> use_fallback && sk -> sk_state == SMC_LISTEN ) {
151+ } else {
152+ if (sk -> sk_state != SMC_LISTEN && sk -> sk_state != SMC_INIT )
153+ sock_put (sk ); /* passive closing */
154+ if (sk -> sk_state == SMC_LISTEN ) {
154155 /* wake up clcsock accept */
155156 rc = kernel_sock_shutdown (smc -> clcsock , SHUT_RDWR );
156157 }
157- mutex_lock (& smc -> clcsock_release_lock );
158- sock_release (smc -> clcsock );
159- smc -> clcsock = NULL ;
160- mutex_unlock (& smc -> clcsock_release_lock );
161- }
162- if (smc -> use_fallback ) {
163- if (sk -> sk_state != SMC_LISTEN && sk -> sk_state != SMC_INIT )
164- sock_put (sk ); /* passive closing */
165158 sk -> sk_state = SMC_CLOSED ;
166159 sk -> sk_state_change (sk );
167160 }
168161
162+ sk -> sk_prot -> unhash (sk );
163+
164+ if (sk -> sk_state == SMC_CLOSED ) {
165+ if (smc -> clcsock ) {
166+ mutex_lock (& smc -> clcsock_release_lock );
167+ sock_release (smc -> clcsock );
168+ smc -> clcsock = NULL ;
169+ mutex_unlock (& smc -> clcsock_release_lock );
170+ }
171+ if (!smc -> use_fallback )
172+ smc_conn_free (& smc -> conn );
173+ }
174+
169175 /* detach socket */
170176 sock_orphan (sk );
171177 sock -> sk = NULL ;
172- if (!smc -> use_fallback && sk -> sk_state == SMC_CLOSED )
173- smc_conn_free (& smc -> conn );
174178 release_sock (sk );
175179
176180 sock_put (sk ); /* final sock_put */
@@ -476,7 +480,12 @@ static int smc_connect_abort(struct smc_sock *smc, int reason_code,
476480{
477481 if (local_contact == SMC_FIRST_CONTACT )
478482 smc_lgr_forget (smc -> conn .lgr );
479- mutex_unlock (& smc_create_lgr_pending );
483+ if (smc -> conn .lgr -> is_smcd )
484+ /* there is only one lgr role for SMC-D; use server lock */
485+ mutex_unlock (& smc_server_lgr_pending );
486+ else
487+ mutex_unlock (& smc_client_lgr_pending );
488+
480489 smc_conn_free (& smc -> conn );
481490 return reason_code ;
482491}
@@ -561,7 +570,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
561570 struct smc_link * link ;
562571 int reason_code = 0 ;
563572
564- mutex_lock (& smc_create_lgr_pending );
573+ mutex_lock (& smc_client_lgr_pending );
565574 local_contact = smc_conn_create (smc , false, aclc -> hdr .flag , ibdev ,
566575 ibport , ntoh24 (aclc -> qpn ), & aclc -> lcl ,
567576 NULL , 0 );
@@ -572,7 +581,8 @@ static int smc_connect_rdma(struct smc_sock *smc,
572581 reason_code = SMC_CLC_DECL_SYNCERR ; /* synchr. error */
573582 else
574583 reason_code = SMC_CLC_DECL_INTERR ; /* other error */
575- return smc_connect_abort (smc , reason_code , 0 );
584+ mutex_unlock (& smc_client_lgr_pending );
585+ return reason_code ;
576586 }
577587 link = & smc -> conn .lgr -> lnk [SMC_SINGLE_LINK ];
578588
@@ -616,7 +626,7 @@ static int smc_connect_rdma(struct smc_sock *smc,
616626 return smc_connect_abort (smc , reason_code ,
617627 local_contact );
618628 }
619- mutex_unlock (& smc_create_lgr_pending );
629+ mutex_unlock (& smc_client_lgr_pending );
620630
621631 smc_copy_sock_settings_to_clc (smc );
622632 if (smc -> sk .sk_state == SMC_INIT )
@@ -633,11 +643,14 @@ static int smc_connect_ism(struct smc_sock *smc,
633643 int local_contact = SMC_FIRST_CONTACT ;
634644 int rc = 0 ;
635645
636- mutex_lock (& smc_create_lgr_pending );
646+ /* there is only one lgr role for SMC-D; use server lock */
647+ mutex_lock (& smc_server_lgr_pending );
637648 local_contact = smc_conn_create (smc , true, aclc -> hdr .flag , NULL , 0 , 0 ,
638649 NULL , ismdev , aclc -> gid );
639- if (local_contact < 0 )
640- return smc_connect_abort (smc , SMC_CLC_DECL_MEM , 0 );
650+ if (local_contact < 0 ) {
651+ mutex_unlock (& smc_server_lgr_pending );
652+ return SMC_CLC_DECL_MEM ;
653+ }
641654
642655 /* Create send and receive buffers */
643656 if (smc_buf_create (smc , true))
@@ -651,7 +664,7 @@ static int smc_connect_ism(struct smc_sock *smc,
651664 rc = smc_clc_send_confirm (smc );
652665 if (rc )
653666 return smc_connect_abort (smc , rc , local_contact );
654- mutex_unlock (& smc_create_lgr_pending );
667+ mutex_unlock (& smc_server_lgr_pending );
655668
656669 smc_copy_sock_settings_to_clc (smc );
657670 if (smc -> sk .sk_state == SMC_INIT )
@@ -1250,7 +1263,7 @@ static void smc_listen_work(struct work_struct *work)
12501263 return ;
12511264 }
12521265
1253- mutex_lock (& smc_create_lgr_pending );
1266+ mutex_lock (& smc_server_lgr_pending );
12541267 smc_close_init (new_smc );
12551268 smc_rx_init (new_smc );
12561269 smc_tx_init (new_smc );
@@ -1272,7 +1285,7 @@ static void smc_listen_work(struct work_struct *work)
12721285 & local_contact ) ||
12731286 smc_listen_rdma_reg (new_smc , local_contact ))) {
12741287 /* SMC not supported, decline */
1275- mutex_unlock (& smc_create_lgr_pending );
1288+ mutex_unlock (& smc_server_lgr_pending );
12761289 smc_listen_decline (new_smc , SMC_CLC_DECL_MODEUNSUPP ,
12771290 local_contact );
12781291 return ;
@@ -1281,29 +1294,33 @@ static void smc_listen_work(struct work_struct *work)
12811294 /* send SMC Accept CLC message */
12821295 rc = smc_clc_send_accept (new_smc , local_contact );
12831296 if (rc ) {
1284- mutex_unlock (& smc_create_lgr_pending );
1297+ mutex_unlock (& smc_server_lgr_pending );
12851298 smc_listen_decline (new_smc , rc , local_contact );
12861299 return ;
12871300 }
12881301
1302+ /* SMC-D does not need this lock any more */
1303+ if (ism_supported )
1304+ mutex_unlock (& smc_server_lgr_pending );
1305+
12891306 /* receive SMC Confirm CLC message */
12901307 reason_code = smc_clc_wait_msg (new_smc , & cclc , sizeof (cclc ),
12911308 SMC_CLC_CONFIRM , CLC_WAIT_TIME );
12921309 if (reason_code ) {
1293- mutex_unlock (& smc_create_lgr_pending );
1310+ if (!ism_supported )
1311+ mutex_unlock (& smc_server_lgr_pending );
12941312 smc_listen_decline (new_smc , reason_code , local_contact );
12951313 return ;
12961314 }
12971315
12981316 /* finish worker */
12991317 if (!ism_supported ) {
1300- if (smc_listen_rdma_finish (new_smc , & cclc , local_contact )) {
1301- mutex_unlock (& smc_create_lgr_pending );
1318+ rc = smc_listen_rdma_finish (new_smc , & cclc , local_contact );
1319+ mutex_unlock (& smc_server_lgr_pending );
1320+ if (rc )
13021321 return ;
1303- }
13041322 }
13051323 smc_conn_save_peer_info (new_smc , & cclc );
1306- mutex_unlock (& smc_create_lgr_pending );
13071324 smc_listen_out_connected (new_smc );
13081325}
13091326
0 commit comments